void Mesh::Finalize () { if (DBGERROR (finalized)) { return; } calculatedTriangleNormals.clear (); calculatedVertexNormals.clear (); bool needVertexNormals = false; for (UIndex i = 0; i < triangles.size (); i++) { Triangle& triangle = triangles[i]; if (triangle.curveGroup != Mesh::NonCurved) { needVertexNormals = true; } if (triangle.texCoord0 == InvalidIndex) { texCoords.push_back (Vec2 (0.0, 0.0)); triangle.texCoord0 = texCoords.size () - 1; } if (triangle.texCoord1 == InvalidIndex) { texCoords.push_back (Vec2 (0.0, 0.0)); triangle.texCoord1 = texCoords.size () - 1; } if (triangle.texCoord2 == InvalidIndex) { texCoords.push_back (Vec2 (0.0, 0.0)); triangle.texCoord2 = texCoords.size () - 1; } calculatedTriangleNormals.push_back (CalculateTriangleNormal (i)); } if (needVertexNormals) { CalculateVertexNormals (); } CalculateBoundingShapes (); CalculateOctree (); finalized = true; }
//-------------------------------------------------------------------------------------- // FillGrid_WithNormals_Indexed // Creates a regular grid of indexed triangles, including normals. // // Parameters: // // IN // pd3dDevice: The D3D device // dwWidth, dwLength: Number of grid vertices in X and Z direction // fGridSizeX, fGridSizeZ: Grid extents in local space units // // OUT // lplpVB: A pointer to the vertex buffer containing grid vertices // lplpIB: A pointer to the index buffer containing grid indices //-------------------------------------------------------------------------------------- void FillGrid_WithNormals_Indexed( ID3D11Device* pd3dDevice, DWORD dwWidth, DWORD dwLength, float fGridSizeX, float fGridSizeZ, ID3D11Buffer** lplpVB, ID3D11Buffer** lplpIB ) { HRESULT hr; DWORD nNumVertex = ( dwWidth + 1 ) * ( dwLength + 1 ); DWORD nNumIndex = 3 * 2 * dwWidth * dwLength; float fStepX = fGridSizeX / dwWidth; float fStepZ = fGridSizeZ / dwLength; // Allocate memory for buffer of vertices in system memory EXTENDEDVERTEX* pVertexBuffer = new EXTENDEDVERTEX[nNumVertex]; EXTENDEDVERTEX* pVertex = &pVertexBuffer[0]; // Fill vertex buffer for ( DWORD i=0; i<=dwLength; ++i ) { for ( DWORD j=0; j<=dwWidth; ++j ) { pVertex->x = -fGridSizeX/2.0f + j*fStepX; pVertex->y = 0.0f; pVertex->z = fGridSizeZ/2.0f - i*fStepZ; pVertex->nx = 0.0f; pVertex->ny = 0.0f; pVertex->nz = 0.0f; pVertex->u = 0.0f + ( (float)j / dwWidth ); pVertex->v = 0.0f + ( (float)i / dwLength ); pVertex++; } } // Allocate memory for buffer of indices in system memory WORD* pIndexBuffer = new WORD [nNumIndex]; WORD* pIndex = &pIndexBuffer[0]; // Fill index buffer for ( DWORD i=0; i<dwLength; ++i ) { for ( DWORD j=0; j<dwWidth; ++j ) { *pIndex++ = (WORD)( i * ( dwWidth+1 ) + j ); *pIndex++ = (WORD)( i * ( dwWidth+1 ) + j + 1 ); *pIndex++ = (WORD)( ( i+1 ) * ( dwWidth+1 ) + j ); *pIndex++ = (WORD)( ( i+1 ) * (dwWidth+1) + j ); *pIndex++ = (WORD)( i * (dwWidth+1) + j + 1 ); *pIndex++ = (WORD)( ( i+1 ) * (dwWidth+1) + j + 1 ); } } // Set initial data info D3D11_SUBRESOURCE_DATA InitData; InitData.pSysMem = pIndexBuffer; // Fill DX11 index buffer description D3D11_BUFFER_DESC bd; bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof( WORD ) * nNumIndex; bd.BindFlags = D3D11_BIND_INDEX_BUFFER; bd.CPUAccessFlags = 0; bd.MiscFlags = 0; // Create DX11 index buffer specifying initial data hr = pd3dDevice->CreateBuffer( &bd, &InitData, lplpIB ); if( FAILED( hr ) ) { OutputDebugString( L"FillGrid_WithNormals_Indexed: Failed to create index buffer.\n" ); return; } DXUT_SetDebugName( *lplpIB, "FillGrid IB Nrmls" ); // Write normals into vertex buffer pVertex = &pVertexBuffer[0]; // Loop through all indices for ( DWORD i=0; i<nNumIndex/3; ++i ) { WORD i1 = pIndexBuffer[3*i + 0]; WORD i2 = pIndexBuffer[3*i + 1]; WORD i3 = pIndexBuffer[3*i + 2]; D3DXVECTOR3 Normal = CalculateTriangleNormal( (D3DXVECTOR3 *)&pVertexBuffer[i1].x, (D3DXVECTOR3 *)&pVertexBuffer[i2].x, (D3DXVECTOR3 *)&pVertexBuffer[i3].x ); // Add normal to each vertex for this triangle *( (D3DXVECTOR3 *)&pVertexBuffer[i1].nx ) += Normal; *( (D3DXVECTOR3 *)&pVertexBuffer[i2].nx ) += Normal; *( (D3DXVECTOR3 *)&pVertexBuffer[i3].nx ) += Normal; } // Final normalization pass for ( DWORD i=0; i<nNumVertex; ++i ) { D3DXVec3Normalize( (D3DXVECTOR3 *)&pVertexBuffer[i].nx, (D3DXVECTOR3 *)&pVertexBuffer[i].nx ); } // Set initial data info InitData.pSysMem = pVertexBuffer; // Fill DX11 vertex buffer description bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof( EXTENDEDVERTEX ) * nNumVertex; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; bd.CPUAccessFlags = 0; bd.MiscFlags = 0; // Create DX11 vertex buffer specifying initial data hr = pd3dDevice->CreateBuffer( &bd, &InitData, lplpVB ); if( FAILED( hr ) ) { OutputDebugString( L"FillGrid_WithNormals_Indexed: Failed to create vertex buffer.\n" ); return; } DXUT_SetDebugName( *lplpVB, "FillGrid VB Nrmls Idx" ); // Release host memory index buffer delete [] pIndexBuffer; // Release host memory vertex buffer delete [] pVertexBuffer; }