trpage_warchive.cpp
来自「最新osg包」· C++ 代码 · 共 1,608 行 · 第 1/3 页
CPP
1,608 行
tileTable.SetNumTiles(lodSize.x,lodSize.y,i); } } firstHeaderWrite = false; } // Now set the individual tile locations // Nothing special need to be done with version 2.1 since // only tile with lod 0 will be found in the tileFiles container for (unsigned int i=0;i<tileFiles.size();i++) { TileFile &tf = tileFiles[i]; for (unsigned int j=0;j<tf.tiles.size();j++) { TileFileEntry &te = tf.tiles[j]; trpgwAppAddress addr; addr.file = tf.id; addr.offset = te.offset; tileTable.SetTile(te.x,te.y,te.lod,addr,te.zmin,te.zmax); } tf.tiles.clear(); } } // Write all the headers into a buffer if (!header.Write(buf)) return false; // Do the mat table and texture table // These can be different depending on the version switch (majorVersion) { case 1: { trpgMatTable1_0 matTable1_0(matTable); trpgTexTable1_0 texTable1_0(texTable); trpgTileTable1_0 tileTable1_0(tileTable); if (!matTable1_0.Write(buf) || !texTable1_0.Write(buf) || !modelTable.Write(buf) || !tileTable1_0.Write(buf) || !lightTable.Write(buf) || !rangeTable.Write(buf)) return false; } break; case 2: if(!header.GetIsMaster()||texTable.isValid()) { if(!texTable.Write(buf)) { strcpy(errMess, "Error writing texture table"); if(texTable.getErrMess()) { strcat(errMess, ": "); strcat(errMess, texTable.getErrMess()); return false; } } } //These tables will not be populated if this is the master table. if(!header.GetIsMaster()) { if (!matTable.Write(buf)) { strcpy(errMess, "Error writing material table"); if(matTable.getErrMess()) { strcat(errMess, ": "); strcat(errMess, matTable.getErrMess()); return false; } } if(!modelTable.Write(buf) ) { strcpy(errMess, "Error writing model table"); if(modelTable.getErrMess()) { strcat(errMess, ": "); strcat(errMess, modelTable.getErrMess()); return false; } } } //always write the tile table, even if we are a master if(!tileTable.Write(buf)) { strcpy(errMess, "Error writing tile table"); if(tileTable.getErrMess()) { strcat(errMess, ": "); strcat(errMess, tileTable.getErrMess()); return false; } } if(!header.GetIsMaster()) { if(!lightTable.Write(buf)) { strcpy(errMess, "Error writing light table"); if(lightTable.getErrMess()) { strcat(errMess, ": "); strcat(errMess, lightTable.getErrMess()); return false; } } if(!rangeTable.Write(buf)) { strcpy(errMess, "Error writing range table"); if(rangeTable.getErrMess()) { strcat(errMess, ": "); strcat(errMess, rangeTable.getErrMess()); return false; } } if (!textStyleTable.Write(buf)) { strcpy(errMess,"Error writing text style table"); if (textStyleTable.getErrMess()) { strcat(errMess, ": "); strcat(errMess, textStyleTable.getErrMess()); return false; } } if (!supportStyleTable.Write(buf)) { strcpy(errMess,"Error writing support style table"); if (supportStyleTable.getErrMess()) { strcat(errMess, ": "); strcat(errMess, supportStyleTable.getErrMess()); return false; } } if (!labelPropertyTable.Write(buf)) { strcpy(errMess,"Error writing label property table"); if (labelPropertyTable.getErrMess()) { strcat(errMess, ": "); strcat(errMess, labelPropertyTable.getErrMess()); return false; } } } break; } // Write the disk header int32 magic = GetMagicNumber(); if (ness != cpuNess) magic = trpg_byteswap_int(magic); if (fwrite(&magic,sizeof(int32),1,fp) != 1) { strcpy(errMess, "Could not write the magic number"); return false; } // Write the header length int32 headerSize = buf.length(); int headLen = headerSize; if (ness != cpuNess) headerSize = trpg_byteswap_int(headerSize); if (fwrite(&headerSize,1,sizeof(int32),fp) != sizeof(int32)) { strcpy(errMess, "Could not write the header size"); return false; } // Write the buffer const char *data = buf.getData(); if (WriteHeaderData(data,headLen,fp) != headLen) { strcpy(errMess, "Could not write the buffer"); return false; } // Note: Not sure what this is char space[40]; if (fwrite(space,1,4,fp) != 4) return false; // Flush output fflush(fp); // Head back to the start of the file rewind(fp); return true;}/* Get a new appendable file. */trpgwAppFile *trpgwArchive::GetNewWAppFile(trpgEndian inNess,const char *fileName,bool reuse){ return new trpgwAppFile(inNess,fileName,reuse);}/* Get a new write image helper */trpgwImageHelper *trpgwArchive::GetNewWImageHelper(trpgEndian ness,char *dir,trpgTexTable &inTexTable){ bool separateGeo = false; int majorVer,minorVer; GetHeader()->GetVersion(majorVer,minorVer); if((majorVer >= TRPG_NOMERGE_VERSION_MAJOR) && (minorVer>=TRPG_NOMERGE_VERSION_MINOR)) { separateGeo = true; } return new trpgwImageHelper(ness,dir,inTexTable,separateGeo);}/* Increment Tile File. Close the current tile file (if any) and open the next one. Also update the records we're keeping of which tiles went in which files.*/bool trpgwArchive::IncrementTileFile(){ if (tileMode != TileLocal) return false; // Closes the current tile file if (tileFile) { delete tileFile; tileFile=NULL; } // Open the next one char filename[1024]; sprintf(filename,"%s" PATHSEPERATOR "tileFile_%d.tpf",dir,tileFileCount++); tileFile = GetNewWAppFile(ness,filename,true); if (!tileFile->isValid()) return false; // Add another TileFiles entry tileFiles.resize(tileFiles.size()+1); tileFiles[tileFiles.size()-1].id = tileFiles.size()-1; return true;}/* Designate Tile File Close the current tile file (if any) and open one with the given base name. This is used for regenerate.*/bool trpgwArchive::DesignateTileFile(int id){ if (tileMode != TileLocal) return false; // Close the current tile file if (tileFile) { delete tileFile; tileFile=NULL; } // Open a named on char filename[1024]; sprintf(filename,"%s" PATHSEPERATOR "tileFile_%d.tpf",dir,id); tileFile = GetNewWAppFile(ness,filename); if (!tileFile->isValid()) return false; // Add another TileFiles entry tileFiles.resize(tileFiles.size()+1); tileFiles[tileFiles.size()-1].id = id; return true;}/* WriteTile. Write the given tile (x,y,lod) in the appropriate mode (Local or External). The tile header is given separately from the rest of the tile, but they are appended together to the file.*/bool trpgwArchive::WriteTile(unsigned int x,unsigned int y,unsigned int lod, float zmin, float zmax, const trpgMemWriteBuffer *head,const trpgMemWriteBuffer *buf, int32& fileId, int32& fileOffset){ FILE *tfp=NULL; if (!isValid()) return false; fileId = -1; fileOffset = -1; // External tiles get their own individual files if (tileMode == TileExternal || tileMode == TileExternalSaved) { // Make a new filename char filename[1024]; // Note: Windows specific sprintf(filename,"%s" PATHSEPERATOR "tile_%d_%d_%d.tpt",dir,x,y,lod); if (!(tfp = osgDB::fopen(filename,"wb"))) return false; // Write the header first unsigned int len; const char *data; if (head) { data = head->getData(); len = head->length(); if (fwrite(data,sizeof(char),len,tfp) != len) { fclose(tfp); return false; } } // Write the buffer out data = buf->getData(); len = buf->length(); if (fwrite(data,sizeof(char),len,tfp) != len) { fclose(tfp); return false; } fclose(tfp); // In version 2.1 and over we still add an entry to the tile table // to save the zmin and zmax value. if(tileMode == TileExternalSaved && lod == 0) { externalTiles.push_back(TileFileEntry()); TileFileEntry& tf = externalTiles.back(); tf.x = x; tf.y = y; tf.lod = lod; tf.offset = -1; tf.zmax = zmax; tf.zmin = zmin; } } else { // Local tiles get appended to a tile file if (!tileFile) { if (!IncrementTileFile()) return false; } // See if we've exceeded the maximum advised size for a tile file while (maxTileFileLen > 0 && tileFile->GetLengthWritten() > maxTileFileLen) { if (!IncrementTileFile()) return false; } int32 pos = static_cast<int32>(tileFile->Pos()); if (!tileFile->Append(head,buf)) return false; // Keep track of the fact that this went here TileFile &tf = tileFiles[tileFiles.size()-1]; TileFileEntry te; te.x = x; te.y = y; te.lod = lod; te.zmin = zmin; te.zmax = zmax; te.offset = pos; if(majorVersion == 2 && minorVersion >=1) { // Version 2.1, we need to keep track of lod 0 only if(lod == 0) tf.tiles.push_back(te); } else tf.tiles.push_back(te); fileOffset = pos; fileId = tileFiles[tileFiles.size()-1].id; } return true;}/* **************** Geometry Stats Used by the Geometry Helper **************** */trpgwGeomStats::trpgwGeomStats(){ totalTri = totalStripTri = totalFanTri = totalBagTri = 0; for (int i=0;i<15;i++) { stripStat[i] = fanStat[i] = 0; } stripGeom = fanGeom = bagGeom = 0; stateChanges = 0; numStrip = numFan = 0; totalQuad = 0;}trpgwGeomStats::~trpgwGeomStats(){}/* **************** Geometry Helper Here, since it's used with a write archive. **************** */trpgwGeomHelper::trpgwGeomHelper(){ buf = NULL; mode = trpgGeometry::Triangles;}trpgwGeomHelper::~trpgwGeomHelper(){}void trpgwGeomHelper::SetMode(int m){ if (m == trpgGeometry::Triangles || m == trpgGeometry::Quads) mode = m;}trpgwGeomHelper::trpgwGeomHelper(trpgWriteBuffer *ibuf, int dtype){ init(ibuf,dtype);}void trpgwGeomHelper::init(trpgWriteBuffer *ibuf,int dtype){ buf = ibuf; dataType = dtype; zmin = 1e12; zmax = -1e12;}// Reset back to a clean state (except for the buffer)void trpgwGeomHelper::Reset(){ ResetTri(); ResetPolygon(); zmin = 1e12; zmax = -1e12;}// Reset triangle arrays (usually after a flush)void trpgwGeomHelper::ResetTri(){ strips.Reset(); fans.Reset(); bags.Reset(); tex.resize(0); norm.resize(0); vert.resize(0);}// Start a polygon definitionvoid trpgwGeomHelper::StartPolygon(){ ResetPolygon();}// Finish a polygon definitionvoid trpgwGeomHelper::EndPolygon(){ // See if we can add it to the current triangle arrays if (vert.size() && (matTri != matPoly)) { // Couldn't flush geometry and move on FlushGeom(); } // Turn the polygon into triangles // Note: Only dealing with convex here matTri = matPoly; unsigned int numMats=matTri.size(); switch (mode) { case trpgGeometry::Triangles: { int num = polyVert.size() - 2; int id1,id2; for (int i=0;i<num;i++) { // Note: Handle color /* Swap 1 and 2 positions This lets the Optimizer pick up on triangle fans If you're not using our optimizer this will do very weird things Probably it will screw up backface culling. */ // Note: turned this off because it was broken. Put it back#if 0 id1 = i+1; id2 = i+2; if (num > 1) { id1 = i+2; id2 = i+1; }#else id1 = i+1; id2 = i+2;#endif // Define the triangle vert.push_back(polyVert[0]); vert.push_back(polyVert[id1]); vert.push_back(polyVert[id2]); norm.push_back(polyNorm[0]); norm.push_back(polyNorm[id1]); norm.push_back(polyNorm[id2]); // multiple textures unsigned int loop; for (loop=0;loop<numMats;loop++) tex.push_back(polyTex[loop]); for (loop=0;loop<numMats;loop++) tex.push_back(polyTex[numMats*id1+loop]); for (loop=0;loop<numMats;loop++) tex.push_back(polyTex[numMats*id2+loop]); } } break; case trpgGeometry::Quads: { int num = polyVert.size(); if (polyVert.size() == 4) { for (int i=0;i<num;i++) { vert.push_back(polyVert[i]); norm.push_back(polyNorm[i]); // multiple textures for (unsigned int loop=0;loop<numMats;loop++) tex.push_back(polyTex[numMats*i+loop]); } } } break; } ResetPolygon();}// Clean out the polygon arraysvoid trpgwGeomHelper::ResetPolygon(){ tmpTex.resize(0); matPoly.resize(0); polyTex.resize(0); polyNorm.resize(0); polyVert.resize(0);}// Set the current color// Note: Required
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?