Show
Ignore:
Timestamp:
06/08/11 19:45:24 (4 years ago)
Author:
robert
Message:

Cleaned up example to use the new ImageUtils? functions for creating a 3D image from a list of images.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/examples/osgvolume/osgvolume.cpp

    r12506 r12507  
    7979}; 
    8080 
    81 struct PassThroughTransformFunction 
    82 { 
    83     unsigned char operator() (unsigned char c) const { return c; } 
    84 }; 
    85  
    86  
    87 void clampToNearestValidPowerOfTwo(int& sizeX, int& sizeY, int& sizeZ, int s_maximumTextureSize, int t_maximumTextureSize, int r_maximumTextureSize) 
    88 { 
    89     // compute nearest powers of two for each axis. 
    90     int s_nearestPowerOfTwo = 1; 
    91     while(s_nearestPowerOfTwo<sizeX && s_nearestPowerOfTwo<s_maximumTextureSize) s_nearestPowerOfTwo*=2; 
    92  
    93     int t_nearestPowerOfTwo = 1; 
    94     while(t_nearestPowerOfTwo<sizeY && t_nearestPowerOfTwo<t_maximumTextureSize) t_nearestPowerOfTwo*=2; 
    95  
    96     int r_nearestPowerOfTwo = 1; 
    97     while(r_nearestPowerOfTwo<sizeZ && r_nearestPowerOfTwo<r_maximumTextureSize) r_nearestPowerOfTwo*=2; 
    98  
    99     sizeX = s_nearestPowerOfTwo; 
    100     sizeY = t_nearestPowerOfTwo; 
    101     sizeZ = r_nearestPowerOfTwo; 
     81 
     82osg::Image* createTexture3D(osg::ImageList& imageList, 
     83            unsigned int numComponentsDesired, 
     84            int s_maximumTextureSize, 
     85            int t_maximumTextureSize, 
     86            int r_maximumTextureSize, 
     87            bool resizeToPowerOfTwo) 
     88{ 
     89 
     90    if (numComponentsDesired==0) 
     91    { 
     92        return osg::createImage3DWithAlpha(imageList, 
     93                                        s_maximumTextureSize, 
     94                                        t_maximumTextureSize, 
     95                                        r_maximumTextureSize, 
     96                                        resizeToPowerOfTwo); 
     97    } 
     98    else 
     99    { 
     100        GLenum desiredPixelFormat = 0; 
     101        switch(numComponentsDesired) 
     102        { 
     103            case(1) : desiredPixelFormat = GL_LUMINANCE; break; 
     104            case(2) : desiredPixelFormat = GL_LUMINANCE_ALPHA; break; 
     105            case(3) : desiredPixelFormat = GL_RGB; break; 
     106            case(4) : desiredPixelFormat = GL_RGBA; break; 
     107        } 
     108 
     109        return osg::createImage3D(imageList, 
     110                                        desiredPixelFormat, 
     111                                        s_maximumTextureSize, 
     112                                        t_maximumTextureSize, 
     113                                        r_maximumTextureSize, 
     114                                        resizeToPowerOfTwo); 
     115    } 
    102116} 
    103117 
    104 #if 1 
    105118struct ModulateAlphaByLuminanceOperator 
    106119{ 
     
    114127}; 
    115128 
    116 osg::Image* createTexture3D(osg::ImageList& imageList, 
    117             unsigned int numComponentsDesired, 
    118             int s_maximumTextureSize, 
    119             int t_maximumTextureSize, 
    120             int r_maximumTextureSize, 
    121             bool resizeToPowerOfTwo) 
    122 { 
    123  
    124     GLenum desiredPixelFormat = 0; 
    125     bool modulateAlphaByLuminance = false; 
    126     if (numComponentsDesired==0) 
    127     { 
    128         unsigned int maxNumComponents = osg::maximimNumOfComponents(imageList); 
    129         if (maxNumComponents==3) 
    130         { 
    131             desiredPixelFormat = GL_RGBA; 
    132             modulateAlphaByLuminance = true; 
    133         } 
    134     } 
    135     else 
    136     { 
    137         switch(numComponentsDesired) 
    138         { 
    139             case(1) : desiredPixelFormat = GL_LUMINANCE; break; 
    140             case(2) : desiredPixelFormat = GL_LUMINANCE_ALPHA; break; 
    141             case(3) : desiredPixelFormat = GL_RGB; break; 
    142             case(4) : desiredPixelFormat = GL_RGBA; break; 
    143         } 
    144     } 
    145  
    146     osg::ref_ptr<osg::Image> image = osg::createImage3D(imageList, 
    147                                         desiredPixelFormat, 
    148                                         s_maximumTextureSize, 
    149                                         t_maximumTextureSize, 
    150                                         r_maximumTextureSize, 
    151                                         resizeToPowerOfTwo); 
    152     if (image.valid()) 
    153     { 
    154         if (modulateAlphaByLuminance) 
    155         { 
    156             osg::modifyImage(image.get(), ModulateAlphaByLuminanceOperator()); 
    157         } 
    158         return image.release(); 
    159     } 
    160     else 
    161     { 
    162         return 0; 
    163     } 
    164 } 
    165 #else 
    166  
    167 struct ProcessRow 
    168 { 
    169     virtual ~ProcessRow() {} 
    170  
    171     virtual void operator() (unsigned int num, 
    172                     GLenum source_pixelFormat, unsigned char* source, 
    173                     GLenum dest_pixelFormat, unsigned char* dest) const 
    174     { 
    175         switch(source_pixelFormat) 
    176         { 
    177         case(GL_LUMINANCE): 
    178         case(GL_ALPHA): 
    179             switch(dest_pixelFormat) 
    180             { 
    181             case(GL_LUMINANCE): 
    182             case(GL_ALPHA): A_to_A(num, source, dest); break; 
    183             case(GL_LUMINANCE_ALPHA): A_to_LA(num, source, dest); break; 
    184             case(GL_RGB): A_to_RGB(num, source, dest); break; 
    185             case(GL_RGBA): A_to_RGBA(num, source, dest); break; 
    186             } 
    187             break; 
    188         case(GL_LUMINANCE_ALPHA): 
    189             switch(dest_pixelFormat) 
    190             { 
    191             case(GL_LUMINANCE): 
    192             case(GL_ALPHA): LA_to_A(num, source, dest); break; 
    193             case(GL_LUMINANCE_ALPHA): LA_to_LA(num, source, dest); break; 
    194             case(GL_RGB): LA_to_RGB(num, source, dest); break; 
    195             case(GL_RGBA): LA_to_RGBA(num, source, dest); break; 
    196             } 
    197             break; 
    198         case(GL_RGB): 
    199             switch(dest_pixelFormat) 
    200             { 
    201             case(GL_LUMINANCE): 
    202             case(GL_ALPHA): RGB_to_A(num, source, dest); break; 
    203             case(GL_LUMINANCE_ALPHA): RGB_to_LA(num, source, dest); break; 
    204             case(GL_RGB): RGB_to_RGB(num, source, dest); break; 
    205             case(GL_RGBA): RGB_to_RGBA(num, source, dest); break; 
    206             } 
    207             break; 
    208         case(GL_RGBA): 
    209             switch(dest_pixelFormat) 
    210             { 
    211             case(GL_LUMINANCE): 
    212             case(GL_ALPHA): RGBA_to_A(num, source, dest); break; 
    213             case(GL_LUMINANCE_ALPHA): RGBA_to_LA(num, source, dest); break; 
    214             case(GL_RGB): RGBA_to_RGB(num, source, dest); break; 
    215             case(GL_RGBA): RGBA_to_RGBA(num, source, dest); break; 
    216             } 
    217             break; 
    218         case(GL_BGR): 
    219             switch(dest_pixelFormat) 
    220             { 
    221             case(GL_LUMINANCE): 
    222             case(GL_ALPHA): BGR_to_A(num, source, dest); break; 
    223             case(GL_LUMINANCE_ALPHA): BGR_to_LA(num, source, dest); break; 
    224             case(GL_RGB): BGR_to_RGB(num, source, dest); break; 
    225             case(GL_RGBA): BGR_to_RGBA(num, source, dest); break; 
    226             } 
    227             break; 
    228         case(GL_BGRA): 
    229             switch(dest_pixelFormat) 
    230             { 
    231             case(GL_LUMINANCE): 
    232             case(GL_ALPHA): BGRA_to_A(num, source, dest); break; 
    233             case(GL_LUMINANCE_ALPHA): BGRA_to_LA(num, source, dest); break; 
    234             case(GL_RGB): BGRA_to_RGB(num, source, dest); break; 
    235             case(GL_RGBA): BGRA_to_RGBA(num, source, dest); break; 
    236             } 
    237             break; 
    238         } 
    239     } 
    240  
    241     /////////////////////////////////////////////////////////////////////////////// 
    242     // alpha sources.. 
    243     virtual void A_to_A(unsigned int num, unsigned char* source, unsigned char* dest) const 
    244     { 
    245         for(unsigned int i=0;i<num;++i) 
    246         { 
    247             *dest++ = *source++; 
    248         } 
    249     } 
    250  
    251     virtual void A_to_LA(unsigned int num, unsigned char* source, unsigned char* dest) const 
    252     { 
    253         for(unsigned int i=0;i<num;++i) 
    254         { 
    255             *dest++ = *source; 
    256             *dest++ = *source++; 
    257         } 
    258     } 
    259  
    260     virtual void A_to_RGB(unsigned int num, unsigned char* source, unsigned char* dest) const 
    261     { 
    262         for(unsigned int i=0;i<num;++i) 
    263         { 
    264             *dest++ = *source; 
    265             *dest++ = *source; 
    266             *dest++ = *source++; 
    267         } 
    268     } 
    269  
    270     virtual void A_to_RGBA(unsigned int num, unsigned char* source, unsigned char* dest) const 
    271     { 
    272         for(unsigned int i=0;i<num;++i) 
    273         { 
    274             *dest++ = *source; 
    275             *dest++ = *source; 
    276             *dest++ = *source; 
    277             *dest++ = *source++; 
    278         } 
    279     } 
    280  
    281     /////////////////////////////////////////////////////////////////////////////// 
    282     // alpha luminance sources.. 
    283     virtual void LA_to_A(unsigned int num, unsigned char* source, unsigned char* dest) const 
    284     { 
    285         for(unsigned int i=0;i<num;++i) 
    286         { 
    287             ++source; 
    288             *dest++ = *source++; 
    289         } 
    290     } 
    291  
    292     virtual void LA_to_LA(unsigned int num, unsigned char* source, unsigned char* dest) const 
    293     { 
    294         for(unsigned int i=0;i<num;++i) 
    295         { 
    296             *dest++ = *source++; 
    297             *dest++ = *source++; 
    298         } 
    299     } 
    300  
    301     virtual void LA_to_RGB(unsigned int num, unsigned char* source, unsigned char* dest) const 
    302     { 
    303         for(unsigned int i=0;i<num;++i) 
    304         { 
    305             *dest++ = *source; 
    306             *dest++ = *source; 
    307             *dest++ = *source; 
    308             source+=2; 
    309         } 
    310     } 
    311  
    312     virtual void LA_to_RGBA(unsigned int num, unsigned char* source, unsigned char* dest) const 
    313     { 
    314         for(unsigned int i=0;i<num;++i) 
    315         { 
    316             *dest++ = *source; 
    317             *dest++ = *source; 
    318             *dest++ = *source++; 
    319             *dest++ = *source++; 
    320         } 
    321     } 
    322  
    323     /////////////////////////////////////////////////////////////////////////////// 
    324     // RGB sources.. 
    325     virtual void RGB_to_A(unsigned int num, unsigned char* source, unsigned char* dest) const 
    326     { 
    327         for(unsigned int i=0;i<num;++i) 
    328         { 
    329             unsigned char val = *source; 
    330             *dest++ = val; 
    331             source += 3; 
    332         } 
    333     } 
    334  
    335     virtual void RGB_to_LA(unsigned int num, unsigned char* source, unsigned char* dest) const 
    336     { 
    337         for(unsigned int i=0;i<num;++i) 
    338         { 
    339             unsigned char val = *source; 
    340             *dest++ = val; 
    341             *dest++ = val; 
    342             source += 3; 
    343         } 
    344     } 
    345  
    346     virtual void RGB_to_RGB(unsigned int num, unsigned char* source, unsigned char* dest) const 
    347     { 
    348         for(unsigned int i=0;i<num;++i) 
    349         { 
    350             *dest++ = *source++; 
    351             *dest++ = *source++; 
    352             *dest++ = *source++; 
    353         } 
    354     } 
    355  
    356     virtual void RGB_to_RGBA(unsigned int num, unsigned char* source, unsigned char* dest) const 
    357     { 
    358         for(unsigned int i=0;i<num;++i) 
    359         { 
    360             unsigned char val = *source; 
    361             *dest++ = *source++; 
    362             *dest++ = *source++; 
    363             *dest++ = *source++; 
    364             *dest++ = val; 
    365         } 
    366     } 
    367  
    368     /////////////////////////////////////////////////////////////////////////////// 
    369     // RGBA sources.. 
    370     virtual void RGBA_to_A(unsigned int num, unsigned char* source, unsigned char* dest) const 
    371     { 
    372         for(unsigned int i=0;i<num;++i) 
    373         { 
    374             source += 3; 
    375             *dest++ = *source++; 
    376         } 
    377     } 
    378  
    379     virtual void RGBA_to_LA(unsigned int num, unsigned char* source, unsigned char* dest) const 
    380     { 
    381         for(unsigned int i=0;i<num;++i) 
    382         { 
    383             unsigned char val = *source; 
    384             source += 3; 
    385             *dest++ = val; 
    386             *dest++ = *source++; 
    387         } 
    388     } 
    389  
    390     virtual void RGBA_to_RGB(unsigned int num, unsigned char* source, unsigned char* dest) const 
    391     { 
    392         for(unsigned int i=0;i<num;++i) 
    393         { 
    394             *dest++ = *source++; 
    395             *dest++ = *source++; 
    396             *dest++ = *source++; 
    397             ++source; 
    398         } 
    399     } 
    400  
    401     virtual void RGBA_to_RGBA(unsigned int num, unsigned char* source, unsigned char* dest) const 
    402     { 
    403         for(unsigned int i=0;i<num;++i) 
    404         { 
    405             *dest++ = *source++; 
    406             *dest++ = *source++; 
    407             *dest++ = *source++; 
    408             *dest++ = *source++; 
    409         } 
    410     } 
    411  
    412      /////////////////////////////////////////////////////////////////////////////// 
    413     // BGR sources.. 
    414     virtual void BGR_to_A(unsigned int num, unsigned char* source, unsigned char* dest) const 
    415     { 
    416         for(unsigned int i=0;i<num;++i) 
    417         { 
    418             unsigned char val = *source; 
    419             *dest++ = val; 
    420             source += 3; 
    421         } 
    422     } 
    423  
    424     virtual void BGR_to_LA(unsigned int num, unsigned char* source, unsigned char* dest) const 
    425     { 
    426         for(unsigned int i=0;i<num;++i) 
    427         { 
    428             unsigned char val = *source; 
    429             *dest++ = val; 
    430             *dest++ = val; 
    431             source += 3; 
    432         } 
    433     } 
    434  
    435     virtual void BGR_to_RGB(unsigned int num, unsigned char* source, unsigned char* dest) const 
    436     { 
    437         for(unsigned int i=0;i<num;++i) 
    438         { 
    439             unsigned char blue = *source++; 
    440             unsigned char green = *source++; 
    441             unsigned char red = *source++; 
    442             *dest++ = red; 
    443             *dest++ = green; 
    444             *dest++ = blue; 
    445         } 
    446     } 
    447  
    448     virtual void BGR_to_RGBA(unsigned int num, unsigned char* source, unsigned char* dest) const 
    449     { 
    450         for(unsigned int i=0;i<num;++i) 
    451         { 
    452             unsigned char blue = *source++; 
    453             unsigned char green = *source++; 
    454             unsigned char red = *source++; 
    455             unsigned char val = (unsigned char)((int(red)+int(green)+int(blue))/3); 
    456             *dest++ = red; 
    457             *dest++ = green; 
    458             *dest++ = blue; 
    459             *dest++ = val; 
    460         } 
    461     } 
    462  
    463     /////////////////////////////////////////////////////////////////////////////// 
    464     // BGRA sources.. 
    465     virtual void BGRA_to_A(unsigned int num, unsigned char* source, unsigned char* dest) const 
    466     { 
    467         for(unsigned int i=0;i<num;++i) 
    468         { 
    469             source += 3; 
    470             *dest++ = *source++; 
    471         } 
    472     } 
    473  
    474     virtual void BGRA_to_LA(unsigned int num, unsigned char* source, unsigned char* dest) const 
    475     { 
    476         for(unsigned int i=0;i<num;++i) 
    477         { 
    478             unsigned char val = *source; 
    479             source += 3; 
    480             *dest++ = val; 
    481             *dest++ = *source++; 
    482         } 
    483     } 
    484  
    485     virtual void BGRA_to_RGB(unsigned int num, unsigned char* source, unsigned char* dest) const 
    486     { 
    487         for(unsigned int i=0;i<num;++i) 
    488         { 
    489             unsigned char blue = *source++; 
    490             unsigned char green = *source++; 
    491             unsigned char red = *source++; 
    492             *dest++ = red; 
    493             *dest++ = green; 
    494             *dest++ = blue; 
    495             ++source; 
    496         } 
    497     } 
    498  
    499     virtual void BGRA_to_RGBA(unsigned int num, unsigned char* source, unsigned char* dest) const 
    500     { 
    501         for(unsigned int i=0;i<num;++i) 
    502         { 
    503             unsigned char blue = *source++; 
    504             unsigned char green = *source++; 
    505             unsigned char red = *source++; 
    506             unsigned char alpha = *source++; 
    507             *dest++ = red; 
    508             *dest++ = green; 
    509             *dest++ = blue; 
    510             *dest++ = alpha; 
    511         } 
    512     } 
    513  
    514 }; 
    515  
    516 osg::Image* createTexture3D(osg::ImageList& imageList,  
    517             unsigned int numComponentsDesired, 
    518             int s_maximumTextureSize, 
    519             int t_maximumTextureSize, 
    520             int r_maximumTextureSize, 
    521             bool resizeToPowerOfTwo) 
    522 { 
    523     ProcessRow processRow; 
    524     int max_s = 0; 
    525     int max_t = 0; 
    526     unsigned int max_components = 0; 
    527     int total_r = 0; 
    528     osg::ImageList::iterator itr; 
    529     for(itr=imageList.begin(); 
    530         itr!=imageList.end(); 
    531         ++itr) 
    532     { 
    533         osg::Image* image = itr->get(); 
    534         GLenum pixelFormat = image->getPixelFormat(); 
    535         if (pixelFormat==GL_ALPHA || 
    536             pixelFormat==GL_INTENSITY || 
    537             pixelFormat==GL_LUMINANCE || 
    538             pixelFormat==GL_LUMINANCE_ALPHA || 
    539             pixelFormat==GL_RGB || 
    540             pixelFormat==GL_RGBA || 
    541             pixelFormat==GL_BGR || 
    542             pixelFormat==GL_BGRA) 
    543         { 
    544             max_s = osg::maximum(image->s(), max_s); 
    545             max_t = osg::maximum(image->t(), max_t); 
    546             max_components = osg::maximum(osg::Image::computeNumComponents(pixelFormat), max_components); 
    547             total_r += image->r(); 
    548         } 
    549         else 
    550         { 
    551             osg::notify(osg::NOTICE)<<"Image "<<image->getFileName()<<" has unsuitable pixel format 0x"<< std::hex<< pixelFormat << std::dec << std::endl; 
    552         } 
    553     } 
    554  
    555     if (max_components==3) 
    556     { 
    557         // change RGB to a RGBA 
    558         max_components = 4; 
    559     } 
    560  
    561     if (numComponentsDesired!=0) max_components = numComponentsDesired; 
    562  
    563     GLenum desiredPixelFormat = 0; 
    564     switch(max_components) 
    565     { 
    566     case(1): 
    567         osg::notify(osg::NOTICE)<<"desiredPixelFormat = GL_LUMINANCE" << std::endl; 
    568         desiredPixelFormat = GL_LUMINANCE; 
    569         break; 
    570     case(2): 
    571         osg::notify(osg::NOTICE)<<"desiredPixelFormat = GL_LUMINANCE_ALPHA" << std::endl; 
    572         desiredPixelFormat = GL_LUMINANCE_ALPHA; 
    573         break; 
    574     case(3): 
    575         osg::notify(osg::NOTICE)<<"desiredPixelFormat = GL_RGB" << std::endl; 
    576         desiredPixelFormat = GL_RGB; 
    577         break; 
    578     case(4): 
    579         osg::notify(osg::NOTICE)<<"desiredPixelFormat = GL_RGBA" << std::endl; 
    580         desiredPixelFormat = GL_RGBA; 
    581         break; 
    582     } 
    583     if (desiredPixelFormat==0) return 0; 
    584  
    585     // compute nearest powers of two for each axis. 
    586  
    587     int s_nearestPowerOfTwo = 1; 
    588     int t_nearestPowerOfTwo = 1; 
    589     int r_nearestPowerOfTwo = 1; 
    590  
    591     if (resizeToPowerOfTwo) 
    592     { 
    593         while(s_nearestPowerOfTwo<max_s && s_nearestPowerOfTwo<s_maximumTextureSize) s_nearestPowerOfTwo*=2; 
    594         while(t_nearestPowerOfTwo<max_t && t_nearestPowerOfTwo<t_maximumTextureSize) t_nearestPowerOfTwo*=2; 
    595         while(r_nearestPowerOfTwo<total_r && r_nearestPowerOfTwo<r_maximumTextureSize) r_nearestPowerOfTwo*=2; 
    596  
    597         osg::notify(osg::NOTICE)<<"max image width = "<<max_s<<"  nearest power of two = "<<s_nearestPowerOfTwo<<std::endl; 
    598         osg::notify(osg::NOTICE)<<"max image height = "<<max_t<<"  nearest power of two = "<<t_nearestPowerOfTwo<<std::endl; 
    599         osg::notify(osg::NOTICE)<<"max image depth = "<<total_r<<"  nearest power of two = "<<r_nearestPowerOfTwo<<std::endl; 
    600     } 
    601     else 
    602     { 
    603         s_nearestPowerOfTwo = max_s; 
    604         t_nearestPowerOfTwo = max_t; 
    605         r_nearestPowerOfTwo = total_r; 
    606     } 
    607  
    608     // now allocate the 3d texture; 
    609     osg::ref_ptr<osg::Image> image_3d = new osg::Image; 
    610     image_3d->allocateImage(s_nearestPowerOfTwo,t_nearestPowerOfTwo,r_nearestPowerOfTwo, 
    611                             desiredPixelFormat,GL_UNSIGNED_BYTE); 
    612  
    613  
    614     unsigned int r_offset = (total_r<r_nearestPowerOfTwo) ? r_nearestPowerOfTwo/2 - total_r/2 : 0; 
    615  
    616     int curr_dest_r = r_offset; 
    617  
    618     // copy across the values from the source images into the image_3d. 
    619     for(itr=imageList.begin(); 
    620         itr!=imageList.end(); 
    621         ++itr) 
    622     { 
    623         osg::Image* image = itr->get(); 
    624         GLenum pixelFormat = image->getPixelFormat(); 
    625         if (pixelFormat==GL_ALPHA || 
    626             pixelFormat==GL_LUMINANCE || 
    627             pixelFormat==GL_INTENSITY || 
    628             pixelFormat==GL_LUMINANCE_ALPHA || 
    629             pixelFormat==GL_RGB || 
    630             pixelFormat==GL_RGBA || 
    631             pixelFormat==GL_BGR || 
    632             pixelFormat==GL_BGRA) 
    633         { 
    634  
    635             int num_r = osg::minimum(image->r(), (image_3d->r() - curr_dest_r)); 
    636             int num_t = osg::minimum(image->t(), image_3d->t()); 
    637             int num_s = osg::minimum(image->s(), image_3d->s()); 
    638  
    639             unsigned int s_offset_dest = (image->s()<s_nearestPowerOfTwo) ? s_nearestPowerOfTwo/2 - image->s()/2 : 0; 
    640             unsigned int t_offset_dest = (image->t()<t_nearestPowerOfTwo) ? t_nearestPowerOfTwo/2 - image->t()/2 : 0; 
    641  
    642             for(int r=0;r<num_r;++r, ++curr_dest_r) 
    643             { 
    644                 for(int t=0;t<num_t;++t) 
    645                 { 
    646                     unsigned char* dest = image_3d->data(s_offset_dest,t+t_offset_dest,curr_dest_r); 
    647                     unsigned char* source = image->data(0,t,r); 
    648  
    649                     processRow(num_s, image->getPixelFormat(), source, image_3d->getPixelFormat(), dest); 
    650                 } 
    651             } 
    652         } 
    653     } 
    654     return image_3d.release(); 
    655 } 
    656 #endif 
    657129 
    658130struct ScaleOperator 
     
    701173    inline void rgba(float& r,float& g,float& b,float& a) const {  r = _colours[_pos].r(); g = _colours[_pos].g(); b = _colours[_pos].b(); a = _colours[_pos++].a(); } 
    702174}; 
     175 
     176void clampToNearestValidPowerOfTwo(int& sizeX, int& sizeY, int& sizeZ, int s_maximumTextureSize, int t_maximumTextureSize, int r_maximumTextureSize) 
     177{ 
     178    // compute nearest powers of two for each axis. 
     179    int s_nearestPowerOfTwo = 1; 
     180    while(s_nearestPowerOfTwo<sizeX && s_nearestPowerOfTwo<s_maximumTextureSize) s_nearestPowerOfTwo*=2; 
     181 
     182    int t_nearestPowerOfTwo = 1; 
     183    while(t_nearestPowerOfTwo<sizeY && t_nearestPowerOfTwo<t_maximumTextureSize) t_nearestPowerOfTwo*=2; 
     184 
     185    int r_nearestPowerOfTwo = 1; 
     186    while(r_nearestPowerOfTwo<sizeZ && r_nearestPowerOfTwo<r_maximumTextureSize) r_nearestPowerOfTwo*=2; 
     187 
     188    sizeX = s_nearestPowerOfTwo; 
     189    sizeY = t_nearestPowerOfTwo; 
     190    sizeZ = r_nearestPowerOfTwo; 
     191} 
    703192 
    704193osg::Image* readRaw(int sizeX, int sizeY, int sizeZ, int numberBytesPerComponent, int numberOfComponents, const std::string& endian, const std::string& raw_filename)