ShaderNode.cc

00001 /*===========================================================================*\
00002  *                                                                           *
00003  *                              OpenFlipper                                  *
00004  *      Copyright (C) 2001-2009 by Computer Graphics Group, RWTH Aachen      *
00005  *                           www.openflipper.org                             *
00006  *                                                                           *
00007  *---------------------------------------------------------------------------*
00008  *  This file is part of OpenFlipper.                                        *
00009  *                                                                           *
00010  *  OpenFlipper is free software: you can redistribute it and/or modify      *
00011  *  it under the terms of the GNU Lesser General Public License as           *
00012  *  published by the Free Software Foundation, either version 3 of           *
00013  *  the License, or (at your option) any later version with the              *
00014  *  following exceptions:                                                    *
00015  *                                                                           *
00016  *  If other files instantiate templates or use macros                       *
00017  *  or inline functions from this file, or you compile this file and         *
00018  *  link it with other files to produce an executable, this file does        *
00019  *  not by itself cause the resulting executable to be covered by the        *
00020  *  GNU Lesser General Public License. This exception does not however       *
00021  *  invalidate any other reasons why the executable file might be            *
00022  *  covered by the GNU Lesser General Public License.                        *
00023  *                                                                           *
00024  *  OpenFlipper is distributed in the hope that it will be useful,           *
00025  *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
00026  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
00027  *  GNU Lesser General Public License for more details.                      *
00028  *                                                                           *
00029  *  You should have received a copy of the GNU LesserGeneral Public          *
00030  *  License along with OpenFlipper. If not,                                  *
00031  *  see <http://www.gnu.org/licenses/>.                                      *
00032  *                                                                           *
00033 \*===========================================================================*/
00034 
00035 /*===========================================================================*\
00036  *                                                                           *
00037  *   $Revision: 6743 $                                                       *
00038  *   $Author: moebius $                                                      *
00039  *   $Date: 2009-08-05 11:03:10 +0200 (Mi, 05. Aug 2009) $                   *
00040  *                                                                           *
00041 \*===========================================================================*/
00042 
00043 
00044 
00045 
00046 //=============================================================================
00047 //
00048 //  CLASS ShaderNode - IMPLEMENTATION
00049 //
00050 //=============================================================================
00051 
00052 
00053 //== INCLUDES =================================================================
00054 
00055 
00056 #include "ShaderNode.hh"
00057 #include "DrawModes.hh"
00058 #include <vector>
00059 
00060 
00061 //== NAMESPACES ===============================================================
00062 
00063 namespace ACG {
00064 namespace SceneGraph {
00065 
00066 
00067 //== IMPLEMENTATION ==========================================================
00068 
00069 
00070 ShaderNode::ShaderNode( BaseNode*            _parent,
00071                         const std::string&   _name)
00072   : BaseNode(_parent, _name),
00073     shaderDir_("")
00074 {
00075 }
00076 
00077 ShaderNode::~ShaderNode() {
00078   if ( shaderDir_ != "" ) {
00079 
00080     for (size_t i = 0; i < sizeof(unsigned int)*8 ;  ++i) {
00081       if ( shaders[i].initialized ) {
00082 
00083         if ( shaders[i].program != 0 )
00084            delete shaders[i].program;
00085 
00086          if ( shaders[i].vertexShader != 0 )
00087            delete shaders[i].vertexShader;
00088 
00089          if ( shaders[i].fragmentShader != 0 )
00090            delete shaders[i].fragmentShader;
00091       }
00092 
00093     }
00094   }
00095 }
00096 
00097 //----------------------------------------------------------------------------
00098 bool
00099 ShaderNode::
00100 hasShader( unsigned int _drawmode, bool _pick ) {
00101 
00102   unsigned int mode = _drawmode;
00103   for (size_t i = 0; i < sizeof(unsigned int)*8 ;  ++i) {
00104     if (mode & 1) {
00105       if (_pick)
00106         return pickShaders[i].initialized;
00107       else
00108         return shaders[i].initialized;
00109     }
00110 
00111     mode >>= 1;
00112   }
00113   return false;
00114 }
00115 
00116 //----------------------------------------------------------------------------
00117 
00118 
00119 void
00120 ShaderNode::enter(GLState& /*_state*/, unsigned int _drawmode  )
00121 {
00122   unsigned int mode = _drawmode;
00123   for (size_t i = 0; i < sizeof(unsigned int)*8 ;  ++i) {
00124     if (mode & 1) {
00125       if ( shaders[i].initialized ) {
00126         shaders[i].program->use();
00127       }
00128     }
00129 
00130     mode >>= 1;
00131   }
00132 }
00133 
00134 //----------------------------------------------------------------------------
00135 
00136 void
00137 ShaderNode::enterPick(GLState& /*_state*/, PickTarget /*_target*/, unsigned int _drawmode  )
00138 {
00139   unsigned int mode = _drawmode;
00140   for (size_t i = 0; i < sizeof(unsigned int)*8 ;  ++i) {
00141     if (mode & 1) {
00142       if ( pickShaders[i].initialized ) {
00143         pickShaders[i].program->use();
00144      }
00145     }
00146 
00147     mode >>= 1;
00148   }
00149 }
00150 
00151 //----------------------------------------------------------------------------
00152 std::string
00153 ShaderNode::vertexShaderName(unsigned int _drawmode, bool _pick) {
00154   unsigned int mode = _drawmode;
00155   for (size_t i = 0; i < sizeof(unsigned int)*8 ;  ++i) {
00156     if (mode & 1) {
00157       if (_pick)
00158       {
00159         if ( pickShaders[i].initialized ) {
00160           return pickShaders[i].vertexShaderFile;
00161         }
00162       }
00163       else
00164       {
00165         if ( shaders[i].initialized ) {
00166           return shaders[i].vertexShaderFile;
00167         }
00168       }
00169     }
00170 
00171     mode >>= 1;
00172   }
00173 
00174   return std::string("");
00175 }
00176 
00177 //----------------------------------------------------------------------------
00178 std::string
00179 ShaderNode::fragmentShaderName(unsigned int _drawmode, bool _pick) {
00180   unsigned int mode = _drawmode;
00181   for (size_t i = 0; i < sizeof(unsigned int)*8 ;  ++i) {
00182     if (mode & 1) {
00183       if (_pick)
00184       {
00185         if ( pickShaders[i].initialized ) {
00186           return pickShaders[i].fragmentShaderFile;
00187         }
00188       }
00189       else
00190       {
00191         if ( shaders[i].initialized ) {
00192           return shaders[i].fragmentShaderFile;
00193         }
00194       }
00195     }
00196 
00197     mode >>= 1;
00198   }
00199 
00200   return std::string("");
00201 }
00202 
00203 
00204 //----------------------------------------------------------------------------
00205 
00206 
00207 void ShaderNode::leave(GLState& /*_state*/, unsigned int _drawmode )
00208 {
00209   unsigned int mode = _drawmode;
00210   for (size_t i = 0; i < sizeof(unsigned int)*8 ;  ++i) {
00211     if (mode & 1) {
00212       if ( shaders[i].initialized ) {
00213         shaders[i].program->disable();
00214       }
00215     }
00216 
00217     mode >>= 1;
00218   }
00219 }
00220 
00221 //----------------------------------------------------------------------------
00222 
00223 
00224 void ShaderNode::leavePick(GLState& /*_state*/, PickTarget /*_target*/, unsigned int _drawmode )
00225 {
00226   unsigned int mode = _drawmode;
00227   for (size_t i = 0; i < sizeof(unsigned int)*8 ;  ++i) {
00228     if (mode & 1) {
00229       if ( pickShaders[i].initialized ) {
00230         pickShaders[i].program->disable();
00231       }
00232     }
00233 
00234     mode >>= 1;
00235   }
00236 }
00237 
00238 //----------------------------------------------------------------------------
00239 
00241 GLSL::PtrProgram
00242 ShaderNode::
00243 getShader( unsigned int _drawmode, bool _pick ) {
00244   unsigned int mode = _drawmode;
00245   for (size_t i = 0; i < sizeof(unsigned int)*8 ;  ++i) {
00246     if (mode & 1) {
00247       if (_pick)
00248       {
00249         if ( pickShaders[i].initialized ) {
00250           return pickShaders[i].program;
00251         }
00252       }
00253       else
00254       {
00255         if ( shaders[i].initialized ) {
00256           return shaders[i].program;
00257         }
00258       }
00259     }
00260 
00261     mode >>= 1;
00262 
00263   }
00264 
00265   // No shader found for this mode
00266   return 0;
00267 }
00268 
00269 //----------------------------------------------------------------------------
00270 
00271 
00272 void
00273 ShaderNode::
00274 setShader( unsigned int _drawmode ,
00275            std::string _vertexShader,
00276            std::string _fragmentShader,
00277            std::string _pickVertexShader,
00278            std::string _pickFragmentShader) {
00279 
00280   // OpenGl 2.0 is needed for GLSL support
00281   if (!glewIsSupported("GL_VERSION_2_0")) {
00282     std::cerr << "No shader support... unable to load shaders!" << std::endl;
00283     return;
00284 
00285   }
00286 
00287   if ( shaderDir_ == "" ) {
00288     std::cerr << "No shader dir set for shadernode! Unable to load shaders" << std::endl;
00289     return;
00290   }
00291 
00292   unsigned int mode = _drawmode;
00293   for (size_t i = 0; i < sizeof(unsigned int)*8 ;  ++i) {
00294 
00295     if (mode & 1) {
00296 
00297       if ( shaders[i].initialized ) {
00298         if ( shaders[i].program != 0 )
00299            delete shaders[i].program;
00300 
00301          if ( shaders[i].vertexShader != 0 )
00302            delete shaders[i].vertexShader;
00303 
00304          if ( shaders[i].fragmentShader != 0 )
00305            delete shaders[i].fragmentShader;
00306 
00307          shaders[i].initialized    = false;
00308       }
00309 
00310       shaders[i].vertexShaderFile   = shaderDir_ + _vertexShader;
00311       shaders[i].fragmentShaderFile = shaderDir_ + _fragmentShader;
00312 
00313       const char* vertexShaderFilePath   = shaders[i].vertexShaderFile.c_str();
00314       const char* fragmentShaderFilePath = shaders[i].fragmentShaderFile.c_str();
00315       shaders[i].vertexShader            = GLSL::loadVertexShader(vertexShaderFilePath);
00316       shaders[i].fragmentShader          = GLSL::loadFragmentShader(fragmentShaderFilePath);
00317       shaders[i].program                 = GLSL::PtrProgram(new GLSL::Program());
00318 
00319       if ( (shaders[i].vertexShader == 0) ||
00320            (shaders[i].fragmentShader == 0) ||
00321            (shaders[i].program == 0) ) {
00322         std::cerr << "Unable to load shaders" << shaders[i].vertexShaderFile <<
00323                      " or " << shaders[i].fragmentShaderFile << std::endl;
00324         shaders[i].vertexShader   = 0;
00325         shaders[i].fragmentShader = 0;
00326         shaders[i].program        = 0;
00327         shaders[i].initialized    = false;
00328         return;
00329       }
00330 
00331       shaders[i].program->attach(shaders[i].vertexShader);
00332       shaders[i].program->attach(shaders[i].fragmentShader);
00333       shaders[i].program->link();
00334 
00335       shaders[i].initialized = true;
00336 
00337       if ( pickShaders[i].initialized ) {
00338         if ( pickShaders[i].program != 0 )
00339            delete pickShaders[i].program;
00340 
00341          if ( pickShaders[i].vertexShader != 0 )
00342            delete pickShaders[i].vertexShader;
00343 
00344          if ( pickShaders[i].fragmentShader != 0 )
00345            delete pickShaders[i].fragmentShader;
00346 
00347          pickShaders[i].initialized    = false;
00348       }
00349 
00350       if (_pickVertexShader.length () > 0 && _pickFragmentShader.length () > 0)
00351       {
00352         pickShaders[i].vertexShaderFile   = shaderDir_ + _pickVertexShader;
00353         pickShaders[i].fragmentShaderFile = shaderDir_ + _pickFragmentShader;
00354 
00355         const char* vertexShaderFilePath   = pickShaders[i].vertexShaderFile.c_str();
00356         const char* fragmentShaderFilePath = pickShaders[i].fragmentShaderFile.c_str();
00357         pickShaders[i].vertexShader        = GLSL::loadVertexShader(vertexShaderFilePath);
00358         pickShaders[i].fragmentShader      = GLSL::loadFragmentShader(fragmentShaderFilePath);
00359         pickShaders[i].program             = GLSL::PtrProgram(new GLSL::Program());
00360 
00361         if ( (pickShaders[i].vertexShader == 0) ||
00362              (pickShaders[i].fragmentShader == 0) ||
00363              (pickShaders[i].program == 0) ) {
00364           std::cerr << "Unable to load pick shaders" << pickShaders[i].vertexShaderFile <<
00365                        " or " << pickShaders[i].fragmentShaderFile << std::endl;
00366           pickShaders[i].vertexShader   = 0;
00367           pickShaders[i].fragmentShader = 0;
00368           pickShaders[i].program        = 0;
00369           pickShaders[i].initialized    = false;
00370           return;
00371         }
00372 
00373         pickShaders[i].program->attach(pickShaders[i].vertexShader);
00374         pickShaders[i].program->attach(pickShaders[i].fragmentShader);
00375         pickShaders[i].program->link();
00376 
00377         pickShaders[i].initialized = true;
00378       }
00379     }
00380 
00381     mode >>= 1;
00382   }
00383 
00384 }
00385 
00386 //----------------------------------------------------------------------------
00387 
00388 void
00389 ShaderNode::
00390 setShaderDir( std::string _shaderDir) {
00391   shaderDir_ = _shaderDir;
00392 }
00393 
00394 unsigned int
00395 ShaderNode::
00396 availableDrawModes() const
00397 {
00398 
00399   unsigned int drawModes(0);
00400 
00401   drawModes |= DrawModes::SOLID_PHONG_SHADED;
00402   drawModes |= DrawModes::SOLID_SHADER;
00403 
00404   return drawModes;
00405 
00406 }
00407 
00408 //=============================================================================
00409 } // namespace SceneGraph
00410 } // namespace ACG
00411 //=============================================================================

acg pic Project OpenFlipper, ©  Computer Graphics Group, RWTH Aachen. Documentation generated using doxygen .