void Terrain::Init(ID3D11Device* device, ID3D11DeviceContext* dc, const InitInfo& initInfo) { mInfo = initInfo; // Divide heightmap into patches such that each patch has CellsPerPatch. mNumPatchVertRows = ((mInfo.HeightmapHeight-1) / CellsPerPatch) + 1; mNumPatchVertCols = ((mInfo.HeightmapWidth-1) / CellsPerPatch) + 1; mNumPatchVertices = mNumPatchVertRows*mNumPatchVertCols; mNumPatchQuadFaces = (mNumPatchVertRows-1)*(mNumPatchVertCols-1); LoadHeightmap(); Smooth(); CalcAllPatchBoundsY(); BuildQuadPatchVB(device); BuildQuadPatchIB(device); BuildHeightmapSRV(device); std::vector<std::wstring> layerFilenames; layerFilenames.push_back(mInfo.LayerMapFilename0); layerFilenames.push_back(mInfo.LayerMapFilename1); layerFilenames.push_back(mInfo.LayerMapFilename2); layerFilenames.push_back(mInfo.LayerMapFilename3); layerFilenames.push_back(mInfo.LayerMapFilename4); mLayerMapArraySRV = d3dHelper::CreateTexture2DArraySRV(device, dc, layerFilenames); HR(D3DX11CreateShaderResourceViewFromFileW(device, mInfo.BlendMapFilename.c_str(), 0, 0, &mBlendMapSRV, 0)); }
GameObject* Terrain::CreateGameObject(const char* diffuseTxt_filename, const char* normalTxt_filename, const char* heightTxt_filemane) { std::vector<float2> texture_coordinate = calculateTextureCoordiate(); std::vector<float2> boundsY = CalcAllPatchBoundsY(); const int iNumVertices = m_initInfo.HeightmapWidth / 8 * (m_initInfo.HeightmapHeight) / 8 * 4; const int iNumIndices = iNumVertices; VertexTerrain* vertices = new VertexTerrain[iNumVertices]; unsigned int* indices = new unsigned int[iNumIndices]; // Translate the terrain, so that the mid-point of terrain is at (0, 0, 0) Matrix4 translate; translate.CreateTranslation(Vector3(-GetWidth() / 2.0f, 0.0f, -GetDepth() / 2.0f)); // Initialize the index to the vertex buffer. int indexCounter = 0; // Load the vertex and index array with the terrain data. for (int j = 0; j < m_initInfo.HeightmapHeight - 8; j += 8) { for (int i = 0; i < m_initInfo.HeightmapWidth - 8; i += 8) { const int index_bl = m_initInfo.HeightmapWidth * j + i; const int index_br = m_initInfo.HeightmapWidth * j + (i + 8); const int index_ul = m_initInfo.HeightmapWidth * (j + 8) + i; const int index_ur = m_initInfo.HeightmapWidth * (j + 8) + (i + 8); const float2 bl_uv( texture_coordinate[index_bl].x, texture_coordinate[index_bl].y ); const float2 br_uv( (texture_coordinate[index_br].x == 0.0f ? 1.0f : texture_coordinate[index_br].x), texture_coordinate[index_br].y ); const float2 ul_uv( texture_coordinate[index_ul].x, (texture_coordinate[index_ul].y == 1.0f ? 0.0f : texture_coordinate[index_ul].y) ); const float2 ur_uv( (texture_coordinate[index_ur].x == 0.0f ? 1.0f : texture_coordinate[index_ur].x), (texture_coordinate[index_ur].y == 1.0f ? 0.0f : texture_coordinate[index_ur].y) ); Vector3 bl(i * m_initInfo.CellSpacing, m_HeightMap[index_bl] * m_initInfo.CellSpacing, j* m_initInfo.CellSpacing); Vector3 br((i + 8)* m_initInfo.CellSpacing, m_HeightMap[index_br] * m_initInfo.CellSpacing, j* m_initInfo.CellSpacing); Vector3 ul(i* m_initInfo.CellSpacing, m_HeightMap[index_ul] * m_initInfo.CellSpacing, (j + 8)* m_initInfo.CellSpacing); Vector3 ur((i + 8)* m_initInfo.CellSpacing, m_HeightMap[index_ur] * m_initInfo.CellSpacing, (j + 8)* m_initInfo.CellSpacing); const int patch_id = j + (i / m_initInfo.CellsPerPatch); // bottom left { vertices[indexCounter].m_pos = bl; vertices[indexCounter].m_UV[0] = bl_uv.x; vertices[indexCounter].m_UV[1] = bl_uv.y; vertices[indexCounter].m_boundsY[0] = boundsY[patch_id].x; vertices[indexCounter].m_boundsY[1] = boundsY[patch_id].y; indices[indexCounter] = indexCounter; indexCounter++; } // bottom right { vertices[indexCounter].m_pos = br; vertices[indexCounter].m_UV[0] = br_uv.x; vertices[indexCounter].m_UV[1] = br_uv.y; vertices[indexCounter].m_boundsY[0] = boundsY[patch_id].x; vertices[indexCounter].m_boundsY[1] = boundsY[patch_id].y; indices[indexCounter] = indexCounter; indexCounter++; } // upper left { vertices[indexCounter].m_pos = ul; vertices[indexCounter].m_UV[0] = ul_uv.x; vertices[indexCounter].m_UV[1] = ul_uv.y; vertices[indexCounter].m_boundsY[0] = boundsY[patch_id].x; vertices[indexCounter].m_boundsY[1] = boundsY[patch_id].y; indices[indexCounter] = indexCounter; indexCounter++; } // upper right { vertices[indexCounter].m_pos = ur; vertices[indexCounter].m_UV[0] = ur_uv.x; vertices[indexCounter].m_UV[1] = ur_uv.y; vertices[indexCounter].m_boundsY[0] = boundsY[patch_id].x; vertices[indexCounter].m_boundsY[1] = boundsY[patch_id].y; indices[indexCounter] = indexCounter; indexCounter++; } } } std::string diffuseTxt_filepath = std::string("../Assets/") + diffuseTxt_filename; std::string normalTxt_filepath = std::string("../Assets/") + normalTxt_filename; std::string heightTxt_filepath = std::string("../Assets/") + heightTxt_filemane; MeshData* meshData = new MeshData(vertices, iNumVertices, indices, iNumIndices, sizeof(VertexTerrain)); meshData->SetBoundingBox(AABB(Vector3(0, 0, 0), Vector3(m_initInfo.HeightmapHeight, 0, m_initInfo.HeightmapWidth))); Handle hMeshComp(sizeof(MeshComponent)); new (hMeshComp) MeshComponent(meshData); SceneGraph::GetInstance()->AddComponent((MeshComponent*) hMeshComp.Raw()); RenderPass* renderPass = new RenderPass; renderPass->SetVertexShader("../DEngine/Shaders/VS_terrain.hlsl"); renderPass->SetHullShader("../DEngine/Shaders/HS_terrain.hlsl"); renderPass->SetDomainShader("../DEngine/Shaders/DS_terrain.hlsl"); renderPass->SetPixelShader("../DEngine/Shaders/PS_terrain.hlsl"); Handle hTexture1(sizeof(Texture)); new (hTexture1) Texture(Texture::SHADER_RESOURCES, 1, diffuseTxt_filepath.c_str()); Handle hTexture2(sizeof(Texture)); new (hTexture2) Texture(Texture::SHADER_RESOURCES, 1, normalTxt_filepath.c_str()); Handle hTexture3(sizeof(Texture)); new (hTexture3) Texture(Texture::SHADER_RESOURCES, 1, heightTxt_filepath.c_str()); renderPass->AddTexture(hTexture1); renderPass->AddTexture(hTexture2); renderPass->AddTexture(hTexture3); renderPass->SetTopology(D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST); renderPass->SetBlendState(State::NULL_STATE); renderPass->SetRenderTargets(D3D11Renderer::GetInstance()->m_pRTVArray, 2); renderPass->SetDepthStencilView(D3D11Renderer::GetInstance()->m_depth->GetDSV()); renderPass->SetDepthStencilState(State::DEFAULT_DEPTH_STENCIL_DSS); renderPass->SetRasterizerState(State::CULL_BACK_RS); ((MeshComponent*) hMeshComp.Raw())->m_pMeshData->m_Material.AddPassToTechnique(renderPass); GameObject* terrain = new GameObject; terrain->AddComponent((Component*) hMeshComp.Raw()); delete[] vertices; delete[] indices; return terrain; }