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 + -
显示快捷键?