728x90
Terrain.cpp, h
더보기
#include "Framework.h" #include "Terrain.h" Terrain::Terrain(Shader * shader, wstring heightFile) :shader(shader) { hightMap = new Texture(heightFile); CreateVertexData(); CreateIndexData(); CreateBuffer(); D3DXMatrixIdentity(&world); } Terrain::~Terrain() { SafeDeleteArray(vertices); SafeRelease(vertexBuffer); SafeDeleteArray(indices); SafeRelease(indexBuffer); SafeDelete(hightMap); } void Terrain::Update() { shader->AsMatrix("World")->SetMatrix(world); shader->AsMatrix("View")->SetMatrix(Context::Get()->View()); shader->AsMatrix("Projection")->SetMatrix(Context::Get()->Projection()); } void Terrain::Render() { UINT stride = sizeof(VertexTerrain); UINT offset = 0; D3D::GetDC()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); D3D::GetDC()->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset); D3D::GetDC()->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R32_UINT, 0); shader->DrawIndexed(0, pass, indexCount); } void Terrain::CreateVertexData() { //hightMap의 가로 세로 크기 width = hightMap->GetWidth(); height = hightMap->GetHeight(); //픽셀 정보 가져오기 vector<Color> pixels; hightMap->ReadPixel(&pixels); //생성 vertexCount = width * height; vertices = new VertexTerrain[vertexCount]; for (UINT z = 0; z < height; z++) { for (UINT x = 0; x < width; x++) { UINT index = width * z + x; //World 좌표계랑 UV 좌표계는 다르기 떄문에 반전 시켜야함 UINT pixel = width * (height - z - 1 ) + x; vertices[index].Position.x = (float)x; vertices[index].Position.y = pixels[pixel].r * (255.0f / 10); vertices[index].Position.z = (float)z; } } } void Terrain::CreateIndexData() { //Set Index Subresource indexCount = (width - 1) * (height - 1) * 6; indices = new UINT[indexCount]; UINT index = 0; for (UINT y = 0; y < height - 1 ; y++) { for (UINT x = 0; x < width - 1; x++) { indices[index + 0] = (width) * y + x; indices[index + 1] = (width) * (y + 1) + x; indices[index + 2] = (width) * y + x + 1; indices[index + 3] = (width) * y + x + 1; indices[index + 4] = (width) * (y + 1) + x; indices[index + 5] = (width) * (y + 1) + x + 1; index += 6; } } } void Terrain::CreateBuffer() { //Create VertexBuffer { D3D11_BUFFER_DESC desc; ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC)); desc.ByteWidth = sizeof(VertexTerrain) * vertexCount; desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; D3D11_SUBRESOURCE_DATA data = { 0 }; data.pSysMem = vertices; Check(D3D::GetDevice()->CreateBuffer(&desc, &data, &vertexBuffer)); } //Create IndexBuffer { D3D11_BUFFER_DESC desc; ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC)); desc.ByteWidth = sizeof(UINT) * indexCount; desc.BindFlags = D3D11_BIND_INDEX_BUFFER; D3D11_SUBRESOURCE_DATA data = { 0 }; data.pSysMem = indices; Check(D3D::GetDevice()->CreateBuffer(&desc, &data, &indexBuffer)); } }
#pragma once class Terrain { public: Terrain(Shader* shader, wstring heightFile); ~Terrain(); void Update(); void Render(); UINT& Pass() { return pass; } private: void CreateVertexData(); void CreateIndexData(); void CreateBuffer(); private: struct VertexTerrain { Vector3 Position; }; private: Shader* shader; UINT pass = 0; UINT width, height; UINT vertexCount; VertexTerrain* vertices; ID3D11Buffer* vertexBuffer; UINT indexCount; UINT* indices; ID3D11Buffer* indexBuffer; Matrix world; //높이맵 Texture* hightMap; };
TerrainDemo.cpp, h
더보기
#include "stdafx.h" #include "TerrainDemo.h" void TerrainDemo::Initialize() { Context::Get()->GetCamera()->RotationDegree(6, 0, 0); Context::Get()->GetCamera()->Position(110, 50, 0); ((Freedom*)Context::Get()->GetCamera())->Speed(50); shader = new Shader(L"11_Terrain.fxo"); terrain = new Terrain(shader, L"HightMap256.png"); } void TerrainDemo::Destroy() { SafeDelete(shader); SafeDelete(terrain); } void TerrainDemo::Update() { //쉐이더에 등록한 Pass 갯수 반환 static UINT Pass = shader->PassCount() - 1; ImGui::InputInt("Pass", (int*)&Pass); Pass %= 2; terrain->Pass() = Pass; terrain->Update(); } void TerrainDemo::Render() { terrain->Render(); }
#pragma once #include "Systems/IExecute.h" class TerrainDemo : public IExecute { public: virtual void Initialize() override; virtual void Destroy() override; virtual void Update() override; virtual void PreRender() override {}; virtual void Render() override; virtual void PostRender() override {}; virtual void ResizeScreen() override {}; private: struct Vertex { Vector3 Position; Vector2 Uv; }; private: Shader* shader; Terrain* terrain; };
11_Terrain.fx
더보기
matrix World, View, Projection; struct VertexInput { float4 Position : Position; }; struct VertexOutput { float4 Position : SV_Position; }; RasterizerState RS { FillMode = WireFrame; }; VertexOutput VS(VertexInput input) { VertexOutput output; output.Position = mul(input.Position, World); output.Position = mul(output.Position, View); output.Position = mul(output.Position, Projection); return output; } float4 PS(VertexOutput input) : SV_Target { return float4(1, 1, 0, 1); } technique11 T0 { pass P0 { SetVertexShader(CompileShader(vs_5_0, VS())); SetPixelShader(CompileShader(ps_5_0, PS())); } pass P1 { SetRasterizerState(RS); SetVertexShader(CompileShader(vs_5_0, VS())); SetPixelShader(CompileShader(ps_5_0, PS())); } }
실행
지금부터 진짜로 3D 내용의 시작이라고 볼 수 있음
Diffusemap은 기본 색상 이라서 높이 관련은 따로 Hightmap을 사용을 해서 지형을 만듬
지형의 크기는 Hightmap정보를 받아서 사용하기 때문에 Index 에서 가로 세로 -1 해줘야함

Environment안에 이제부터 지형, 날씨, 구름...등을 작성을 하면 UnitTest에서 사용하기 때문에
즉 한번 선언하면 왠만하면 수정을 안하기 때문에 Framework에다 만들어서 사용
'DirectX > DirectX 3D_(구)' 카테고리의 다른 글
13_BaseMap (0) | 2021.07.04 |
---|---|
12_Normal [1/2] (0) | 2021.07.03 |
10_Sampler (0) | 2021.07.02 |
09_Texture (0) | 2021.06.30 |
08_Cube (0) | 2021.06.30 |