root/OpenSceneGraph/trunk/src/osgPlugins/txp/trpage_rarchive.cpp @ 13041

Revision 13041, 21.6 kB (checked in by robert, 3 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* ************************
2   Copyright Terrain Experts Inc.
3   Terrain Experts Inc (TERREX) reserves all rights to this source code
4   unless otherwise specified in writing by the President of TERREX.
5   This copyright may be updated in the future, in which case that version
6   supercedes this one.
7   -------------------
8   Terrex Experts Inc.
9   4400 East Broadway #314
10   Tucson, AZ  85711
11   info@terrex.com
12   Tel: (520) 323-7990
13   ************************
14   */
15
16#include <osgDB/FileUtils>
17
18#include <stdlib.h>
19#include <stdio.h>
20#include <string.h>
21
22/* trpage_rarchive.cpp
23   This source file implements the methods for a trpgr_Archive.
24   The Read Archive is used to read a paging archive from disk.
25*/
26
27#include <trpage_read.h>
28#include <trpage_compat.h>
29
30// Constructor
31trpgr_Archive::trpgr_Archive()
32{
33    fp = NULL;
34    ness = LittleEndian;
35    strcpy(dir,".");
36    tileCache = NULL;
37}
38
39// Destructor
40trpgr_Archive::~trpgr_Archive()
41{
42    if (fp)
43        fclose(fp);
44    fp = NULL;
45    if (tileCache)
46        delete tileCache;
47}
48
49int32 trpgr_Archive::GetHeaderData(char *dataPtr, int length, FILE *filehandle)
50{
51    return fread(dataPtr,1,length,filehandle);
52}
53
54// Set the directory where the archive is
55void trpgr_Archive::SetDirectory(const char *in_dir)
56{
57    strncpy(dir,in_dir,1024);
58}
59
60// Open File
61// Open the given file and look for the file specific info
62bool trpgr_Archive::OpenFile(const char *name)
63{
64    char file[1024];
65    sprintf(file,"%s" PATHSEPERATOR "%s",dir,name);
66
67    CloseFile();
68
69    if (!(fp = osgDB::fopen(file,"rb")))
70        return false;
71
72    // Look for a magic # and endianness
73    int32 magic;
74    if (fread(&magic,sizeof(int32),1,fp) != 1)
75        return false;
76
77    headerRead = false;
78
79    // Figure out the endianness from the magic number
80    trpgEndian cpuNess = trpg_cpu_byte_order();
81    if (magic == GetMagicNumber()) {
82        ness = cpuNess;
83        return true;
84    }
85    if (trpg_byteswap_int(magic) == GetMagicNumber()) {
86        if (cpuNess == LittleEndian)
87            ness = BigEndian;
88        else
89            ness = LittleEndian;
90        return true;
91    }
92    if (magic != GetMagicNumber())
93        return false;
94
95    // Not one of our files
96    return false;
97}
98
99// Get new reading app file cache
100trpgrAppFileCache* trpgr_Archive::GetNewRAppFileCache(const char *fullBase, const char *ext)
101{
102    return new trpgrAppFileCache(fullBase,ext);
103}
104
105trpgrImageHelper* trpgr_Archive::GetNewRImageHelper(trpgEndian ness,char *dir,const trpgMatTable &matTable,const trpgTexTable &texTable)
106{
107    bool separateGeo = false;
108    int majorVer,minorVer;
109    GetHeader()->GetVersion(majorVer,minorVer);
110    if((majorVer >= TRPG_NOMERGE_VERSION_MAJOR) && (minorVer>=TRPG_NOMERGE_VERSION_MINOR)) {
111        separateGeo = true;
112    }
113    return new trpgrImageHelper(ness,dir,matTable,texTable,separateGeo);
114}
115
116// Close File
117// Close the currently open file
118void trpgr_Archive::CloseFile()
119{
120    if (fp)
121        fclose(fp);
122    fp = NULL;
123    if (tileCache)
124        delete tileCache;
125    tileCache = NULL;
126}
127
128/**
129 * Read a sub block from a 2.2 TXP database. This can be called any time after ReadHeader is called
130 * if ReadHeader is called with the false parameter to specify not to read all the sub-archives.
131 * This can make a huge improvement in startup time for loading a very large archive with many blocks.
132 **/
133bool trpgr_Archive::ReadSubArchive(int row, int col, trpgEndian cpuNess)
134{
135    int ret;
136    trpgHeader blockHeader;
137    trpgr_Parser bparser;
138
139    char blockpath[1024];
140    //open the block archive
141    // the block archive will be in the base dir + \\cols\\row\\archive.txp
142    sprintf(blockpath,"%s%s%d%s%d%sarchive.txp",dir,PATHSEPERATOR,col,PATHSEPERATOR,row,PATHSEPERATOR);
143    FILE *bfp = osgDB::fopen(blockpath,"rb");
144    if(!bfp) {
145        return false;
146    }
147    // Look for a magic # and endianness
148    int32 bmagic;
149    if (fread(&bmagic,sizeof(int32),1,bfp) != 1)
150        return false;
151    // The block archive will always be the same endianness as the master
152    if ( (bmagic != GetMagicNumber()) && (trpg_byteswap_int(bmagic) != GetMagicNumber()) )
153        return false;
154
155    int32 bheaderSize=0;
156    if (fread(&bheaderSize,sizeof(int32),1,bfp) != 1)
157        return false;
158    if (ness != cpuNess)
159        bheaderSize = trpg_byteswap_int(bheaderSize);
160    int bheadLen = bheaderSize;
161    if (bheadLen < 0)
162        return false;
163
164    // Read in the header whole
165    trpgMemReadBuffer bbuf(ness);
166    bbuf.SetLength(bheadLen);
167    char *bdata = bbuf.GetDataPtr();
168    if ((ret = GetHeaderData(bdata,bheadLen,bfp)) != bheadLen)
169        return false;
170    //keep track of where this came from in the master table.
171    tileTable.SetCurrentBlock(row,col,true);
172    texTable.SetCurrentBlock(row,col);
173
174    bparser.AddCallback(TRPGHEADER,&blockHeader);
175    bparser.AddCallback(TRPGMATTABLE,&materialTable);    // Went back to oldest style for 2.0
176    //if(!headerHasTexTable) {
177    bparser.AddCallback(TRPGTEXTABLE2,&texTable);            // Added for 2.0
178    //}
179    bparser.AddCallback(TRPGMODELTABLE,&modelTable);
180    bparser.AddCallback(TRPGLIGHTTABLE,&lightTable);                // Added for 2.0
181    bparser.AddCallback(TRPGRANGETABLE,&rangeTable);                // Added for 2.0
182    bparser.AddCallback(TRPG_TEXT_STYLE_TABLE,&textStyleTable);                // Added for 2.1
183    bparser.AddCallback(TRPG_SUPPORT_STYLE_TABLE,&supportStyleTable);
184    bparser.AddCallback(TRPG_LABEL_PROPERTY_TABLE,&labelPropertyTable);
185    // Don't read the tile table for v1.0 archives
186    // It's only really used for 2.0 archives
187    bparser.AddCallback(TRPGTILETABLE2,&tileTable);
188
189    // Parse the buffer
190    if (!bparser.Parse(bbuf))
191        return false;
192    //close the block archive
193    fclose(bfp);
194
195    tileTable.SetCurrentBlock(-1,-1,false);
196
197    return true;
198}
199
200bool trpgr_Archive::ReadHeader()
201{
202    return ReadHeader(true);
203}
204
205// Read Header
206// Run through the rest of the header information
207bool trpgr_Archive::ReadHeader(bool readAllBlocks)
208{
209    int ret;
210
211    if (!fp || headerRead)
212        return false;
213
214    headerRead = true;
215
216    // Next int64 should be the header size
217    trpgEndian cpuNess = trpg_cpu_byte_order();
218    int32 headerSize;
219    if (fread(&headerSize,sizeof(int32),1,fp) != 1)
220        return false;
221    if (ness != cpuNess)
222        headerSize = trpg_byteswap_int(headerSize);
223    int headLen = headerSize;
224    if (headLen < 0)
225        return false;
226
227    // Read in the header whole
228    trpgMemReadBuffer buf(ness);
229    buf.SetLength(headLen);
230    char *data = buf.GetDataPtr();
231    if ((ret = GetHeaderData(data,headLen,fp)) != headLen)
232        return false;
233
234    // Set up a parser
235    // Catch the tables we need for the archive
236    trpgMatTable1_0 oldMatTable;
237    trpgTexTable1_0 oldTexTable;
238    trpgr_Parser parser;
239    parser.AddCallback(TRPGHEADER,&header);
240    parser.AddCallback(TRPGMATTABLE,&materialTable);    // Went back to oldest style for 2.0
241    parser.AddCallback(TRPGMATTABLE2,&oldMatTable);     // Added 11-14-98 (1.0 material table)
242    parser.AddCallback(TRPGTEXTABLE,&oldTexTable);
243    parser.AddCallback(TRPGTEXTABLE2,&texTable);            // Added for 2.0
244    parser.AddCallback(TRPGMODELTABLE,&modelTable);
245    parser.AddCallback(TRPGLIGHTTABLE,&lightTable);                // Added for 2.0
246    parser.AddCallback(TRPGRANGETABLE,&rangeTable);                // Added for 2.0
247    parser.AddCallback(TRPG_TEXT_STYLE_TABLE,&textStyleTable);                // Added for 2.1
248    parser.AddCallback(TRPG_SUPPORT_STYLE_TABLE,&supportStyleTable);
249    parser.AddCallback(TRPG_LABEL_PROPERTY_TABLE,&labelPropertyTable);
250    // Don't read the tile table for v1.0 archives
251    // It's only really used for 2.0 archives
252    parser.AddCallback(TRPGTILETABLE2,&tileTable);
253
254    // Parse the buffer
255    if (!parser.Parse(buf))
256        return false;
257
258    if(header.GetIsMaster())
259    {
260        // bool firstBlock = true;
261        //if the master has textures, we want to use them instead of the tables in the
262        //block archives
263
264        // int numTiles = 0;
265        //tileTable.
266        int totalrows,totalcols;
267        trpg2dPoint mhdr_swExtents;
268        trpg2dPoint mhdr_neExtents;
269        trpg3dPoint mhdr_Origin;
270        // integrate header information from the block header.
271        header.GetExtents(mhdr_swExtents,mhdr_neExtents);
272        header.GetOrigin(mhdr_Origin);
273        header.GetBlocks(totalrows,totalcols);
274        if(readAllBlocks) {
275            for(int row=0;row<totalrows;row++) {
276                for(int col=0;col<totalcols;col++) {
277                    // Read each block -- Warning, this can take a while!!!
278                    ReadSubArchive( row, col, cpuNess);
279                }
280            }
281        }
282        else {
283            ReadSubArchive( 0, 0, cpuNess);//Get the first archive!
284        }
285
286    }
287    tileTable.SetCurrentBlock(-1,-1,false);
288
289    // 1.0 Compatibility
290    // If we see an older style material table, convert it to the new style
291    // This isn't terribly memory efficient, but it does work
292    if (oldMatTable.isValid())
293        materialTable = oldMatTable;
294    if (oldTexTable.isValid())
295        texTable = oldTexTable;
296
297    // Set up a tile cache, if needed
298    trpgTileTable::TileMode tileMode;
299    tileTable.GetMode(tileMode);
300    if (tileMode == trpgTileTable::Local) {
301        if (tileCache)  delete tileCache;
302        char fullBase[1024];
303        sprintf(fullBase,"%s" PATHSEPERATOR "tileFile",dir);
304        tileCache = GetNewRAppFileCache(fullBase,"tpf");
305    }
306
307    valid = true;
308
309    return true;
310}
311
312// Read Tile
313// Read a tile into a read buffer
314// For version 2.1 only  tile with lod=0 are stored in the tile table, so an
315// error will be returned if you try to use the table with a differrent lod.
316bool trpgr_Archive::ReadTile(uint32 x,uint32 y,uint32 lod,trpgMemReadBuffer &buf)
317{
318    if (!isValid())
319        return false;
320
321    // Reality check the address
322    int32 numLods;
323    header.GetNumLods(numLods);
324    if (static_cast<int>(lod) >= numLods)
325        return false;
326    trpg2iPoint lodSize;
327    header.GetLodSize(lod,lodSize);
328    if (static_cast<int>(x) >= lodSize.x || static_cast<int>(y) >= lodSize.y)
329        return false;
330
331    trpgTileTable::TileMode tileMode;
332    tileTable.GetMode(tileMode);
333
334    bool status = true;
335    if (tileMode == trpgTileTable::External || tileMode == trpgTileTable::ExternalSaved) {
336        status = ReadExternalTile(x, y, lod, buf);
337
338    } else {
339        // Local tile.  Figure out where it is (which file)
340        int majorVersion, minorVersion;
341        header.GetVersion(majorVersion, minorVersion);
342        if(majorVersion == 2 && minorVersion >=1)
343        {
344            // Version 2.1
345            // Tile table contains only lod 0 tiles
346            if(lod != 0)
347                status = false;
348        }
349
350        if(status)
351        {
352            trpgwAppAddress addr;
353            float zmin,zmax;
354            status = tileTable.GetTile(x,y,lod,addr,zmin,zmax);
355
356            if(status)
357                status = ReadTile(addr, buf);
358        }
359    }
360
361    return status;
362}
363
364bool trpgr_Archive::ReadExternalTile(uint32 x,uint32 y,uint32 lod,trpgMemReadBuffer &buf)
365{
366    // Figure out the file name
367    char filename[1024];
368    int majorVer,minorVer;
369    header.GetVersion(majorVer,minorVer);
370    if((majorVer >= TRPG_NOMERGE_VERSION_MAJOR) && (minorVer >= TRPG_NOMERGE_VERSION_MINOR)) {
371        int blockx,blocky;
372        unsigned int denom = (1 << lod); // this should work up to lod 31
373        blockx = x/denom;
374        blocky = y/denom;
375        sprintf(filename,"%s" PATHSEPERATOR "%d" PATHSEPERATOR "%d" PATHSEPERATOR "tile_%d_%d_%d.tpt",
376                dir,blockx,blocky,x,y,lod);
377    }
378    else {
379        sprintf(filename,"%s" PATHSEPERATOR "tile_%d_%d_%d.tpt",dir,x,y,lod);
380    }
381    // Open the file and read the contents
382    FILE *fp= 0;
383    try {
384        if (!(fp = osgDB::fopen(filename,"rb")))  {
385
386            throw 1;
387        }
388        // Find the file end
389        if (fseek(fp,0,SEEK_END))
390            throw 1;
391        // Note: This means tile is capped at 2 gigs
392        long pos = ftell(fp);
393        if (fseek(fp,0,SEEK_SET))
394            throw 1;
395        // Now we know the size.  Read the whole file
396        buf.SetLength(pos);
397        char *data = buf.GetDataPtr();
398        if (fread(data,pos,1,fp) != 1)
399            throw 1;
400        fclose(fp);
401        fp = NULL;
402    }
403    catch (...) {
404        if (fp)
405            fclose(fp);
406        return false;
407    }
408
409    return true;
410}
411bool trpgr_Archive::ReadTile(const trpgwAppAddress& addr, trpgMemReadBuffer &buf)
412{
413    // Fetch the appendable file from the cache
414    trpgrAppFile *tf = tileCache->GetFile(ness,addr.file,addr.col,addr.row);
415    if (!tf)
416        return false;
417
418    // Fetch the tile
419    if (!tf->Read(&buf,addr.offset))
420        return false;
421    else
422        return true;
423}
424
425// Get methods
426const trpgHeader *trpgr_Archive::GetHeader() const
427{
428    return &header;
429}
430const trpgMatTable *trpgr_Archive::GetMaterialTable() const
431{
432    return &materialTable;
433}
434trpgTexTable *trpgr_Archive::GetTexTable()
435{
436    return &texTable;
437}
438const trpgModelTable *trpgr_Archive::GetModelTable() const
439{
440    return &modelTable;
441}
442const trpgTileTable *trpgr_Archive::GetTileTable() const
443{
444    return &tileTable;
445}
446const trpgLightTable *trpgr_Archive::GetLightTable() const
447{
448    return &lightTable;
449}
450const trpgRangeTable *trpgr_Archive::GetRangeTable() const
451{
452    return &rangeTable;
453}
454const trpgTextStyleTable *trpgr_Archive::GetTextStyleTable() const
455{
456    return &textStyleTable;
457}
458const trpgSupportStyleTable *trpgr_Archive::GetSupportStyleTable() const
459{
460    return &supportStyleTable;
461}
462const trpgLabelPropertyTable *trpgr_Archive::GetLabelPropertyTable() const
463{
464    return &labelPropertyTable;
465}
466trpgEndian trpgr_Archive::GetEndian() const
467{
468    return ness;
469}
470
471// Utility MBR routine
472bool trpgr_Archive::trpgGetTileMBR(uint32 x,uint32 y,uint32 lod,trpg3dPoint &ll,trpg3dPoint &ur) const
473{
474    if (!header.isValid())
475        return false;
476    int32 numLod;
477    header.GetNumLods(numLod);
478    trpg2iPoint maxXY;
479    header.GetLodSize(lod,maxXY);
480    if (static_cast<int>(x) >= maxXY.x || static_cast<int>(y)>= maxXY.y)
481        return false;
482
483    trpg3dPoint origin;
484    header.GetOrigin(origin);
485    trpg2dPoint size;
486    header.GetTileSize(lod,size);
487
488    ll.x = origin.x + size.x*x;
489    ll.y = origin.y + size.y*y;
490    ur.x = origin.x + size.x*(x+1);
491    ur.y = origin.y + size.y*(y+1);
492
493    // If the tiles are local, we should have Z information
494    trpgwAppAddress addr;
495    float elev_min=0.0,elev_max=0.0;
496    tileTable.GetTile(x,y,lod,addr,elev_min,elev_max);
497    ll.z = elev_min;  ur.z = elev_max;
498
499    return true;
500}
501
502/* *****************
503   Read Image Helper
504   *****************
505   */
506
507trpgrImageHelper::trpgrImageHelper(trpgEndian inNess,char *inDir,
508                                   const trpgMatTable &inMatTable,const trpgTexTable &inTexTable,bool separateGeoTyp)
509{
510    Init(inNess,inDir,inMatTable,inTexTable,separateGeoTyp);
511}
512
513void trpgrImageHelper::Init(trpgEndian inNess,char *inDir,
514                            const trpgMatTable &inMatTable,const trpgTexTable &inTexTable,bool separateGeoTyp)
515{
516    ness = inNess;
517    strcpy(dir,inDir);
518    this->separateGeoTyp = separateGeoTyp;
519    matTable = &inMatTable;
520    texTable = &inTexTable;
521
522    // Set up the texture cache
523    // It doesn't do anything until it's called anyway
524    char fullBase[1024];
525    sprintf(fullBase,"%s" PATHSEPERATOR "texFile",dir);
526    texCache = GetNewRAppFileCache(fullBase,"txf");
527    if(separateGeoTyp) {
528        sprintf(fullBase,"%s" PATHSEPERATOR "geotypFile",dir);
529        geotypCache = GetNewRAppFileCache(fullBase,"txf");
530    }
531    else {
532        geotypCache = texCache;
533    }
534
535}
536
537trpgrImageHelper::~trpgrImageHelper()
538{
539    if (texCache) {
540        delete texCache;
541        texCache = NULL;
542    }
543    if(separateGeoTyp && geotypCache) {
544        delete geotypCache;
545        geotypCache = NULL;
546    }
547}
548
549trpgrAppFileCache* trpgrImageHelper::GetNewRAppFileCache(const char *fullBase,const char* /*ext*/)
550{
551    return new trpgrAppFileCache(fullBase,"txf");
552}
553
554bool trpgrImageHelper::GetLocalGL(const trpgTexture *tex,char *data,int32 size)
555{
556    // Make sure the texture is Local
557    trpgTexture::ImageMode mode;
558    tex->GetImageMode(mode);
559    if (mode != trpgTexture::Local)
560        return false;
561
562    // Fetch data data
563    trpgwAppAddress addr;
564    tex->GetImageAddr(addr);
565    trpgrAppFile *af = geotypCache->GetFile(ness,addr.file,addr.col,addr.row);
566    if (!af)
567        return false;
568    if (!af->Read(data,addr.offset,0,size))
569        return false;
570
571    return true;
572}
573
574bool trpgrImageHelper::GetMipLevelLocalGL(int miplevel, const trpgTexture *tex,char *data,int32 dataSize)
575{
576    if ( miplevel >= tex->CalcNumMipmaps() || miplevel < 0 )
577        return false;
578
579    // Make sure the texture is Local
580    trpgTexture::ImageMode mode;
581    tex->GetImageMode(mode);
582    if (mode != trpgTexture::Local)
583        return false;
584
585    // Fetch data data
586    trpgwAppAddress addr;
587    tex->GetImageAddr(addr);
588    trpgrAppFile *af = texCache->GetFile(ness,addr.file,addr.col,addr.row);
589    if (!af)
590        return false;
591
592    int level_offset = (const_cast<trpgTexture*>(tex))->MipLevelOffset(miplevel);
593    if (!af->Read(data,addr.offset,level_offset,dataSize))
594        return false;
595
596    return true;
597}
598
599
600bool trpgrImageHelper::GetImageInfoForLocalMat(const trpgLocalMaterial *locMat,
601                                               const trpgMaterial **retMat,const trpgTexture **retTex,int &totSize)
602{
603    return GetNthImageInfoForLocalMat(locMat, 0, retMat, retTex, totSize);
604}
605
606bool trpgrImageHelper::GetNthImageInfoForLocalMat(const trpgLocalMaterial *locMat, int index,
607                                                  const trpgMaterial **retMat,const trpgTexture **retTex,int &totSize)
608{
609    // Get the base material for the Local Material
610    int32 matSubTable,matID;
611    locMat->GetBaseMaterial(matSubTable,matID);
612    // For right now, force the subtable number to match the index.
613    // Eventually, either store multiple base materials for each local material,
614    // or overhaul this in some other fashion.
615    int numTables;
616    if (!matTable->GetNumTable(numTables))
617        return false;
618    if (index>=numTables)
619        return false;
620    if (index>0) matSubTable=index; // otherwise, leave it alone - could be nonzero
621    const trpgMaterial *mat = matTable->GetMaterialRef(matSubTable,matID);
622    if (!mat)
623        return false;
624
625    // Now get the texture (always the first one)
626    trpgTextureEnv texEnv;
627    int32 texID;
628    if (!mat->GetTexture(0,texID,texEnv))
629        return false;
630    const trpgTexture *tex = texTable->GetTextureRef(texID);
631    if (!tex)
632        return false;
633
634    totSize = tex->CalcTotalSize();
635
636    *retTex = tex;
637    *retMat = mat;
638    return true;
639}
640
641bool trpgrImageHelper::GetImageForLocalMat(const trpgLocalMaterial *locMat,char *data,int dataSize)
642{
643    return GetNthImageForLocalMat(locMat, 0, data, dataSize);
644}
645
646bool trpgrImageHelper::GetNthImageForLocalMat(const trpgLocalMaterial *locMat,int index, char *data,int dataSize)
647{
648    if (!locMat->isValid())
649        return false;
650
651    const trpgMaterial *mat;
652    const trpgTexture *tex;
653    int totSize;
654    if (!GetNthImageInfoForLocalMat(locMat,index,&mat,&tex,totSize))
655        return false;
656
657    // Determine the type
658    trpgTexture::ImageMode imageMode;
659    tex->GetImageMode(imageMode);
660    switch (imageMode) {
661    case trpgTexture::Template:
662    {
663        // Read the image data out of the Local image (in an archive somewhere)
664        trpgwAppAddress addr;
665        if (!locMat->GetNthAddr(index,addr)) return false;
666        trpgrAppFile *af = texCache->GetFile(ness,addr.file,addr.col,addr.row);
667        if (!af)
668            return false;
669        if (!af->Read(data,addr.offset,0,dataSize))
670            return false;
671    }
672    break;
673    case trpgTexture::Global:
674        // Note: Not dealing with Global textures yet
675        return false;
676        break;
677    default:
678        // This is not a valid Local Material
679        return false;
680    };
681
682    return true;
683}
684
685bool trpgrImageHelper::GetMipLevelForLocalMat(int miplevel, const trpgLocalMaterial *locMat,char *data,int dataSize)
686{
687    return GetNthImageMipLevelForLocalMat(miplevel, locMat, 0, data, dataSize);
688}
689
690bool trpgrImageHelper::GetNthImageMipLevelForLocalMat(int miplevel, const trpgLocalMaterial *locMat, int index, char *data,int dataSize)
691{
692    if (index>0) return false; // not yet, folks, if ever.  index>1 means sensors for now.
693    if (!locMat->isValid()) return false;
694
695    const trpgMaterial *mat;
696    const trpgTexture *tex;
697    int totSize;
698    if (!GetNthImageInfoForLocalMat(locMat,index,&mat,&tex,totSize))
699        return false;
700
701    if ( miplevel >= tex->CalcNumMipmaps() || miplevel < 0 )
702        return false;
703
704    // Determine the type
705    trpgTexture::ImageMode imageMode;
706    tex->GetImageMode(imageMode);
707    switch (imageMode) {
708    case trpgTexture::Template:
709    {
710        // Read the image data out of the Local image (in an archive somewhere)
711        trpgwAppAddress addr;
712        if (!locMat->GetNthAddr(index,addr)) return false;
713        trpgrAppFile *af = texCache->GetFile(ness,addr.file,addr.col,addr.row);
714        if (!af)  return false;
715
716        int level_offset = (const_cast<trpgTexture*>(tex))->MipLevelOffset(miplevel);
717        if (!af->Read(data,addr.offset,level_offset,dataSize))
718            return false;
719    }
720    break;
721    case trpgTexture::Global:
722        // Note: Not dealing with Global textures yet
723        return false;
724        break;
725    default:
726        // This is not a valid Local Material
727        return false;
728    };
729
730    return true;
731}
732
733bool trpgrImageHelper::GetImagePath(const trpgTexture *tex,char *fullPath,int pathLen)
734{
735    char name[1024];
736    int nameLen=1024;
737    tex->GetName(name,nameLen);
738    nameLen = strlen(name);
739
740    if (static_cast<int>(strlen(dir)) + nameLen + 2 > pathLen)
741        return false;
742
743    sprintf(fullPath,"%s" PATHSEPERATOR "%s",dir,name);
744
745    return true;
746}
Note: See TracBrowser for help on using the browser.