//-------------------------------------------------------------------------------------- // Name: Write() // Desc: Writes the mesh to an XBG file //-------------------------------------------------------------------------------------- HRESULT Mesh::Write( const CHAR* strFilename ) { // Open the file DWORD dwNumBytesWritten; HANDLE hFile = CreateFile( strFilename, FILE_ALL_ACCESS, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); if( hFile == INVALID_HANDLE_VALUE ) { ATG_PrintError( "File not found!\n" ); return E_FAIL; } // Compute storage requirements DWORD g_dwFrameSpace = 0; DWORD g_dwMeshSpace = 0; DWORD g_dwVertexSpace = 0; DWORD g_dwIndexSpace = 0; for( DWORD i = 0; i < m_dwNumFrames; i++ ) { MESH_FRAME* pFrame = &m_pFrames[i]; MESH_DATA* pMesh = pFrame->m_pMeshData; DWORD dwIndexSize = pMesh->m_IB.Common & D3DINDEXBUFFER_INDEX32 ? sizeof( DWORD ) : sizeof( WORD ); g_dwFrameSpace += sizeof( MESH_FRAME ); g_dwMeshSpace += sizeof( MESH_DATA ) - sizeof( MESH_SUBSET ); g_dwMeshSpace += sizeof( MESH_SUBSET ) * pMesh->m_dwNumSubsets; g_dwIndexSpace += ( ( dwIndexSize * pMesh->m_dwNumIndices + ( 4096 - 1 ) ) / 4096 ) * 4096; g_dwVertexSpace += ( ( pMesh->m_dwVertexSize * pMesh->m_dwNumVertices + ( 4096 - 1 ) ) / 4096 ) * 4096; } DWORD dwNumSysMemBytes = g_dwFrameSpace + g_dwMeshSpace; DWORD dwNumVidMemBytes = g_dwIndexSpace + g_dwVertexSpace; // Read the magic number XBG_HEADER xbgHeader; xbgHeader.dwMagic = XBG7_FILE_ID; xbgHeader.dwSysMemSize = dwNumSysMemBytes; xbgHeader.dwVidMemSize = dwNumVidMemBytes; xbgHeader.dwNumFrames = m_dwNumFrames; WriteFile( hFile, &xbgHeader, sizeof( XBG_HEADER ), &dwNumBytesWritten, NULL ); DWORD g_dwFramesFileOffset = sizeof( XBG_HEADER ); DWORD g_dwMeshesFileOffset = g_dwFramesFileOffset + g_dwFrameSpace; DWORD g_dwIndicesFileOffset = 0; DWORD g_dwVerticesFileOffset = g_dwIndexSpace; // Write the frames for( DWORD i = 0; i < m_dwNumFrames; i++ ) { MESH_FRAME* pFrame = &m_pFrames[i]; MESH_DATA* pMesh = pFrame->m_pMeshData; // Write out the frame MESH_FRAME frame = *pFrame; frame.Pad[0] = 0x11111111; if( pFrame->m_pChild ) { DWORD dwOffset = ( DWORD )pFrame->m_pChild - ( DWORD )m_pFrames; frame.m_pChild = ( MESH_FRAME* )( g_dwFramesFileOffset + dwOffset ); } if( pFrame->m_pNext ) { DWORD dwOffset = ( DWORD )pFrame->m_pNext - ( DWORD )m_pFrames; frame.m_pNext = ( MESH_FRAME* )( g_dwFramesFileOffset + dwOffset ); } frame.m_pMeshData = ( MESH_DATA* )g_dwMeshesFileOffset; g_dwMeshesFileOffset += ( sizeof( MESH_DATA ) - sizeof( MESH_SUBSET ) ) + sizeof( MESH_SUBSET ) * pMesh->m_dwNumSubsets; // Write out frame info WriteFile( hFile, &frame, sizeof( MESH_FRAME ), &dwNumBytesWritten, NULL ); } // Write the meshes for( DWORD i = 0; i < m_dwNumFrames; i++ ) { MESH_FRAME* pFrame = &m_pFrames[i]; MESH_DATA* pMesh = pFrame->m_pMeshData; DWORD dwIndexSize = pMesh->m_IB.Common & D3DINDEXBUFFER_INDEX32 ? sizeof( DWORD ) : sizeof( WORD ); D3DFORMAT d3dIndexFormat = pMesh->m_IB.Common & D3DINDEXBUFFER_INDEX32 ? D3DFMT_INDEX32 : D3DFMT_INDEX16; // Write out the meshdata MESH_DATA mesh = *pMesh; if( pMesh->m_dwNumVertices ) { XGSetVertexBufferHeader( pMesh->m_dwNumVertices * pMesh->m_dwVertexSize, 0, D3DPOOL_DEFAULT, g_dwVerticesFileOffset, &mesh.m_VB ); g_dwVerticesFileOffset += ( ( pMesh->m_dwVertexSize * pMesh->m_dwNumVertices + ( 4096 - 1 ) ) / 4096 ) * 4096; } if( mesh.m_dwNumIndices ) { XGSetIndexBufferHeader( pMesh->m_dwNumIndices * dwIndexSize, 0, d3dIndexFormat, D3DPOOL_DEFAULT, g_dwIndicesFileOffset, &mesh.m_IB ); g_dwIndicesFileOffset += ( ( pMesh->m_dwNumIndices * dwIndexSize + ( 4096 - 1 ) ) / 4096 ) * 4096; } mesh.m_pVertexDecl = NULL; // Write out mesh info WriteFile( hFile, &mesh, sizeof( MESH_DATA ) - sizeof( MESH_SUBSET ), &dwNumBytesWritten, NULL ); // Write out subset data for( DWORD j = 0; j < pMesh->m_dwNumSubsets; j++ ) { MESH_SUBSET subset = pMesh->m_pSubsets[j]; subset.Pad[0] = 0x11111111; subset.pTexture = NULL; WriteFile( hFile, &subset, sizeof( MESH_SUBSET ), &dwNumBytesWritten, NULL ); } } static BYTE Pad[4096] = { 0 }; // Write indices for( DWORD i = 0; i < m_dwNumFrames; i++ ) { MESH_FRAME* pFrame = &m_pFrames[i]; MESH_DATA* pMesh = pFrame->m_pMeshData; if( pMesh->m_dwNumIndices ) { VOID* pIndexData; DWORD dwIndexSize = pMesh->m_IB.Common & D3DINDEXBUFFER_INDEX32 ? sizeof( DWORD ) : sizeof( WORD ); DWORD dwSize = pMesh->m_dwNumIndices * dwIndexSize; pMesh->m_IB.Lock( 0, 0, &pIndexData, 0 ); WriteFile( hFile, pIndexData, dwSize, &dwNumBytesWritten, NULL ); pMesh->m_IB.Unlock(); // Pad to aligment DWORD dwPadSize = ( 4096 - ( dwSize % 4096 ) ) % 4096; if( dwPadSize ) WriteFile( hFile, Pad, dwPadSize, &dwNumBytesWritten, NULL ); } } // Write vertices for( DWORD i = 0; i < m_dwNumFrames; i++ ) { MESH_FRAME* pFrame = &m_pFrames[i]; MESH_DATA* pMesh = pFrame->m_pMeshData; if( pMesh->m_dwNumVertices ) { VOID* pVertexData; DWORD dwSize = pMesh->m_dwNumVertices * pMesh->m_dwVertexSize; pMesh->m_VB.Lock( 0, 0, &pVertexData, 0 ); WriteFile( hFile, pVertexData, dwSize, &dwNumBytesWritten, NULL ); pMesh->m_VB.Unlock(); // Pad to aligment DWORD dwPadSize = ( 4096 - ( dwSize % 4096 ) ) % 4096; if( dwPadSize ) WriteFile( hFile, Pad, dwPadSize, &dwNumBytesWritten, NULL ); } } // Done with the file CloseHandle( hFile ); return S_OK; }
ZED_UINT32 Model::Load( const char *p_pFilename ) { HANDLE ModelFile = ZED_NULL; ModelFile = CreateFile( p_pFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, ZED_NULL ); if( ModelFile == ZED_NULL ) { zedTrace( "Failed to load model: %s\n", p_pFilename ); return ZED_FAIL; } // TEMP! // Don't care about the header's correctness SetFilePointer( ModelFile, 87, ZED_NULL, FILE_CURRENT ); // !TEMP // Get the amount of vertices to process ZED_UINT64 RawVertCount = 0; DWORD ReadIn = 0; ReadFile( ModelFile, &RawVertCount, sizeof( ZED_UINT64 ), &ReadIn, NULL ); ZED_UINT64 VertCount = ( ( RawVertCount/4 )/3 )/2; m_pVertexData = ( LPVERTEX_V1 )malloc( VertCount*sizeof( VERTEX_V1 ) );/*XPhysicalAlloc( VertCount*sizeof( VERTEX_V1 ), MAXULONG_PTR, 0, PAGE_READWRITE );*/ ReadFile( ModelFile, m_pVertexData, VertCount*sizeof( VERTEX_V1 ), &ReadIn, NULL ); if( ReadIn != VertCount*sizeof( VERTEX_V1 ) ) { zedTrace( "[ERROR] Failed to read the vertex data for %s\n", p_pFilename ); return ZED_FAIL; } // Skip over the indices and face normal header SetFilePointer( ModelFile, 12, ZED_NULL, FILE_CURRENT ); // NOT WORKING!! ZED_UINT64 RawFaceCount = 0; // Should be 268272 for GraveGuy.zed ReadFile( ModelFile, &RawFaceCount, sizeof( ZED_UINT64 ), &ReadIn, NULL ); ZED_UINT64 FaceCount = ( RawFaceCount/12 )/3; m_pFaceData = ( LPFACE_V1 )malloc( sizeof( LPFACE_V1 )*FaceCount );/*XPhysicalAlloc( sizeof( ZED_UINT16 )*FaceCount, MAXULONG_PTR, MAXULONG_PTR, PAGE_READWRITE );*/ ReadFile( ModelFile, m_pFaceData, sizeof( FACE_V1 )*FaceCount, &ReadIn, NULL ); if( ReadIn != sizeof( FACE_V1 )*FaceCount ) { zedTrace( "[ERROR] Failed to read the face data for %s\n", p_pFilename ); } CloseHandle( ModelFile ); // Set up the index and vertex buffers m_pVertexBuffer = new IDirect3DVertexBuffer8( ); m_pIndexBuffer = new IDirect3DIndexBuffer8( ); XGSetVertexBufferHeader( 0, 0, 0, 0, m_pVertexBuffer, 0 ); void *pVertData = XPhysicalAlloc( RawVertCount, MAXULONG_PTR, MAXULONG_PTR, PAGE_READWRITE ); m_pVertexBuffer->Register( pVertData ); memcpy( pVertData, m_pVertexData, RawVertCount ); XGSetIndexBufferHeader( 0, 0, D3DFMT_INDEX16, 0, m_pIndexBuffer, 0 ); return ZED_OK; }