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

OSGDVRIsoShader.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000,2001 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038 
00039 //---------------------------------------------------------------------------
00040 //  Includes
00041 //---------------------------------------------------------------------------
00042 
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045 
00046 
00047 #include <OSGConfig.h>
00048 #include <OSGGL.h>
00049 #include <OSGGLEXT.h>
00050 #include <OSGSlicer.h>
00051 #include <OSGGLU.h>
00052 
00053 #include "OSGDVRIsoShader.h"
00054 
00055 OSG_USING_NAMESPACE
00056 
00057 
00058 // register extensions and initialize extension functions
00059 
00060 UInt32 DVRIsoShader::_ARB_multitexture       = Window::invalidExtensionID;
00061 UInt32 DVRIsoShader::_EXT_texture3D          = Window::invalidExtensionID;
00062 UInt32 DVRIsoShader::_NV_register_combiners  = Window::invalidExtensionID;
00063 UInt32 DVRIsoShader::_NV_register_combiners2 = Window::invalidExtensionID;
00064 UInt32 DVRIsoShader::_SGI_color_matrix       = Window::invalidExtensionID;
00065 UInt32 DVRIsoShader::_ARB_fragment_program   = Window::invalidExtensionID;
00066 UInt32 DVRIsoShader::_EXT_secondary_color    = Window::invalidExtensionID;
00067 
00068 
00069 UInt32 DVRIsoShader::_funcActiveTextureARB            =  
00070     Window::invalidFunctionID;
00071 
00072 UInt32 DVRIsoShader::_funcMultiTexCoord2dARB          = 
00073     Window::invalidFunctionID;
00074 
00075 UInt32 DVRIsoShader::_funcTexImage3DEXT               = 
00076     Window::invalidFunctionID;
00077 
00078 UInt32 DVRIsoShader::_funcCombinerParameteriNV        = 
00079     Window::invalidFunctionID;
00080 
00081 UInt32 DVRIsoShader::_funcCombinerParameterfvNV       = 
00082     Window::invalidFunctionID;
00083 
00084 UInt32 DVRIsoShader::_funcCombinerStageParameterfvNV  = 
00085     Window::invalidFunctionID;
00086 
00087 UInt32 DVRIsoShader::_funcSecondaryColor3fEXT         = 
00088     Window::invalidFunctionID;
00089 
00090 UInt32 DVRIsoShader::_funcSecondaryColor3fvEXT        = 
00091     Window::invalidFunctionID;
00092 
00093 UInt32 DVRIsoShader::_funcCombinerInputNV             = 
00094     Window::invalidFunctionID;
00095 
00096 UInt32 DVRIsoShader::_funcCombinerOutputNV            = 
00097     Window::invalidFunctionID;
00098 
00099 UInt32 DVRIsoShader::_funcFinalCombinerInputNV        = 
00100     Window::invalidFunctionID;
00101 
00106 /*----------------------- constructors & destructors ----------------------*/
00107 
00109 DVRIsoShader::DVRIsoShader(void) :
00110     Inherited()
00111 {
00112     m_gradientImage = NullFC;
00113     m_shadingMode   = SM_NONE;
00114     m_pFragProg     = NullFC;
00115     m_textureId     = -1;
00116 
00117     // Do this here, will change in future for OpenSG as a whole
00118     _ARB_multitexture       = 
00119         Window::registerExtension("GL_ARB_multitexture"      );
00120 
00121     _EXT_texture3D          = 
00122         Window::registerExtension("GL_EXT_texture3D"         );
00123 
00124     _EXT_secondary_color     = 
00125         Window::registerExtension("GL_EXT_secondary_color"   );
00126 
00127     _NV_register_combiners  = 
00128         Window::registerExtension("GL_NV_register_combiners" );
00129 
00130     _NV_register_combiners2 = 
00131         Window::registerExtension("GL_NV_register_combiners2");
00132 
00133     _SGI_color_matrix       = 
00134         Window::registerExtension("GL_SGI_color_matrix"      );
00135 
00136     _ARB_fragment_program   = 
00137         Window::registerExtension("GL_ARB_fragment_program"  );
00138 
00139 
00140     _funcActiveTextureARB            =  
00141        Window::registerFunction(OSG_DLSYM_UNDERSCORE"glActiveTextureARB",    
00142                                 _ARB_multitexture);
00143 
00144     _funcMultiTexCoord2dARB          = 
00145        Window::registerFunction(OSG_DLSYM_UNDERSCORE"glMultiTexCoord2dARB",    
00146                                 _ARB_multitexture);
00147 
00148     _funcTexImage3DEXT               = 
00149        Window::registerFunction(OSG_DLSYM_UNDERSCORE"glTexImage3DEXT",    
00150                                 _ARB_multitexture);
00151 
00152     _funcCombinerParameteriNV        = 
00153        Window::registerFunction(OSG_DLSYM_UNDERSCORE"glCombinerParameteriNV",    
00154                                 _NV_register_combiners);
00155     
00156     _funcCombinerParameterfvNV       = 
00157        Window::registerFunction(OSG_DLSYM_UNDERSCORE"glCombinerParameterfvNV",    
00158                                 _NV_register_combiners);
00159 
00160     _funcCombinerStageParameterfvNV  = 
00161        Window::registerFunction(
00162            OSG_DLSYM_UNDERSCORE"glCombinerStageParameterfvNV",    
00163                                 _NV_register_combiners);
00164 
00165     _funcSecondaryColor3fEXT         = 
00166        Window::registerFunction(OSG_DLSYM_UNDERSCORE"glSecondaryColor3fEXT",    
00167                                 _EXT_secondary_color);
00168 
00169     _funcSecondaryColor3fvEXT        = 
00170        Window::registerFunction(OSG_DLSYM_UNDERSCORE"glSecondaryColor3fvEXT",    
00171                                 _EXT_secondary_color);
00172 
00173     _funcCombinerInputNV             = 
00174        Window::registerFunction(OSG_DLSYM_UNDERSCORE"glCombinerInputNV",    
00175                                 _NV_register_combiners);
00176 
00177     _funcCombinerOutputNV            = 
00178        Window::registerFunction(OSG_DLSYM_UNDERSCORE"glCombinerOutputNV",    
00179                                 _NV_register_combiners);
00180 
00181     _funcFinalCombinerInputNV        = 
00182        Window::registerFunction(OSG_DLSYM_UNDERSCORE"glFinalCombinerInputNV",    
00183                                 _NV_register_combiners);
00184 
00185 }
00186 
00188 DVRIsoShader::DVRIsoShader(const DVRIsoShader &source) :
00189     Inherited(source)
00190 {  
00191     m_gradientImage = NullFC;
00192     m_shadingMode = SM_NONE;
00193     m_pFragProg = NullFC;
00194     m_textureId = -1;
00195 }
00196 
00198 DVRIsoShader::~DVRIsoShader(void)
00199 {
00200     if(m_pFragProg != NullFC) 
00201     {
00202         subRefCP(m_pFragProg);
00203 
00204         m_pFragProg = NullFC;
00205     }
00206 
00207     if(m_gradientImage != NullFC) 
00208     {
00209         subRefCP(m_gradientImage);
00210 
00211         m_gradientImage = NullFC;
00212     }
00213 
00214     m_textureId = -1;
00215 }
00216 
00217 /*----------------------------- class specific ----------------------------*/
00218 
00220 void DVRIsoShader::initMethod(void)
00221 {
00222 }
00223 
00225 
00226 void DVRIsoShader::changed(BitVector whichField, UInt32 origin)
00227 {
00228     // trigger re-initialization
00229     if(whichField & ShadeModeFieldMask)
00230         setActiveShadeMode(SM_AUTO);
00231     
00232     Inherited::changed(whichField, origin);
00233 }
00234 
00236 void DVRIsoShader::dump(      UInt32    , 
00237                         const BitVector ) const
00238 {
00239     SLOG << "Dump DVRIsoShader NI" << std::endl;
00240 }
00241 
00242 // Callback to set up shader - register textures here
00243 bool DVRIsoShader::initialize(DVRVolume *volume, DrawActionBase *action)
00244 {  
00245 
00246     DVRVolumeTexturePtr vol = DVRVOLUME_PARAMETER(volume, DVRVolumeTexture);
00247   
00248     if((volume == NULL) || (vol == NullFC)) 
00249     {
00250         SWARNING << "DVRIsoShader - NO Volume" << std::endl;
00251         return false;
00252     }
00253 
00254     // Determine shading mechanism
00255     tryMode(volume, action, getShadeMode());
00256 
00257     GLenum nInternalFormat = GL_RGBA;
00258     GLenum nExternalFormat = GL_RGBA;
00259 
00260     // create gradient texture
00261     if(m_gradientImage != NullFC)
00262         subRefCP(m_gradientImage);
00263 
00264     m_gradientImage = createGradientImage(vol);
00265 
00266     addRefCP(m_gradientImage);
00267   
00268     if((m_shadingMode == SM_REGISTER_COMBINERS_MULTI2D) || 
00269        (m_shadingMode == SM_FRAGMENT_PROGRAM_2D       )  )
00270     {
00271         // init multitexture 
00272         m_textureId = volume->getTextureManager().registerTexture(
00273             m_gradientImage, 
00274             nInternalFormat, 
00275             nExternalFormat,                      
00276             true,
00277             0,
00278             1);
00279     }
00280     else
00281     {
00282         // init single texture
00283         m_textureId = volume->getTextureManager().registerTexture(
00284             m_gradientImage, 
00285             nInternalFormat, 
00286             nExternalFormat,
00287             true,
00288             0,
00289             -1);
00290     }
00291     
00292     if( m_textureId < 0)
00293     {
00294         SWARNING << "DVRIsoShader - Could not register texture: "
00295                  << m_textureId 
00296                  << std::endl; 
00297 
00298         subRefCP(m_gradientImage);
00299 
00300         return false;
00301     }
00302     
00303     return true;
00304 }
00305 
00306 
00307 // Callback before any slice is rendered - setup per volume
00308 void DVRIsoShader::activate(DVRVolume *volume, DrawActionBase *action)
00309 {
00310     // reinitialize if hardware mode has not yet been chosen or mode 
00311     // has changed
00312 
00313     if(getActiveShadeMode() == SM_AUTO) 
00314     {
00315         cleanup   (volume, action);
00316         initialize(volume, action);
00317         
00318         // notify volume about shader changed
00319         beginEditCP(DVRVolumePtr(volume), DVRVolume::ShaderFieldMask);
00320         endEditCP(DVRVolumePtr  (volume), DVRVolume::ShaderFieldMask);
00321     }
00322 
00323     switch(m_shadingMode)
00324     {
00325         case SM_COLORMATRIX_2D:
00326         case SM_COLORMATRIX_3D:
00327             activate_ColorMatrixShading(volume, action);
00328             break;
00329 
00330         case SM_REGISTER_COMBINERS_2D:
00331         case SM_REGISTER_COMBINERS_MULTI2D:
00332         case SM_REGISTER_COMBINERS_3D: 
00333             activate_NVRegisterCombinerShading(volume, action);
00334             break;
00335 
00336         case SM_FRAGMENT_PROGRAM_2D: 
00337         case SM_FRAGMENT_PROGRAM_3D:
00338             activate_FragmentProgramShading(volume, action);
00339             break;
00340 
00341         case SM_NONE:
00342         default:
00343             break;
00344     }
00345 }
00346 
00347 
00348 // Callback before any brick - state setup per brick
00349 void DVRIsoShader::brickActivate(DVRVolume *, DrawActionBase *, Brick *)
00350 {
00351     FDEBUG(("DVRIsoShader::brickActivate - nothing to do\n"));  
00352 }
00353 
00354 
00355 // Callback after all rendering of the volume is done
00356 void DVRIsoShader::deactivate(DVRVolume *volume, DrawActionBase *action)
00357 {
00358     switch(m_shadingMode)
00359     {
00360         case SM_COLORMATRIX_2D:
00361         case SM_COLORMATRIX_3D:
00362             deactivate_ColorMatrixShading(volume, action);
00363             break;
00364 
00365         case SM_REGISTER_COMBINERS_2D:
00366         case SM_REGISTER_COMBINERS_MULTI2D:
00367         case SM_REGISTER_COMBINERS_3D:
00368             deactivate_NVRegisterCombinerShading(volume, action);
00369             break;
00370 
00371         case SM_FRAGMENT_PROGRAM_2D: 
00372         case SM_FRAGMENT_PROGRAM_3D:
00373             deactivate_FragmentProgramShading(volume, action);
00374             break;
00375 
00376         case SM_NONE:
00377         default:
00378             break;
00379     }
00380 }
00381 
00382 
00383 // Callback to clean up shader resources
00384 void DVRIsoShader::cleanup(DVRVolume *volume, DrawActionBase *)
00385 {
00386     if(m_pFragProg != NullFC) 
00387     {
00388         subRefCP(m_pFragProg);
00389 
00390         m_pFragProg = NullFC;
00391     }
00392 
00393     if(m_gradientImage != NullFC) 
00394     {
00395         subRefCP(m_gradientImage);
00396 
00397         m_gradientImage = NullFC;        
00398     }
00399     
00400     if (m_textureId != -1)
00401     {
00402         volume->getTextureManager().unregisterTexture(m_textureId);
00403     }
00404 }
00405 
00406 
00407 // Own function for rendering a slice, only needed for 2D texturing with 
00408 // slice interpolation, otherwise this is done by the volume
00409 void DVRIsoShader::renderSlice(DVRVolume      *volume, 
00410                                DrawActionBase *action,
00411                                Real32         *data, 
00412                                UInt32          vertices, 
00413                                UInt32          values  )
00414 {
00415     switch(m_shadingMode)
00416     {
00417         case SM_REGISTER_COMBINERS_MULTI2D:
00418             renderSlice_NVRegisterCombinerShading(volume,
00419                                                   action,
00420                                                   data,
00421                                                   vertices,
00422                                                   values);
00423             break;
00424 
00425         case SM_FRAGMENT_PROGRAM_2D:
00426             renderSlice_FragmentProgramShading(volume,
00427                                                action,
00428                                                data,
00429                                                vertices,
00430                                                values);
00431             break;
00432         default:
00433             break;
00434     }
00435 }
00436 
00437 
00438 // Callback for rendering clipped slices
00439 void DVRIsoShader::renderSlice(DVRVolume      *volume, 
00440                                DrawActionBase *action,
00441                                DVRRenderSlice *clippedSlice) 
00442 {
00443     switch(m_shadingMode)
00444     {
00445         case SM_REGISTER_COMBINERS_MULTI2D:
00446             renderSlice_NVRegisterCombinerShading(volume,action,clippedSlice);
00447             break;
00448 
00449         case SM_FRAGMENT_PROGRAM_2D:
00450             renderSlice_FragmentProgramShading(volume,action,clippedSlice);
00451             break;
00452 
00453         default:
00454             break;
00455      }
00456 }
00457 
00458 
00459 // Indicate whether a private function for rendering a slice should be 
00460 // used or not only needed for 2D texturing with slice interpolation
00461 bool DVRIsoShader::hasRenderCallback(void) 
00462 {
00463     switch(m_shadingMode)
00464     {
00465         case SM_REGISTER_COMBINERS_MULTI2D:
00466             return true;
00467 
00468         case SM_FRAGMENT_PROGRAM_2D:
00469             return true;
00470 
00471         default:
00472             break;
00473     }
00474 
00475     return false;
00476 }
00477 
00478 
00479 // Indicate whether slices should be multitextured or not
00480 bool DVRIsoShader::useMTSlabs(void)
00481 {
00482     switch(m_shadingMode)
00483     {
00484         case SM_REGISTER_COMBINERS_MULTI2D:
00485             return true;
00486 
00487         case SM_FRAGMENT_PROGRAM_2D:
00488             return true;
00489 
00490         default:
00491             break;
00492     }
00493 
00494     return false;
00495 }
00496 
00497 
00498 // Compute gradients from a 3D volume
00499 ImagePtr DVRIsoShader::createGradientImage(DVRVolumeTexturePtr volTex)
00500 { 
00501     int resX = (int) volTex->getImage()->getWidth(); 
00502     int resY = (int) volTex->getImage()->getHeight(); 
00503     int resZ = (int) volTex->getImage()->getDepth(); 
00504     
00505     int nGradSetSize =   resX * resY * resZ * 4; 
00506     int zOff         =   resX * resY; 
00507     int yOff         =   resX;
00508     
00509     
00510     //  Compute the Gradients  
00511     UChar8 *volData = volTex->getImage()->getData();
00512   
00513     UChar8 *gradbuffer = new UChar8[nGradSetSize];  
00514 
00515     Vec3f gradient;
00516 
00517     for(int z = 0 ; z < resZ ; z++) 
00518     { 
00519         for(int y = 0 ; y < resY ; y++) 
00520         { 
00521             for(int x = 0 ; x < resX ; x++) 
00522             { 
00523                 
00524                 if(x == 0)
00525                 {
00526                     gradient = Vec3f(-1.0, 0.0, 0.0);
00527                 } 
00528                 else if (x == resX-1) 
00529                 {
00530                     gradient = Vec3f( 1.0, 0.0, 0.0);
00531                 } 
00532                 else if (y == 0) 
00533                 {
00534                     gradient = Vec3f(0.0, -1.0, 0.0);
00535                 }
00536                 else if (y == resY-1) 
00537                 {
00538                     gradient = Vec3f(0.0,  1.0, 0.0);
00539                 } 
00540                 else if (z == 0) 
00541                 {
00542                     gradient = Vec3f(0.0, 0.0, -1.0);
00543                 } else if (z == resZ-1) 
00544                 {
00545                     gradient = Vec3f(0.0, 0.0,  1.0);
00546                 } 
00547                 else 
00548                 {
00549                     UChar8 &dataXl = 
00550                         volData[z      * zOff +  y      * yOff + x - 1]; 
00551 
00552                     UChar8 &dataXr = 
00553                         volData[z      * zOff +  y      * yOff + x + 1]; 
00554 
00555                     UChar8 &dataYb = 
00556                         volData[z      * zOff + (y - 1) * yOff + x    ]; 
00557 
00558                     UChar8 &dataYt = 
00559                         volData[z      * zOff + (y + 1) * yOff + x    ]; 
00560 
00561                     UChar8 &dataZf = 
00562                         volData[(z - 1) * zOff +  y      * yOff + x    ]; 
00563 
00564                     UChar8 &dataZn = 
00565                         volData[(z + 1) * zOff +  y      * yOff + x    ]; 
00566                     
00567                     gradient = Vec3f((float)(dataXl - dataXr), 
00568                                      (float)(dataYb - dataYt), 
00569                                      (float)(dataZf - dataZn));  
00570 
00571                     if(gradient.length() != 0.0)
00572                         gradient.normalize(); 
00573                     
00574                 } 
00575         
00576                 gradbuffer[4 * (z * zOff + y * yOff + x)  ] 
00577                     = (UChar8) (127.0 + gradient[0] * 127.0); // R 
00578 
00579                 gradbuffer[4 * (z * zOff + y * yOff + x) + 1] 
00580                     = (UChar8) (127.0 + gradient[1] * 127.0); // G 
00581 
00582                 gradbuffer[4 * (z * zOff + y * yOff + x) + 2] 
00583                     = (UChar8) (127.0 + gradient[2] * 127.0); // B 
00584 
00585                 gradbuffer[4 * (z * zOff + y * yOff + x) + 3] 
00586                     = volData[z * zOff +  y    * yOff + x  ]; // A 
00587 
00588             } // for x 
00589             
00590         } // for y 
00591         
00592     } // for z 
00593     
00594     ImagePtr m_gradientImage = Image::create();
00595 
00596     m_gradientImage->set(Image::OSG_RGBA_PF,
00597                          resX, 
00598                          resY, 
00599                          resZ,
00600                          1, 
00601                          1, 
00602                          0.0, 
00603                          gradbuffer);
00604 
00605     delete [] gradbuffer;
00606     
00607     return m_gradientImage;
00608 }
00609 
00610 // get currently active lightsources from OpenGL state
00611 // should be changed as soon as OpenSG actions can handle this
00612 void DVRIsoShader::getLightSources(DirLightList &diffuseLights,
00613                                    DirLightList &specularLights,
00614                                    Color4f      &ambientLight   )
00615 {
00616     ambientLight  .clear();
00617     diffuseLights .clear();
00618     specularLights.clear();
00619 
00620     GLint maxNumLights;
00621 
00622     glGetIntegerv(GL_MAX_LIGHTS, &maxNumLights);
00623 
00624     GLfloat  lightPos     [4];
00625     GLfloat  diffuseColor [4];
00626     GLfloat  specularColor[4];
00627     GLfloat  ambientColor [4];  
00628 
00629     for(int i = 0; i < maxNumLights; i++) 
00630     {
00631         if(glIsEnabled(GLenum(GL_LIGHT0 + i)))
00632         {
00633             glGetLightfv(GLenum(GL_LIGHT0 + i), GL_POSITION, lightPos     );
00634             glGetLightfv(GLenum(GL_LIGHT0 + i), GL_AMBIENT,  ambientColor );
00635             glGetLightfv(GLenum(GL_LIGHT0 + i), GL_DIFFUSE,  diffuseColor );
00636             glGetLightfv(GLenum(GL_LIGHT0 + i), GL_SPECULAR, specularColor);
00637             
00638             //      SLOG << "LightSource: " << i << " enabled" << std::endl;
00639 
00640             // check for directional light
00641             // homogenous coordinate = 0 -> infinity !
00642             if(1.0 ==  lightPos[3] + 1.0) 
00643             { 
00644                 DirLight light;
00645                 
00646                 // set global light direction
00647                 light.dir.setValues(lightPos[0],lightPos[1],lightPos[2]);
00648                 
00649                 // SLOG << "Pos: " << i << " :" << light.dir << std::endl;
00650                 
00651                 // diffuse
00652                 if(diffuseColor[0] > 1e-6 || 
00653                    diffuseColor[1] > 1e-6 || 
00654                    diffuseColor[2] > 1e-6)
00655                 {
00656                     light.color = Color4f(diffuseColor[0],
00657                                           diffuseColor[1],
00658                                           diffuseColor[2],
00659                                           0.0f);
00660 
00661                     diffuseLights.push_back(light);
00662                 }
00663                 
00664                 // specular
00665                 if(specularColor[0] > 1e-6 || 
00666                    specularColor[1] > 1e-6 || 
00667                    specularColor[2] > 1e-6)
00668                 {
00669                     light.color = Color4f(specularColor[0],
00670                                           specularColor[1],
00671                                           specularColor[2],
00672                                           0.0f);
00673 
00674                     specularLights.push_back(light);
00675                 }
00676                 
00677                 // ambient
00678                 for(unsigned int i = 0; i < 4; i++)
00679                 {
00680                     ambientLight[i] += ambientColor[i];
00681                 }
00682             }
00683         }
00684     }
00685     
00686     // global ambient
00687     glGetFloatv(GL_LIGHT_MODEL_AMBIENT,ambientColor);
00688 
00689     for(unsigned int i = 0; i < 4; i++)
00690     {
00691         ambientLight[i] += ambientColor[i];
00692     }
00693 }
00694 
00695 // check if current OpenGL version is greater or equal to the given version
00696 // Note: only the major and the minor version is checked!!
00697 bool DVRIsoShader::checkGLVersion(GLfloat minVersion)
00698 {
00699     char *versionString = (char*) glGetString(GL_VERSION);
00700 
00701     if(atof(versionString) >= minVersion)
00702         return true;
00703     else
00704         return false;
00705 }
00706 
00707 
00709 UInt8 DVRIsoShader::selectMode(DVRVolume *volume, DrawActionBase *action)
00710 {
00711     if(isModeSupported(volume, action, SM_FRAGMENT_PROGRAM_3D))
00712     { 
00713         FINFO(("DVRIsoShader - Autoselect: Using 3D textures and "
00714                "fragment program...\n"));
00715 
00716         return SM_FRAGMENT_PROGRAM_3D;
00717     }
00718 
00719     if(isModeSupported(volume, action, SM_FRAGMENT_PROGRAM_2D))
00720     { 
00721         FINFO(("DVRIsoShader - Autoselect: Using 2D textures and "
00722                "fragment program...\n"));
00723 
00724         return SM_FRAGMENT_PROGRAM_2D;
00725     }
00726 
00727     if(isModeSupported(volume, action, SM_REGISTER_COMBINERS_3D))
00728     { 
00729         FINFO(("DVRIsoShader - Autoselect: Using 3D textures and "
00730                "register combiners...\n"));
00731         
00732         return SM_REGISTER_COMBINERS_3D;
00733     }
00734 
00735     if(isModeSupported(volume, action, SM_REGISTER_COMBINERS_MULTI2D))
00736     {
00737         FINFO(("DVRIsoShader - Autoselect: Using 2D multi textures and "
00738                "register combiners...\n"));
00739         
00740         return SM_REGISTER_COMBINERS_MULTI2D;
00741     }
00742 
00743     if(isModeSupported(volume, action, SM_REGISTER_COMBINERS_2D))
00744     { 
00745         FINFO(("DVRIsoShader - Autoselect: Using 2D textures and "
00746                "register combiners...\n"));
00747 
00748         return SM_REGISTER_COMBINERS_2D;
00749     }
00750     
00751     if(isModeSupported(volume, action, SM_COLORMATRIX_3D))
00752     {
00753         FINFO(("DVRIsoShader - Autoselect: Using 3D textures and "
00754                "color matrix...\n"));
00755 
00756         return SM_COLORMATRIX_3D;
00757     }
00758 
00759     if(isModeSupported(volume, action, SM_COLORMATRIX_2D))
00760     {
00761         FINFO(("DVRIsoShader - Autoselect: Using 2D textures and "
00762                "color matrix...\n"));
00763 
00764         return SM_COLORMATRIX_2D;
00765     }
00766     
00767     SWARNING << "DVRIsoShader - None of the implemented shading algorithms"
00768              <<std::endl
00769              <<"is supported by this hardware!"
00770              <<std::endl;
00771 
00772     return SM_NONE;
00773 }
00774 
00776 bool DVRIsoShader::isModeSupported(DVRVolume      *volume, 
00777                                    DrawActionBase *action, 
00778                                    UInt8           mode  )
00779 { 
00780     Window *win = action->getWindow();
00781     
00782     if(!win)
00783     {
00784         SWARNING << "DVRIsoShader - No valid window" << std::endl;
00785         return false;
00786     }
00787 
00788     GLint numStencil;
00789     bool  forceTexture2D = false;
00790     bool  forceTexture3D = false;
00791 
00792     if(volume->getTextures2D() == 1)
00793     {
00794         forceTexture2D = true;
00795         SLOG << "DVRIsoShader - 2D textures forced" << std::endl;
00796     }
00797     else if(volume->getTextures2D() == 0)
00798     {
00799         forceTexture3D = true;
00800         SLOG << "DVRIsoShader - 3D textures forced" << std::endl;
00801     }
00802     
00803     switch(mode) 
00804     {
00805         case SM_COLORMATRIX_2D:
00806             glGetIntegerv(GL_STENCIL_BITS, &numStencil);
00807 
00808             return 
00809                 numStencil > 0                           && 
00810                 (win->hasExtension(_SGI_color_matrix) || 
00811                  checkGLVersion(1.2)                   ) && 
00812                 !forceTexture3D;
00813 
00814         case SM_COLORMATRIX_3D:
00815             glGetIntegerv(GL_STENCIL_BITS,&numStencil);
00816 
00817             return 
00818                 numStencil > 0                          && 
00819                 win->hasExtension(_EXT_texture3D)       && 
00820                 (win->hasExtension(_SGI_color_matrix) || 
00821                  checkGLVersion(1.2)                   ) && 
00822                 !forceTexture2D;
00823 
00824         case SM_REGISTER_COMBINERS_2D:
00825             return 
00826                 win->hasExtension(_NV_register_combiners) && !forceTexture3D;
00827 
00828         case SM_REGISTER_COMBINERS_MULTI2D:
00829             return 
00830                 win->hasExtension(_ARB_multitexture     ) && 
00831                 win->hasExtension(_NV_register_combiners) && 
00832                 !forceTexture3D;
00833 
00834         case SM_REGISTER_COMBINERS_3D:
00835             return 
00836                 win->hasExtension(_EXT_texture3D        ) && 
00837                 win->hasExtension(_NV_register_combiners) && 
00838                 !forceTexture2D;
00839 
00840         case SM_FRAGMENT_PROGRAM_2D:
00841             return 
00842                 win->hasExtension(_ARB_multitexture    ) && 
00843                 win->hasExtension(_ARB_fragment_program) && 
00844                 !forceTexture3D;
00845 
00846         case SM_FRAGMENT_PROGRAM_3D:
00847             return 
00848                 win->hasExtension(_EXT_texture3D       ) && 
00849                 win->hasExtension(_ARB_fragment_program) && 
00850                 !forceTexture2D;
00851 
00852         case SM_NONE:  
00853             return true;
00854 
00855         default:    
00856             break;
00857     }
00858     
00859     return false;
00860 }
00861 
00863 bool DVRIsoShader::tryMode(DVRVolume      *volume, 
00864                            DrawActionBase *action, 
00865                            UInt8           mode )
00866 {
00867     if(mode != SM_AUTO)
00868     {
00869         // A certain mode has been selected
00870         if(isModeSupported( volume, action, mode ))
00871         {
00872             SWARNING << "DVRIsoShader - User specified shading mode "
00873                      << int(mode) 
00874                      << std::endl;
00875 
00876             m_shadingMode =  mode;
00877         }
00878         else
00879         {
00880             SWARNING << "DVRIsoShader - Unsupported shading mode requested "
00881                      << int(mode)
00882                      << " disabling shading" 
00883                      << std::endl;
00884 
00885             m_shadingMode = SM_NONE;
00886         }
00887     }
00888     else 
00889     {
00890         // Use automatic mode selection
00891         m_shadingMode = selectMode(volume, action);
00892     }
00893 
00894     setActiveShadeMode(m_shadingMode);
00895     
00896     return m_shadingMode == mode;
00897 }
00898 
00899 
00900 /*-------------------------------------------------------------------------*/
00901 /*                              cvs id's                                   */
00902 
00903 #ifdef __sgi
00904 #pragma set woff 1174
00905 #endif
00906 
00907 #ifdef OSG_LINUX_ICC
00908 #pragma warning( disable : 177 )
00909 #endif
00910 
00911 namespace
00912 {
00913     static char cvsid_cpp[] = "@(#)$Id: $";
00914     static char cvsid_hpp[] = OSGDVRISOSHADER_HEADER_CVSID;
00915     static char cvsid_inl[] = OSGDVRISOSHADER_INLINE_CVSID;
00916 }

Generated on Thu Aug 25 04:03:36 2005 for OpenSG by  doxygen 1.4.3