void Heightmap::CalculateNormals(Vertex *vertexArray) { // Estimate normals for interior nodes using central difference. float invTwoDX = 1.0f / (2.0f*mCellSpacing); float invTwoDZ = 1.0f / (2.0f*mCellSpacing); for(UINT i = 2; i < mNumRows-1; ++i) { for(UINT j = 2; j < mNumCols-1; ++j) { float t = mHeightmap[(i-1)*mNumCols + j]; float b = mHeightmap[(i+1)*mNumCols + j]; float l = mHeightmap[i*mNumCols + j - 1]; float r = mHeightmap[i*mNumCols + j + 1]; D3DXVECTOR3 tanZ(0.0f, (t-b)*invTwoDZ, 1.0f); D3DXVECTOR3 tanX(1.0f, (r-l)*invTwoDX, 0.0f); D3DXVECTOR3 N; D3DXVec3Cross(&N, &tanZ, &tanX); D3DXVec3Normalize(&N, &N); vertexArray[i*mNumCols+j].normal = N; } } }
void Terrain::buildVB() { std::vector<TerrainVertex> vertices(mNumVertices); float halfWidth = (mInfo.NumCols-1)*mInfo.CellSpacing*0.5f; float halfDepth = (mInfo.NumRows-1)*mInfo.CellSpacing*0.5f; float du = 1.0f / (mInfo.NumCols-1); float dv = 1.0f / (mInfo.NumRows-1); for(UINT i = 0; i < mInfo.NumRows; ++i) { float z = halfDepth - i*mInfo.CellSpacing; for(UINT j = 0; j < mInfo.NumCols; ++j) { float x = -halfWidth + j*mInfo.CellSpacing; float y = mHeightmap[i*mInfo.NumCols+j]; vertices[i*mInfo.NumCols+j].pos = D3DXVECTOR3(x, y, z); vertices[i*mInfo.NumCols+j].normal = D3DXVECTOR3(0.0f, 1.0f, 0.0f); // Stretch texture over grid. vertices[i*mInfo.NumCols+j].texC.x = j*du; vertices[i*mInfo.NumCols+j].texC.y = i*dv; } } // Estimate normals for interior nodes using central difference. float invTwoDX = 1.0f / (2.0f*mInfo.CellSpacing); float invTwoDZ = 1.0f / (2.0f*mInfo.CellSpacing); for(UINT i = 2; i < mInfo.NumRows-1; ++i) { for(UINT j = 2; j < mInfo.NumCols-1; ++j) { float t = mHeightmap[(i-1)*mInfo.NumCols + j]; float b = mHeightmap[(i+1)*mInfo.NumCols + j]; float l = mHeightmap[i*mInfo.NumCols + j - 1]; float r = mHeightmap[i*mInfo.NumCols + j + 1]; D3DXVECTOR3 tanZ(0.0f, (t-b)*invTwoDZ, 1.0f); D3DXVECTOR3 tanX(1.0f, (r-l)*invTwoDX, 0.0f); D3DXVECTOR3 N; D3DXVec3Cross(&N, &tanZ, &tanX); D3DXVec3Normalize(&N, &N); vertices[i*mInfo.NumCols+j].normal = N; } } D3D10_BUFFER_DESC vbd; vbd.Usage = D3D10_USAGE_IMMUTABLE; vbd.ByteWidth = sizeof(TerrainVertex) * mNumVertices; vbd.BindFlags = D3D10_BIND_VERTEX_BUFFER; vbd.CPUAccessFlags = 0; vbd.MiscFlags = 0; D3D10_SUBRESOURCE_DATA vinitData; vinitData.pSysMem = &vertices[0]; HR(md3dDevice->CreateBuffer(&vbd, &vinitData, &mVB)); }