Here's the code that I am using right now. The first is my definition of the BSP face:
// BSP face structurestruct tBSPFace{ int textureID; // The index into the texture array int effect; // The index for the effects (-1 == none) int type; // 1 = Polygon, 2 = Patch, 3 = Mesh, 4 = Billboard int startVertexIndex; // The starting index into this face's first vertex int numOfVerts; // The number of vertices for this face int meshVertexIndex; // The index into the first mesh vertex int numMeshVerts; // The number of mesh vertices int lightmapID; // The texture index for the lightmap int lMapCorner[2]; // The face's lightmap corner in the image int lMapSize[2]; // The size of the lightmap section XGVec3 lMapPos; // The 3D origin of lightmap XGVec3 lMapVecs[2]; // The 3D space for s and t unit vector XGVec3 vNormal; // The face normal int size[2]; // The besier patch dimensions};
This way, you can get a better understanding of what each field is compared to your own loaders. Next is my code for the loader, but I'll only show up to the part where the vertex buffer is created and filled so you understand what I am doing:
//--------------------------------------------------------------------------------------// File: CQuake3BSP::LoadBSP// Desc: //--------------------------------------------------------------------------------------bool CQuake3BSP::LoadBSP( char* szFileName ){ HRESULT hr; FILE* fp = NULL; int i = 0; // Open the .bsp file if( ( fp = fopen( szFileName, "rb" ) ) == NULL ) { MessageBoxA( NULL, "Error loading the .bsp file!", "BSP Demo", MB_OK ); return false; } // Initialize the header and lump structures tBSPHeader header = {0}; tBSPLump lumps[kMaxLumps] = {0}; // Read in the header and lump data fread( &header, 1, sizeof( tBSPHeader ), fp ); fread( &lumps, kMaxLumps, sizeof( tBSPLump ), fp ); // Allocate vertex memory m_NumOfVerts = lumps[kVertices].length / sizeof( tBSPVertex ); m_pVerts = new tBSPVertex[m_NumOfVerts]; // Allocate the face memory m_NumOfFaces = lumps[kFaces].length / sizeof( tBSPFace ); m_pFaces = new tBSPFace[m_NumOfFaces]; // Allocate memory for texture information m_NumOfTextures = lumps[kTextures].length / sizeof( tBSPTexture ); tBSPTexture* pTextures = new tBSPTexture[m_NumOfTextures]; // Seek to the position in the file that stores vertex information fseek( fp, lumps[kVertices].offset, SEEK_SET ); // Create a vertex buffer to store all of our vertex data V( DXUTGetD3D9Device()->CreateVertexBuffer( m_NumOfVerts * sizeof( tBSPRenderVertex ), 0, tBSPRenderVertex::FVF, D3DPOOL_MANAGED, &m_pVertexBuffer, NULL ) ); // Lock the vertex buffer and start giving it vertex data tBSPRenderVertex* pVerts = NULL; V( m_pVertexBuffer->Lock( 0, 0, (void**) &pVerts, 0 ) ); // Swap the z coordinate with the y coordinate so that the BSP is rendered // correctly. for( i = 0; i < m_NumOfVerts; i++ ) { // Read current vertex fread( &m_pVerts, 1, sizeof( tBSPVertex ), fp ); // Swap the y and z values and negate the z so y is up float temp = m_pVerts.vecPosition.y; m_pVerts.vecPosition.y = m_pVerts.vecPosition.z; m_pVerts.vecPosition.z = -temp; // Negate the the u tex coord for Direct3D m_pVerts.vecTextureCoord.x *= -1; // Write the most important vertex data to the vertex buffer pVerts.vecPosition = m_pVerts.vecPosition; pVerts.vecTextureCoord = m_pVerts.vecTextureCoord; } // Unlock the vertex buffer V( m_pVertexBuffer->Unlock() );....
Now, for the rendering part. This is my code for rendering faces. I haven't added support for patches, curves or surfaces yet because I haven't gotten that far. I need the general stuff to work first so I can get this game up and running ASAP.
//--------------------------------------------------------------------------------------// Name: CQuake3BSP::RenderFace// Desc: //--------------------------------------------------------------------------------------void CQuake3BSP::RenderFace( int FaceIndex ){ IDirect3DDevice9* pD3DDevice = DXUTGetD3D9Device(); HRESULT hr; // Grab the face from the index passed in tBSPFace* pFace = &m_pFaces[FaceIndex]; // Set the texture V( pD3DDevice->SetTexture( 0, m_ppTextures[pFace->textureID] ) ); // Render the face V( pD3DDevice->SetStreamSource( 0, m_pVertexBuffer, 0, sizeof( tBSPRenderVertex ) ) ); V( pD3DDevice->SetFVF( tBSPRenderVertex::FVF ) ); V( pD3DDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, pFace->startVertexIndex, pFace->numOfVerts - 2 ) ); m_NumOfPrimitives += pFace->numOfVerts - 2; /*V( pD3DDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, pFace->numOfVerts, (m_pVerts + (pFace->startVertexIndex*sizeof(tBSPVertex))), sizeof(tBSPVertex) ) );*/}
How would I go about re-ordering all of this into triangle lists? I've tried various methods, but I can't get anything to work better than what I already have. This sucks. Any ideas?? Thanks.