?? shadowvolume.cpp
字號(hào):
return E_OUTOFMEMORY;
}
hr = pInputMesh->GenerateAdjacency( ADJACENCY_EPSILON, pdwAdj );
if( FAILED( hr ) )
{
delete[] pdwAdj; delete[] pdwPtRep;
pInputMesh->Release();
return hr;
}
pInputMesh->ConvertAdjacencyToPointReps( pdwAdj, pdwPtRep );
delete[] pdwAdj;
SHADOWVERT *pVBData = NULL;
DWORD *pdwIBData = NULL;
pInputMesh->LockVertexBuffer( 0, (LPVOID*)&pVBData );
pInputMesh->LockIndexBuffer( 0, (LPVOID*)&pdwIBData );
if( pVBData && pdwIBData )
{
// Maximum number of unique edges = Number of faces * 3
DWORD dwNumEdges = pInputMesh->GetNumFaces() * 3;
CEdgeMapping *pMapping = new CEdgeMapping[dwNumEdges];
if( pMapping )
{
int nNumMaps = 0; // Number of entries that exist in pMapping
// Create a new mesh
ID3DXMesh *pNewMesh;
hr = D3DXCreateMesh( pInputMesh->GetNumFaces() + dwNumEdges * 2,
pInputMesh->GetNumFaces() * 3,
D3DXMESH_32BIT,
SHADOWVERT::Decl,
pd3dDevice,
&pNewMesh );
if( SUCCEEDED( hr ) )
{
SHADOWVERT *pNewVBData = NULL;
DWORD *pdwNewIBData = NULL;
pNewMesh->LockVertexBuffer( 0, (LPVOID*)&pNewVBData );
pNewMesh->LockIndexBuffer( 0, (LPVOID*)&pdwNewIBData );
// nNextIndex is the array index in IB that the next vertex index value
// will be store at.
int nNextIndex = 0;
if( pNewVBData && pdwNewIBData )
{
ZeroMemory( pNewVBData, pNewMesh->GetNumVertices() * pNewMesh->GetNumBytesPerVertex() );
ZeroMemory( pdwNewIBData, sizeof(DWORD) * pNewMesh->GetNumFaces() * 3 );
// pNextOutVertex is the location to write the next
// vertex to.
SHADOWVERT *pNextOutVertex = pNewVBData;
// Iterate through the faces. For each face, output new
// vertices and face in the new mesh, and write its edges
// to the mapping table.
for( UINT f = 0; f < pInputMesh->GetNumFaces(); ++f )
{
// Copy the vertex data for all 3 vertices
CopyMemory( pNextOutVertex, pVBData + pdwIBData[f * 3], sizeof(SHADOWVERT) );
CopyMemory( pNextOutVertex + 1, pVBData + pdwIBData[f * 3 + 1], sizeof(SHADOWVERT) );
CopyMemory( pNextOutVertex + 2, pVBData + pdwIBData[f * 3 + 2], sizeof(SHADOWVERT) );
// Write out the face
pdwNewIBData[nNextIndex++] = f * 3;
pdwNewIBData[nNextIndex++] = f * 3 + 1;
pdwNewIBData[nNextIndex++] = f * 3 + 2;
// Compute the face normal and assign it to
// the normals of the vertices.
D3DXVECTOR3 v1, v2; // v1 and v2 are the edge vectors of the face
D3DXVECTOR3 vNormal;
v1 = *(D3DXVECTOR3*)(pNextOutVertex + 1) - *(D3DXVECTOR3*)pNextOutVertex;
v2 = *(D3DXVECTOR3*)(pNextOutVertex + 2) - *(D3DXVECTOR3*)(pNextOutVertex + 1);
D3DXVec3Cross( &vNormal, &v1, &v2 );
D3DXVec3Normalize( &vNormal, &vNormal );
pNextOutVertex->Normal = vNormal;
(pNextOutVertex + 1)->Normal = vNormal;
(pNextOutVertex + 2)->Normal = vNormal;
pNextOutVertex += 3;
// Add the face's edges to the edge mapping table
// Edge 1
int nIndex;
int nVertIndex[3] = { pdwPtRep[pdwIBData[f * 3]],
pdwPtRep[pdwIBData[f * 3 + 1]],
pdwPtRep[pdwIBData[f * 3 + 2]] };
nIndex = FindEdgeInMappingTable( nVertIndex[0], nVertIndex[1], pMapping, dwNumEdges );
// If error, we are not able to proceed, so abort.
if( -1 == nIndex )
{
hr = E_INVALIDARG;
goto cleanup;
}
if( pMapping[nIndex].m_anOldEdge[0] == -1 && pMapping[nIndex].m_anOldEdge[1] == -1 )
{
// No entry for this edge yet. Initialize one.
pMapping[nIndex].m_anOldEdge[0] = nVertIndex[0];
pMapping[nIndex].m_anOldEdge[1] = nVertIndex[1];
pMapping[nIndex].m_aanNewEdge[0][0] = f * 3;
pMapping[nIndex].m_aanNewEdge[0][1] = f * 3 + 1;
++nNumMaps;
} else
{
// An entry is found for this edge. Create
// a quad and output it.
assert( nNumMaps > 0 );
pMapping[nIndex].m_aanNewEdge[1][0] = f * 3; // For clarity
pMapping[nIndex].m_aanNewEdge[1][1] = f * 3 + 1;
// First triangle
pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[0][1];
pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[0][0];
pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[1][0];
// Second triangle
pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[1][1];
pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[1][0];
pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[0][0];
// pMapping[nIndex] is no longer needed. Copy the last map entry
// over and decrement the map count.
pMapping[nIndex] = pMapping[nNumMaps-1];
FillMemory( &pMapping[nNumMaps-1], sizeof( pMapping[nNumMaps-1] ), 0xFF );
--nNumMaps;
}
// Edge 2
nIndex = FindEdgeInMappingTable( nVertIndex[1], nVertIndex[2], pMapping, dwNumEdges );
// If error, we are not able to proceed, so abort.
if( -1 == nIndex )
{
hr = E_INVALIDARG;
goto cleanup;
}
if( pMapping[nIndex].m_anOldEdge[0] == -1 && pMapping[nIndex].m_anOldEdge[1] == -1 )
{
pMapping[nIndex].m_anOldEdge[0] = nVertIndex[1];
pMapping[nIndex].m_anOldEdge[1] = nVertIndex[2];
pMapping[nIndex].m_aanNewEdge[0][0] = f * 3 + 1;
pMapping[nIndex].m_aanNewEdge[0][1] = f * 3 + 2;
++nNumMaps;
} else
{
// An entry is found for this edge. Create
// a quad and output it.
assert( nNumMaps > 0 );
pMapping[nIndex].m_aanNewEdge[1][0] = f * 3 + 1;
pMapping[nIndex].m_aanNewEdge[1][1] = f * 3 + 2;
// First triangle
pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[0][1];
pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[0][0];
pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[1][0];
// Second triangle
pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[1][1];
pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[1][0];
pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[0][0];
// pMapping[nIndex] is no longer needed. Copy the last map entry
// over and decrement the map count.
pMapping[nIndex] = pMapping[nNumMaps-1];
FillMemory( &pMapping[nNumMaps-1], sizeof( pMapping[nNumMaps-1] ), 0xFF );
--nNumMaps;
}
// Edge 3
nIndex = FindEdgeInMappingTable( nVertIndex[2], nVertIndex[0], pMapping, dwNumEdges );
// If error, we are not able to proceed, so abort.
if( -1 == nIndex )
{
hr = E_INVALIDARG;
goto cleanup;
}
if( pMapping[nIndex].m_anOldEdge[0] == -1 && pMapping[nIndex].m_anOldEdge[1] == -1 )
{
pMapping[nIndex].m_anOldEdge[0] = nVertIndex[2];
pMapping[nIndex].m_anOldEdge[1] = nVertIndex[0];
pMapping[nIndex].m_aanNewEdge[0][0] = f * 3 + 2;
pMapping[nIndex].m_aanNewEdge[0][1] = f * 3;
++nNumMaps;
} else
{
// An entry is found for this edge. Create
// a quad and output it.
assert( nNumMaps > 0 );
pMapping[nIndex].m_aanNewEdge[1][0] = f * 3 + 2;
pMapping[nIndex].m_aanNewEdge[1][1] = f * 3;
// First triangle
pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[0][1];
pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[0][0];
pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[1][0];
// Second triangle
pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[1][1];
pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[1][0];
pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[0][0];
// pMapping[nIndex] is no longer needed. Copy the last map entry
// over and decrement the map count.
pMapping[nIndex] = pMapping[nNumMaps-1];
FillMemory( &pMapping[nNumMaps-1], sizeof( pMapping[nNumMaps-1] ), 0xFF );
--nNumMaps;
}
}
// Now the entries in the edge mapping table represent
// non-shared edges. What they mean is that the original
// mesh has openings (holes), so we attempt to patch them.
// First we need to recreate our mesh with a larger vertex
// and index buffers so the patching geometry could fit.
DXUTTRACE( L"Faces to patch: %d\n", nNumMaps );
// Create a mesh with large enough vertex and
// index buffers.
SHADOWVERT *pPatchVBData = NULL;
DWORD *pdwPatchIBData = NULL;
ID3DXMesh *pPatchMesh = NULL;
// Make enough room in IB for the face and up to 3 quads for each patching face
hr = D3DXCreateMesh( nNextIndex / 3 + nNumMaps * 7,
( pInputMesh->GetNumFaces() + nNumMaps ) * 3,
D3DXMESH_32BIT,
SHADOWVERT::Decl,
pd3dDevice,
&pPatchMesh );
if( FAILED( hr ) )
goto cleanup;
hr = pPatchMesh->LockVertexBuffer( 0, (LPVOID*)&pPatchVBData );
if( SUCCEEDED( hr ) )
hr = pPatchMesh->LockIndexBuffer( 0, (LPVOID*)&pdwPatchIBData );
if( pPatchVBData && pdwPatchIBData )
{
ZeroMemory( pPatchVBData, sizeof(SHADOWVERT) * ( pInputMesh->GetNumFaces() + nNumMaps ) * 3 );
ZeroMemory( pdwPatchIBData, sizeof(DWORD) * ( nNextIndex + 3 * nNumMaps * 7 ) );
// Copy the data from one mesh to the other
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -