void DefBillb(int i, unsigned int glyph) { #if 0 //BillboardT t; int i = NewBillbT(); if(i < 0) return -1; #endif BillboardT* t = &g_billbT[i]; t->on = true; #if 0 char rawtex[64]; StripPathExtension(tex, rawtex); strcpy(t->name, rawtex); char texpath[128]; sprintf(texpath, "billboards/%s", rawtex); FindTextureExtension(texpath); //CreateTexture(t.tex, texpath); QueueTexture(&t->tex, texpath, true, true); #elif 0 QueueTexture(&t->tex, tex, true, true); #else t->glyph = glyph; #endif //g_billbT.push_back(t); //return g_billbT.size() - 1; //return i; }
bool Quake3BSP_GL::LoadBSP(const char *strFileName) { FILE *fp = NULL; int i = 0; // Check if the .bsp file could be opened if(fopen_s(&fp, strFileName, "rb") != NULL){ // Failed to open the file, return false. return false; } // Initialize the header and lump structures BSPHeader header = {0}; BSPLump lumps[MAX_LUMPS] = {0}; // Read header data fread(&header, 1, sizeof(BSPHeader), fp); fread(&lumps, MAX_LUMPS, sizeof(BSPLump), fp); // Once this is done, we know the sizes we need to allocate for all the data // since that was in the header m_numOfVerts = lumps[VERTICES_LUMP].length / sizeof(BSPVertex); m_pVerts = new BSPVertex [m_numOfVerts]; m_vertexData = new VertV3FUV0UV1[ m_numOfVerts ]; m_numOfFaces = lumps[FACES_LUMP].length / sizeof(BSPFace); m_pFaces = new BSPFace [m_numOfFaces]; m_numOfIndices = lumps[INDICES_LUMP].length / sizeof(int); m_pIndices = new int [m_numOfIndices]; m_indices = new short unsigned int [m_numOfIndices]; m_numOfTextures = lumps[TEXTURE_LUMP].length / sizeof(BSPTexture); m_pTextures = new BSPTexture [m_numOfTextures]; // Now we allocate the buffer for lightmap data and read it in. m_numOfLightmaps = lumps[LIGHTMAPS_LUMP].length / sizeof(BSPLightmap); m_pLightmaps = new BSPLightmap [m_numOfLightmaps ]; // Now that we have allocated enough space for the lightmap // data, let's read it in and build the lightmap textures // later on. fseek(fp, lumps[LIGHTMAPS_LUMP].offset, SEEK_SET); unsigned int h=0; for(i = 0; i < m_numOfLightmaps ; i++){ fread(&m_pLightmaps[i], 1, sizeof(BSPLightmap), fp); // Since we are just reading the data, lets adjust the gamma now. // So we don't have to worry about it later. // We are going to factor it with a gamma of +10. AdjustGamma((unsigned char *)m_pLightmaps[i].imageBits, 128*128*3,10); // Build the lightmap data into a texture BuildTextureDataFromImageBits((unsigned char *)m_pLightmaps[i].imageBits,128,128); m_lightmaps[i]=h; h++; } // Move to the vertex data in the file fseek(fp, lumps[VERTICES_LUMP].offset, SEEK_SET); // Going to go through the verticies and flip them to Z axis forward, and Y axis up // Like the model loader, it's flipped from how our renderer expects it. for(i = 0; i < m_numOfVerts; i++){ fread(&m_pVerts[i], 1, sizeof(BSPVertex), fp); float tempY = m_pVerts[i].vPosition.y; m_pVerts[i].vPosition.y = m_pVerts[i].vPosition.z; m_pVerts[i].vPosition.z = -tempY; m_vertexData[i].x = m_pVerts[i].vPosition.x; m_vertexData[i].y = m_pVerts[i].vPosition.y; m_vertexData[i].z = m_pVerts[i].vPosition.z; m_vertexData[i].u0 = m_pVerts[i].vTextureCoord.x; m_vertexData[i].v0 = 1.0f - m_pVerts[i].vTextureCoord.y; m_vertexData[i].u1 = m_pVerts[i].vLightmapCoord.x; m_vertexData[i].v1 = m_pVerts[i].vLightmapCoord.y; } // Now go to where the indices are, read that data in, // Then go to the face data and read it in as well. fseek(fp, lumps[INDICES_LUMP].offset, SEEK_SET); fread(m_pIndices, m_numOfIndices, sizeof(int), fp); for(int j=0; j<m_numOfIndices; ++j){ m_indices[j] = m_pIndices[j]; } fseek(fp, lumps[FACES_LUMP].offset, SEEK_SET); fread(m_pFaces, m_numOfFaces, sizeof(BSPFace), fp); // Lastly, lets get the texture info so that we can add the filename extension to it // since that is not stored within the Quake3BSP file format. So we'll need to do some // checking to see what extension it is, even though chances are it's .jpg. fseek(fp, lumps[TEXTURE_LUMP].offset, SEEK_SET); fread(m_pTextures, m_numOfTextures, sizeof(BSPTexture), fp); // Append on the extension name unsigned int k=0; for(i = 0; i < m_numOfTextures; i++){ FindTextureExtension(m_pTextures[i].strName); if(strstr(m_pTextures[i].strName,".")) { // This means the texture has an extension, so it is not a shader component // or some other non texture file format, so lets load it up. GLuint textureID=0; m_textureNames.push_back(m_pTextures[i].strName); textureID = Renderer::GetInstance().InitializeTexture(m_pTextures[i].strName); m_textureList.push_back(textureID); m_textures[i]=k; k++; } else { // Just pick some large number we can check to mean this face has no texture. m_textures[i]=INVALID_TEXTURE; } } // Now to deal with BSP data. There is alot to read in and store. // First allocate space for the node data, then read it in. m_numOfNodes = lumps[BSP_NODE_LUMP].length / sizeof(BSPNode); m_pNodes = new BSPNode [m_numOfNodes]; fseek(fp, lumps[BSP_NODE_LUMP].offset, SEEK_SET); fread(m_pNodes, m_numOfNodes, sizeof(BSPNode), fp); // Next, allocate space for leaf data and read it in. m_numOfLeafs = lumps[LEAF_LUMP].length / sizeof(BSPLeaf); m_pLeafs = new BSPLeaf [m_numOfLeafs]; fseek(fp, lumps[LEAF_LUMP].offset, SEEK_SET); fread(m_pLeafs, m_numOfLeafs, sizeof(BSPLeaf), fp); // Need to change the data in the leaf to reflect our axis, which is // Y axis up instead of Z as it is in the Quake3 bsp level data. for(i = 0; i < m_numOfLeafs; i++){ int oldY = m_pLeafs[i].min.y; m_pLeafs[i].min.y = m_pLeafs[i].min.z; m_pLeafs[i].min.z = -oldY; oldY = m_pLeafs[i].max.y; m_pLeafs[i].max.y = m_pLeafs[i].max.z; m_pLeafs[i].max.z = -oldY; } // Now allocate space for leaf face data then read it in. m_numOfLeafFaces = lumps[LEAF_INDICE_FACE_LUMP].length / sizeof(int); m_pLeafFaces = new int [m_numOfLeafFaces]; fseek(fp, lumps[LEAF_INDICE_FACE_LUMP].offset, SEEK_SET); fread(m_pLeafFaces, m_numOfLeafFaces, sizeof(int), fp); // Also allocate space for splitter plan data and read it in. m_numOfPlanes = lumps[SPLITTING_PLANE_LUMP].length / sizeof(BSPPlane); m_pPlanes = new BSPPlane [m_numOfPlanes]; fseek(fp, lumps[SPLITTING_PLANE_LUMP].offset, SEEK_SET); fread(m_pPlanes, m_numOfPlanes, sizeof(BSPPlane), fp); // Again need to format the normals in the plane to reflect our // axis change of Y being the up axis for(i = 0; i < m_numOfPlanes; i++){ float oldY = m_pPlanes[i].vNormal.y; m_pPlanes[i].vNormal.y = m_pPlanes[i].vNormal.z; m_pPlanes[i].vNormal.z = -oldY; } // Lastly we want to get our visibility data. There may or may not be // visibility data, so we scan to the place in the file it should be // then check our length, if we have nothing there, then we'll // just set our clusters to null and be done with it. fseek(fp, lumps[PVS_VIS_LUMP].offset, SEEK_SET); if(lumps[PVS_VIS_LUMP].length){ // There is valid vis data. So first read in the number of clusters // Then we'll allocate enough space for all the clusters and // lastly read all the vis data in as bitsets for each cluster. fread(&(m_clusters.numOfClusters), 1, sizeof(int), fp); fread(&(m_clusters.bytesPerCluster), 1, sizeof(int), fp); int size = m_clusters.numOfClusters * m_clusters.bytesPerCluster; m_clusters.pBitsets = new byte [size]; fread(m_clusters.pBitsets, 1, sizeof(byte) * size, fp); } else { m_clusters.pBitsets = NULL; } // All done, close up and return fclose(fp); return true; }
bool CQuake3BSP::LoadBSP(const char *strFileName) { FILE *fp = NULL; int i = 0; // Check if the .bsp file could be opened if((fp = fopen(strFileName, "rb")) == NULL) { // Display an error message and quit if the file can't be found. MessageBox(g_hWnd, "Could not find BSP file!", "Error", 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); // Now we know all the information about our file. We can // then allocate the needed memory for our member variables. // Allocate the 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 the index memory m_numOfIndices = lumps[kIndices].length / sizeof(int); m_pIndices = new int [m_numOfIndices]; // Allocate memory to read in the texture information. m_numOfTextures = lumps[kTextures].length / sizeof(tBSPTexture); m_pTextures = new tBSPTexture [m_numOfTextures]; // Allocate memory to read in the lightmap data. m_numOfLightmaps = lumps[kLightmaps].length / sizeof(tBSPLightmap); tBSPLightmap *pLightmaps = new tBSPLightmap [m_numOfLightmaps ]; // Seek to the position in the file that stores the vertex information fseek(fp, lumps[kVertices].offset, SEEK_SET); // Go through all of the vertices that need to be read and swap axis's for(i = 0; i < m_numOfVerts; i++) { // Read in the current vertex fread(&m_pVerts[i], 1, sizeof(tBSPVertex), fp); // Swap the y and z values, and negate the new z so Y is up. float temp = m_pVerts[i].vPosition.y; m_pVerts[i].vPosition.y = m_pVerts[i].vPosition.z; m_pVerts[i].vPosition.z = -temp; } // Seek to the position in the file that stores the index information fseek(fp, lumps[kIndices].offset, SEEK_SET); // Read in all the index information fread(m_pIndices, m_numOfIndices, sizeof(int), fp); // Seek to the position in the file that stores the face information fseek(fp, lumps[kFaces].offset, SEEK_SET); // Read in all the face information fread(m_pFaces, m_numOfFaces, sizeof(tBSPFace), fp); // Seek to the position in the file that stores the texture information fseek(fp, lumps[kTextures].offset, SEEK_SET); // Read in all the texture information fread(m_pTextures, m_numOfTextures, sizeof(tBSPTexture), fp); // Go through all of the textures for(i = 0; i < m_numOfTextures; i++) { // Find the extension if any and append it to the file name FindTextureExtension(m_pTextures[i].strName); // Create a texture from the image CreateTexture(m_textures[i], m_pTextures[i].strName); } // Seek to the position in the file that stores the lightmap information fseek(fp, lumps[kLightmaps].offset, SEEK_SET); // Go through all of the lightmaps and read them in for(i = 0; i < m_numOfLightmaps ; i++) { // Read in the RGB data for each lightmap fread(&pLightmaps[i], 1, sizeof(tBSPLightmap), fp); // Create a texture map for each lightmap that is read in. The lightmaps // are always 128 by 128. CreateLightmapTexture(m_lightmaps[i], (unsigned char *)pLightmaps[i].imageBits, 128, 128); } // Delete the image bits because we are already done with them delete [] pLightmaps; // Store the number of nodes and allocate the memory to hold them m_numOfNodes = lumps[kNodes].length / sizeof(tBSPNode); m_pNodes = new tBSPNode [m_numOfNodes]; // Seek to the position in the file that hold the nodes and store them in m_pNodes fseek(fp, lumps[kNodes].offset, SEEK_SET); fread(m_pNodes, m_numOfNodes, sizeof(tBSPNode), fp); // Store the number of leafs and allocate the memory to hold them m_numOfLeafs = lumps[kLeafs].length / sizeof(tBSPLeaf); m_pLeafs = new tBSPLeaf [m_numOfLeafs]; // Seek to the position in the file that holds the leafs and store them in m_pLeafs fseek(fp, lumps[kLeafs].offset, SEEK_SET); fread(m_pLeafs, m_numOfLeafs, sizeof(tBSPLeaf), fp); // Now we need to go through and convert all the leaf bounding boxes // to the normal OpenGL Y up axis. for(i = 0; i < m_numOfLeafs; i++) { // Swap the min y and z values, then negate the new Z int temp = m_pLeafs[i].min.y; m_pLeafs[i].min.y = m_pLeafs[i].min.z; m_pLeafs[i].min.z = -temp; // Swap the max y and z values, then negate the new Z temp = m_pLeafs[i].max.y; m_pLeafs[i].max.y = m_pLeafs[i].max.z; m_pLeafs[i].max.z = -temp; } // Store the number of leaf faces and allocate the memory for them m_numOfLeafFaces = lumps[kLeafFaces].length / sizeof(int); m_pLeafFaces = new int [m_numOfLeafFaces]; // Seek to the leaf faces lump, then read it's data fseek(fp, lumps[kLeafFaces].offset, SEEK_SET); fread(m_pLeafFaces, m_numOfLeafFaces, sizeof(int), fp); // Store the number of planes, then allocate memory to hold them m_numOfPlanes = lumps[kPlanes].length / sizeof(tBSPPlane); m_pPlanes = new tBSPPlane [m_numOfPlanes]; // Seek to the planes lump in the file, then read them into m_pPlanes fseek(fp, lumps[kPlanes].offset, SEEK_SET); fread(m_pPlanes, m_numOfPlanes, sizeof(tBSPPlane), fp); // Go through every plane and convert it's normal to the Y-axis being up for(i = 0; i < m_numOfPlanes; i++) { float temp = m_pPlanes[i].vNormal.y; m_pPlanes[i].vNormal.y = m_pPlanes[i].vNormal.z; m_pPlanes[i].vNormal.z = -temp; } // Seek to the position in the file that holds the visibility lump fseek(fp, lumps[kVisData].offset, SEEK_SET); // Check if there is any visibility information first if(lumps[kVisData].length) { // Read in the number of vectors and each vector's size fread(&(m_clusters.numOfClusters), 1, sizeof(int), fp); fread(&(m_clusters.bytesPerCluster), 1, sizeof(int), fp); // Allocate the memory for the cluster bitsets int size = m_clusters.numOfClusters * m_clusters.bytesPerCluster; m_clusters.pBitsets = new byte [size]; // Read in the all the visibility bitsets for each cluster fread(m_clusters.pBitsets, 1, sizeof(byte) * size, fp); } // Otherwise, we don't have any visibility data (prevents a crash) else m_clusters.pBitsets = NULL; // Like we do for other data, we read get the size of brushes and allocate memory m_numOfBrushes = lumps[kBrushes].length / sizeof(int); m_pBrushes = new tBSPBrush [m_numOfBrushes]; // Here we read in the brush information from the BSP file fseek(fp, lumps[kBrushes].offset, SEEK_SET); fread(m_pBrushes, m_numOfBrushes, sizeof(tBSPBrush), fp); // Get the size of brush sides, then allocate memory for it m_numOfBrushSides = lumps[kBrushSides].length / sizeof(int); m_pBrushSides = new tBSPBrushSide [m_numOfBrushSides]; // Read in the brush sides data fseek(fp, lumps[kBrushSides].offset, SEEK_SET); fread(m_pBrushSides, m_numOfBrushSides, sizeof(tBSPBrushSide), fp); // Read in the number of leaf brushes and allocate memory for it m_numOfLeafBrushes = lumps[kLeafBrushes].length / sizeof(int); m_pLeafBrushes = new int [m_numOfLeafBrushes]; // Finally, read in the leaf brushes for traversing the bsp tree with brushes fseek(fp, lumps[kLeafBrushes].offset, SEEK_SET); fread(m_pLeafBrushes, m_numOfLeafBrushes, sizeof(int), fp); // Close the file fclose(fp); // Here we allocate enough bits to store all the faces for our bitset m_FacesDrawn.Resize(m_numOfFaces); // Return a success return true; }