rawVolModelRenderer.cpp

00001 
00002 /* Copyright (c) 2007       Maxim Makhinya
00003  *
00004  * This library is free software; you can redistribute it and/or modify it under
00005  * the terms of the GNU Lesser General Public License version 2.1 as published
00006  * by the Free Software Foundation.
00007  *  
00008  * This library is distributed in the hope that it will be useful, but WITHOUT
00009  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00010  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00011  * details.
00012  * 
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this library; if not, write to the Free Software Foundation, Inc.,
00015  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00016  */
00017 
00018 #include "rawVolModelRenderer.h"
00019 
00020 #include "fragmentShader_glsl.h"
00021 #include "vertexShader_glsl.h"
00022 
00023 
00024 namespace eVolve
00025 {
00026 
00027 
00028 RawVolumeModelRenderer::RawVolumeModelRenderer( const std::string& filename, 
00029                                                 const uint32_t     precision )
00030         : _rawModel(  filename  )
00031         , _precision( precision )
00032         , _glewContext( 0 )
00033         , _ortho( false )
00034 {
00035 }
00036 
00037 
00038 static void renderSlices( const SliceClipper& sliceClipper )
00039 {
00040     int numberOfSlices = static_cast<int>( 3.6 / sliceClipper.sliceDistance );
00041 
00042     for( int s = 0; s < numberOfSlices; ++s )
00043     {
00044         glBegin( GL_POLYGON );
00045         for( int i = 0; i < 6; ++i )
00046         {
00047             eq::Vector3f pos =
00048                     sliceClipper.getPosition( i, numberOfSlices-1-s );
00049 
00050             glVertex4f( pos.x(), pos.y(), pos.z(), 1.0 );
00051         }
00052         glEnd();
00053     }
00054 }
00055 
00056 
00057 void RawVolumeModelRenderer::_putVolumeDataToShader
00058 (
00059     const VolumeInfo&     volumeInfo,
00060     const double          sliceDistance,
00061     const eq::Matrix4f& invRotationM
00062 )
00063 {
00064     EQASSERT( _glewContext );
00065 
00066     GLhandleARB shader = _shaders.getProgram();
00067     EQASSERT( shader );
00068 
00069     const DataInTextureDimensions& TD = volumeInfo.TD; 
00070 
00071     GLint tParamNameGL;
00072 
00073     // Put texture coordinates modifyers to the shader
00074     tParamNameGL = glGetUniformLocationARB( shader, "W"  );
00075     glUniform1fARB( tParamNameGL, TD.W );
00076 
00077     tParamNameGL = glGetUniformLocationARB( shader, "H"  );
00078     glUniform1fARB( tParamNameGL, TD.H );
00079 
00080     tParamNameGL = glGetUniformLocationARB( shader, "D"  );
00081     glUniform1fARB( tParamNameGL, TD.D  );
00082 
00083     tParamNameGL = glGetUniformLocationARB( shader, "Do" );
00084     glUniform1fARB( tParamNameGL, TD.Do );
00085 
00086     tParamNameGL = glGetUniformLocationARB( shader, "Db" );
00087     glUniform1fARB( tParamNameGL, TD.Db );
00088 
00089     // Put Volume data to the shader
00090     glActiveTextureARB( GL_TEXTURE1 );
00091     glBindTexture( GL_TEXTURE_2D, volumeInfo.preint ); //preintegrated values
00092     tParamNameGL = glGetUniformLocationARB( shader, "preInt" );
00093     glUniform1iARB( tParamNameGL,  1    ); //f-shader
00094 
00095     // Activate last because it has to be the active texture
00096     glActiveTextureARB( GL_TEXTURE0 );
00097     glBindTexture( GL_TEXTURE_3D, volumeInfo.volume ); //gx, gy, gz, val
00098     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER,GL_LINEAR    );
00099 
00100     tParamNameGL = glGetUniformLocationARB(  shader,  "volume"        );
00101     glUniform1iARB( tParamNameGL ,  0            ); //f-shader
00102 
00103     tParamNameGL = glGetUniformLocationARB(  shader,  "sliceDistance" );
00104     glUniform1fARB( tParamNameGL,  sliceDistance ); //v-shader
00105 
00106     tParamNameGL = glGetUniformLocationARB(  shader,  "perspProj" );
00107     glUniform1fARB( tParamNameGL,  _ortho ? 0.0 : 1.0 ); //v-shader
00108 
00109     tParamNameGL = glGetUniformLocationARB(  shader,  "shininess"     );
00110     glUniform1fARB( tParamNameGL,  8.0f         ); //f-shader
00111 
00112     // rotate viewPosition in the oposite direction of model rotation
00113     // to keep light position constant but not recalculate normals 
00114     // in the fragment shader
00115     // viewPosition = invRotationM * eq::Vector4f( 0, 0, 1, 0 );
00116     tParamNameGL = glGetUniformLocationARB(  shader,  "viewVec"       );
00117     glUniform3fARB( tParamNameGL, invRotationM.array[8],
00118                                   invRotationM.array[9],
00119                                   invRotationM.array[10] ); //f-shader
00120 }
00121 
00122 
00123 bool RawVolumeModelRenderer::render
00124 (
00125     const eq::Range&        range,
00126     const eq::Matrix4d&   modelviewM,
00127     const eq::Matrix3d&   modelviewITM,
00128     const eq::Matrix4f&   invRotationM
00129 )
00130 {
00131     VolumeInfo volumeInfo;
00132 
00133     if( !_rawModel.getVolumeInfo( volumeInfo, range ))
00134     {
00135         EQERROR << "Can't get volume data" << std::endl;
00136         return false;
00137     }
00138 
00139     glScalef( volumeInfo.volScaling.W,
00140               volumeInfo.volScaling.H,
00141               volumeInfo.volScaling.D );
00142 
00143     // Enable shaders
00144     glUseProgramObjectARB( _shaders.getProgram( ));
00145 
00146     // Calculate and put necessary data to shaders 
00147 
00148     const uint32_t resolution    = _rawModel.getResolution();
00149     const double   sliceDistance = 3.6 / ( resolution * _precision );
00150 
00151     _putVolumeDataToShader( volumeInfo, sliceDistance, invRotationM );
00152 
00153     _sliceClipper.updatePerFrameInfo( modelviewM, modelviewITM,
00154                                       sliceDistance, range );
00155 
00156     //Render slices
00157     glEnable( GL_BLEND );
00158     glBlendFuncSeparateEXT( GL_ONE, GL_SRC_ALPHA, GL_ZERO, GL_SRC_ALPHA );
00159 
00160     renderSlices( _sliceClipper );
00161 
00162     glDisable( GL_BLEND );
00163 
00164     // Disable shader
00165     glUseProgramObjectARB( 0 );
00166 
00167     return true;
00168 }
00169 
00170 
00171 bool RawVolumeModelRenderer::loadShaders()
00172 {
00173     if( !_shaders.loadShaders( vertexShader_glsl, fragmentShader_glsl,
00174                                _glewContext ))
00175     {
00176         EQERROR << "Can't load glsl shaders" << std::endl;
00177         return false;
00178     }
00179 
00180     EQLOG( eq::LOG_CUSTOM ) << "glsl shaders loaded" << std::endl;
00181     return true;
00182 }
00183 }
00184 
00185 
Generated on Mon Aug 10 18:58:41 2009 for Equalizer 0.9 by  doxygen 1.5.8