Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

OSGTextureManager.cpp

Go to the documentation of this file.
00001 #include <OSGConfig.h>
00002 
00003 #include "OSGTextureManager.h"
00004 
00005 #include <OSGTextureChunk.h>
00006 #include <OSGDrawActionBase.h>
00007 #include <OSGMatrix.h>
00008 #include <OSGVector.h>
00009 #include <OSGQuaternion.h>
00010 #include <OSGLog.h>
00011 
00012 #include "OSGDVRVolumeTexture.h"
00013 #include "OSGDVRVolume.h"
00014 #include "OSGSlicer.h"
00015 #include "OSGBrick.h"
00016 
00017 
00018 #define FACE_FRONT  (1)
00019 #define FACE_BACK   (2)
00020 #define FACE_RIGHT  (4)
00021 #define FACE_LEFT   (8)
00022 #define FACE_BOTTOM (16)
00023 #define FACE_TOP    (32) 
00024 
00025 
00026 OSG_BEGIN_NAMESPACE
00027 
00029 
00030 TextureRecord::TextureRecord(ImagePtr img, 
00031                              UInt32   internal, 
00032                              UInt32   externalFormat,
00033                              Int32    stage0, 
00034                              Int32    stage1) :
00035     _internalFormat(internal      ),
00036     _externalFormat(externalFormat),
00037     _textureStage0 (stage0        ),
00038     _textureStage1 (stage1        )
00039 {
00040     _image = img;
00041     addRefCP(_image);
00042 }
00043 
00044 TextureRecord::~TextureRecord()
00045 {
00046     subRefCP(_image);
00047     _image = NullFC;
00048 }
00049 
00050 
00052 
00053 
00054 TextureManager::TextureManager(DVRVolume *volume) :
00055     _registeredTextures(    ),
00056     _parent            (NULL),
00057     _brickSets         (NULL)
00058 {
00059     _parent   = volume;
00060     _brickSets = new BrickSet[3];
00061 }
00062 
00063 TextureManager::~TextureManager()
00064 {
00065     clearTextures();
00066 
00067     delete [] _brickSets;
00068 }
00069 
00071 Int32 TextureManager::registerTexture(ImagePtr image,
00072                                       UInt32   internalFormat,
00073                                       UInt32   externalFormat,
00074                                       bool     /*doBricking*/,
00075                                       Int32    textureStage0,
00076                                       Int32    textureStage1)
00077 { 
00078     FDEBUG(("TextureManager::registerTexture stage0: %d - stage1: %d\n",
00079             textureStage0, textureStage1));
00080     
00085     
00086     // check for unique texture stages
00087     bool unique = true;
00088 
00089     for(UInt32 i = 0; i < _registeredTextures.size(); i++)
00090     {
00091         if(textureStage0 == _registeredTextures[i]->_textureStage0 ||
00092            textureStage0 == _registeredTextures[i]->_textureStage1  )
00093         {
00094             unique = false;
00095         }
00096 
00097         if((textureStage1 != -1                                    ) &&
00098            (textureStage1 == _registeredTextures[i]->_textureStage0 ||
00099             textureStage1 == _registeredTextures[i]->_textureStage1  )  )
00100         {
00101             unique = false;
00102         }
00103     }
00104 
00105     if(unique == false)
00106     {
00107         SWARNING << "TextureManager::registerTexture - "
00108                  << "ID already in use -> ignoring texture" 
00109                  << std::endl;
00110         return -1;
00111     }
00112 
00113     // store record
00114     TextureRecord * record = new TextureRecord(image,
00115                                                internalFormat,
00116                                                externalFormat,
00117                                                textureStage0,
00118                                                textureStage1);
00119     _registeredTextures.push_back(record);
00120     
00121     return _registeredTextures.size() - 1; 
00122 }
00123 
00124 
00126 void TextureManager::unregisterTexture(Int32 id)
00127 {
00128     FDEBUG(("TextureManager::unregisterTexture\n"));
00129 
00130     if((id < 0) || (UInt32(id) > _registeredTextures.size()))
00131     {
00132         SWARNING << "TextureManager::unregisterTexture - invalid id " 
00133                  << id 
00134                  << std::endl;
00135         return;
00136     }
00137 
00138     TextureSet::iterator iter = _registeredTextures.begin();
00139 
00140     delete _registeredTextures[id];
00141 
00142     _registeredTextures.erase(iter + id);
00143 }
00144 
00145 
00147 void TextureManager::reloadTexture(Int32 id, DrawActionBase *action)
00148 {
00149     if((id < 0) || (UInt32(id) > _registeredTextures.size()))
00150     {
00151         SWARNING << "TextureManager::reloadTexture - invalid id " 
00152                  << id 
00153                  << std::endl;
00154         return;
00155     }
00156     
00157     for(UInt32 k = 0; k < 3; k++)
00158     {
00159         _brickSets[k].reloadBrickTextures(
00160             action, 
00161             _registeredTextures[id]->_textureStage0);
00162 
00163         _brickSets[k].reloadBrickTextures(
00164             action, 
00165             _registeredTextures[id]->_textureStage1);
00166     }
00167 }
00168 
00169 
00171 void TextureManager::clearTextures(ChunkMaterialPtr material)
00172 {
00173     FDEBUG(("TextureManager::clearTexture\n"));
00174 
00176 
00177     if (material != NullFC) 
00178     {
00179         for(UInt32 k = 0; k < 3; k++) 
00180         {
00181             _brickSets[k].clearBrickTextures(material);
00182 
00183             delete [] _brickSets[k].m_pBricks;
00184             
00185             _brickSets[k].m_pBricks    = 0;
00186             _brickSets[k].m_nNumBricks = 0;
00187         }
00188     }
00189     
00190     for(UInt32 i = 0; i < _registeredTextures.size(); i++)
00191     {
00192         delete _registeredTextures[i];
00193     } 
00194 
00195     _registeredTextures.clear();
00196 }
00197       
00198 
00200 void TextureManager::buildTextures(ChunkMaterialPtr  material,
00201                                    DVRVolume        *volume,
00202                                    TextureMode       textureMode)
00203 {
00204     FDEBUG(("TextureManager::buildTextures\n"));
00205 
00206     DVRVolumeTexturePtr vT = DVRVOLUME_PARAMETER(volume, DVRVolumeTexture);
00207 
00208     if(vT == NullFC) 
00209     {
00210         SWARNING << "TextureManager::buildTextures - No Volume" << std::endl;
00211         return;
00212     }
00213 
00214     if(_registeredTextures.size() < 1) 
00215     {
00216         SWARNING << "TextureManager::buildTextures - No registerd textures" 
00217                  << std::endl;
00218         return;
00219     }
00220     
00221     switch(textureMode)
00222     {
00223         case TM_2D_Multi:
00224         {
00225             // Multi-Texture Slabs
00226             Vec3f res = vT->getResolution();
00227 
00228             Vec3f brickSizeX(2,      res[1], res[2]);
00229             Vec3f brickSizeY(res[0], 2,      res[2]);
00230             Vec3f brickSizeZ(res[0], res[1], 2     );
00231             
00232             _brickSets[BrickSet::XY].buildBricks3D(volume, 
00233                                                    brickSizeZ, 
00234                                                    1, 
00235                                                    BrickSet::XY);
00236             _brickSets[BrickSet::XZ].buildBricks3D(volume, 
00237                                                    brickSizeY, 
00238                                                    1, 
00239                                                    BrickSet::XZ);
00240             _brickSets[BrickSet::YZ].buildBricks3D(volume, 
00241                                                    brickSizeX, 
00242                                                    1, 
00243                                                    BrickSet::YZ);
00244             
00245             _brickSets[BrickSet::XY].buildBrickTextures( material, 
00246                                                         _registeredTextures, 
00247                                                          textureMode); 
00248             _brickSets[BrickSet::XZ].buildBrickTextures( material, 
00249                                                         _registeredTextures, 
00250                                                          textureMode); 
00251             _brickSets[BrickSet::YZ].buildBrickTextures( material, 
00252                                                         _registeredTextures, 
00253                                                          textureMode); 
00254             
00255             break;
00256         }
00257         case TM_2D:
00258         {
00259             // Ordinary 2D-Slices
00260             _brickSets[BrickSet::XY].buildBricks2D(volume, BrickSet::XY);
00261             _brickSets[BrickSet::XZ].buildBricks2D(volume, BrickSet::XZ);
00262             _brickSets[BrickSet::YZ].buildBricks2D(volume, BrickSet::YZ);
00263             
00264             _brickSets[BrickSet::XY].buildBrickTextures( material, 
00265                                                         _registeredTextures, 
00266                                                          textureMode); 
00267             _brickSets[BrickSet::XZ].buildBrickTextures( material, 
00268                                                         _registeredTextures, 
00269                                                          textureMode); 
00270             _brickSets[BrickSet::YZ].buildBrickTextures( material, 
00271                                                         _registeredTextures, 
00272                                                          textureMode); 
00273             
00274             break;
00275         }
00276 
00277         default:
00278         case TM_3D:
00279         {
00280             // Ordinary 3D-Bricks
00281             Vec3f res              = vT->getResolution();
00282             Vec3f brickSubdivision = 
00283                 calcBrickSubdivision(int(res[0]), 
00284                                      int(res[1]), 
00285                                      int(res[2]),
00286                                      vT->getImage()->getBpp(), volume);
00287 
00288             Vec3f brickSize(Real32((int)(res[0] / brickSubdivision[0])),
00289                             Real32((int)(res[1] / brickSubdivision[1])),
00290                             Real32((int)(res[2] / brickSubdivision[2])));
00291             
00292 
00293             FDEBUG(
00294                 ("TextureManager::buildTextures - BrickSubdivision %d %d %d\n",
00295                  brickSubdivision[0], 
00296                  brickSubdivision[1], 
00297                  brickSubdivision[2]));
00298             
00299             _brickSets[BrickSet::XY].buildBricks3D(volume, 
00300                                                    brickSize, 
00301                                                    volume->getBrickOverlap());
00302             
00303             _brickSets[BrickSet::XY].buildBrickTextures( material, 
00304                                                         _registeredTextures, 
00305                                                          textureMode);
00306             
00307             break;
00308         }
00309     }
00310 }
00311 
00312 
00314 void TextureManager::dump(      UInt32     /*uiIndent*/, 
00315                           const BitVector  /*bvFlags*/) const
00316 {
00317     SLOG << "TextureManager:" << std::endl;
00318 
00319     for (UInt32 i = 0; i < _registeredTextures.size(); i++)
00320     {
00321         SLOG << "image:          " << _registeredTextures[i]->_image 
00322              << std::endl;
00323         SLOG << "internalFormat: " << _registeredTextures[i]->_internalFormat 
00324              << std::endl;
00325         SLOG << "textureStage0:  " << _registeredTextures[i]->_textureStage0 
00326              << std::endl;
00327         SLOG << "textureStage1:  " << _registeredTextures[i]->_textureStage1 
00328              << std::endl;
00329     } 
00330 }
00331 
00332 
00333 Vec3f TextureManager::calcBrickSubdivision(Int32      resX, 
00334                                            Int32      resY, 
00335                                            Int32      resZ, 
00336                                            Int32      dataSize, 
00337                                            DVRVolume *volume)
00338 {
00339     Int32 mode = volume->getBrickingMode();
00340 
00341     
00342     Vec3f subdivision(1,1,1);
00343     
00344     switch (mode) 
00345     {
00346         case BRICK_SUBDIVIDE_STATIC:
00347         {
00348             subdivision = volume->getBrickStaticSubdivision();
00349             break;
00350         }
00351         
00352         case BRICK_SUBDIVIDE_ON_TEXTURE_MEMORY:
00353         {
00354             Real32 fMB_available = 
00355                 1024.0F * 1024.0F * (Real32) volume->getBrickStaticMemoryMB();
00356 
00357             Real32 fMB_required  = (Real32) (resX * resY * resZ * dataSize);
00358 
00359             Int32 nNumBricks     = (Int32) osgceil(fMB_required / 
00360                                                    fMB_available);
00361             Int32 nRealNumBricks = 1;
00362 
00363             while(nNumBricks > nRealNumBricks) 
00364             {
00365                 if ((resX >= resY) && (resX >= resZ)) 
00366                 {
00367                     resX /= 2;
00368                     subdivision[0] *= 2;
00369                 } 
00370                 else if (resY >= resZ) 
00371                 {
00372                     resY /= 2;
00373                     subdivision[1] *= 2;
00374                     
00375                 }
00376                 else 
00377                 {
00378                     resZ /= 2;
00379                     subdivision[2] *= 2;
00380                 }
00381                 
00382                 nRealNumBricks = 
00383                     (Int32)(subdivision[0] * subdivision[1] * subdivision[2]);
00384             }
00385             break;
00386         }
00387         
00388         case BRICK_SUBDIVIDE_ON_BRICK_SIZE:
00389         {
00390             Vec3f maxSize = volume->getBrickMaxSize();
00391             
00392             while(resX > (Int32) maxSize[0]) 
00393             {
00394                 resX /= 2;
00395                 subdivision[0] *= 2;
00396             }
00397             while(resY > (Int32) maxSize[1]) 
00398             {
00399                 resY /= 2;
00400                 subdivision[1] *= 2;
00401             }
00402             while(resZ > (Int32) maxSize[2]) 
00403             {
00404                 resZ /= 2;
00405                 subdivision[2] *= 2;
00406             }
00407             break;
00408         }
00409         
00410     }
00411     return subdivision;
00412 }
00413 
00414 
00415 Brick *TextureManager::sortBricks(DrawActionBase *da, 
00416                                   Matrix          modelMat, 
00417                                   Vec3f           eyePoint, 
00418                                   DVRVolume      * /*volume*/, 
00419                                   TextureMode     mode) 
00420 {
00421     
00422     FDEBUG(("TextureManager::sortBricks\n"));
00423 
00424     if ((mode == TM_2D) || (mode == TM_2D_Multi)) 
00425     {
00426         // select the right bickset
00427         BrickSet::Orientation ori = BrickSet::XY;
00428         bool                  btf = true;
00429 
00430         switch(Slicer::getSlicingDirection(da,NULL))
00431         {
00432             case Slicer::SD_X_FRONT_TO_BACK:
00433                 ori = BrickSet::YZ;
00434                 btf = false;
00435                 break;
00436             case Slicer::SD_X_BACK_TO_FRONT:
00437                 ori = BrickSet::YZ;
00438                 btf = true;
00439                 break;
00440             case Slicer::SD_Y_FRONT_TO_BACK:
00441                 ori = BrickSet::XZ;
00442                 btf = false;
00443                 break;
00444             case Slicer::SD_Y_BACK_TO_FRONT:
00445                 ori = BrickSet::XZ;
00446                 btf = true;
00447                 break;
00448             case Slicer::SD_Z_FRONT_TO_BACK:
00449                 ori = BrickSet::XY;
00450                 btf = false;
00451                 break;
00452             case Slicer::SD_Z_BACK_TO_FRONT:
00453                 ori = BrickSet::XY;
00454                 btf = true;
00455                 break;
00456             default:
00457                 break;
00458         }
00459         
00460     // btf or ftb? 
00461         return _brickSets[ori].sortBricks2D(btf);
00462     } 
00463     else 
00464     {
00465         return _brickSets[BrickSet::XY].sortBricks3D(modelMat, eyePoint);
00466     }
00467 }
00468 
00469 
00470 OSG_END_NAMESPACE
00471 
00472 

Generated on Thu Aug 25 04:11:34 2005 for OpenSG by  doxygen 1.4.3