# Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics

[Home] [Tutorials] [All Classes] [Grouped Classes]

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/VL/BuildSystem/VL_DISTRO/Visualization_Library_SDK/src/vlGraphics/GLSL.cpp

Go to the documentation of this file.

    00001 /**************************************************************************************/
    00002 /*                                                                                    */
    00003 /*  Visualization Library                                                             */
    00004 /*  http://www.visualizationlibrary.com                                               */
    00005 /*                                                                                    */
    00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
    00007 /*  All rights reserved.                                                              */
    00008 /*                                                                                    */
    00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
    00010 /*  are permitted provided that the following conditions are met:                     */
    00011 /*                                                                                    */
    00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
    00013 /*  list of conditions and the following disclaimer.                                  */
    00014 /*                                                                                    */
    00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
    00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
    00017 /*  other materials provided with the distribution.                                   */
    00018 /*                                                                                    */
    00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
    00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
    00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
    00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
    00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
    00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
    00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
    00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
    00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
    00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
    00029 /*                                                                                    */
    00030 /**************************************************************************************/
    00031
    00032 #include <vlGraphics/GLSL.hpp>
    00033 #include <vlGraphics/OpenGL.hpp>
    00034 #include <vlCore/VLSettings.hpp>
    00035 #include <vlCore/VirtualFile.hpp>
    00036 #include <vlCore/Log.hpp>
    00037 #include <vlCore/Say.hpp>
    00038
    00039 using namespace vl;
    00040
    00041 //-----------------------------------------------------------------------------
    00042 // GLSLShader
    00043 //-----------------------------------------------------------------------------
    00044 GLSLShader::GLSLShader(EShaderType type, const String& source)
    00045 {
    00046   VL_DEBUG_SET_OBJECT_NAME()
    00047   mType = type;
    00048   mHandle = 0;
    00049   mCompiled = false;
    00050   setSource(source);
    00051 }
    00052 //-----------------------------------------------------------------------------
    00053 GLSLShader::~GLSLShader()
    00054 {
    00055   deleteShader();
    00056 }
    00057 //-----------------------------------------------------------------------------
    00058 void GLSLShader::setSource( const String& source )
    00059 {
    00060   std::string new_src = "ERROR";
    00061
    00062   if (vl::locateFile(source))
    00063   {
    00064     new_src = vl::String::loadText(source).toStdString();
    00065     setObjectName( source.toStdString() );
    00066   }
    00067   else
    00068   {
    00069     int cn = source.count('\n');
    00070     int cr = source.count('\r');
    00071     int cf = source.count('\f');
    00072     int line_count = vl::max( vl::max( cn, cr ), cf );
    00073     if(line_count == 0)
    00074     {
    00075       Log::error("GLSLShader::setSource('" + source + "') error: file not found!\n");
    00076       mSource = "";
    00077       VL_TRAP();
    00078     }
    00079     else
    00080       new_src = source.toStdString();
    00081   }
    00082
    00083   // update only if the source is actually different
    00084   if (new_src != "ERROR" && new_src != mSource)
    00085   {
    00086     mSource = new_src;
    00087     mCompiled = false;
    00088   }
    00089 }
    00090 //-----------------------------------------------------------------------------
    00091 bool GLSLShader::compile()
    00092 {
    00093   VL_CHECK_OGL();
    00094   VL_CHECK( GLEW_Has_Shading_Language_20 )
    00095   if( !GLEW_Has_Shading_Language_20 )
    00096     return false;
    00097
    00098   if (mSource.empty())
    00099   {
    00100     Log::error("GLSLShader::compile() failed: shader source is empty!\n");
    00101     VL_TRAP();
    00102     return false;
    00103   }
    00104
    00105   if (!mCompiled)
    00106   {
    00107     // compile the shader
    00108
    00109     if (!handle())
    00110     {
    00111       // createShader();
    00112       mHandle = glCreateShader(mType);
    00113     }
    00114
    00115     // assign sources
    00116
    00117     const GLchar* source[] = { mSource.c_str() };
    00118     glShaderSource(handle(), 1, source, NULL);
    00119
    00120     // compile the shader
    00121
    00122     glCompileShader(handle());
    00123
    00124     if ( compileStatus() )
    00125     {
    00126       mCompiled = true;
    00127       #ifndef NDEBUG
    00128         String log = infoLog();
    00129         if (!log.empty())
    00130           Log::warning( Say("%s\n%s\n\n") << objectName().c_str() << log );
    00131       #endif
    00132     }
    00133     else
    00134     {
    00135       Log::bug( Say("\nGLSLShader::compile() failed! '%s':\n\n") << objectName().c_str() );
    00136       // Log::bug( Say("Source:\n%s\n\n") << mSource.c_str() );
    00137       Log::bug( Say("Info log:\n%s\n\n") << infoLog() );
    00138       VL_TRAP()
    00139     }
    00140   }
    00141
    00142   VL_CHECK_OGL();
    00143   return mCompiled;
    00144 }
    00145 //-----------------------------------------------------------------------------
    00146 bool GLSLShader::compileStatus() const
    00147 {
    00148   VL_CHECK_OGL();
    00149   VL_CHECK( GLEW_Has_Shading_Language_20 )
    00150   if( !GLEW_Has_Shading_Language_20 )
    00151     return false;
    00152   VL_CHECK(handle())
    00153
    00154   int status = 0;
    00155   glGetShaderiv(handle(), GL_COMPILE_STATUS, &status); VL_CHECK_OGL();
    00156   return status == GL_TRUE;
    00157 }
    00158 //-----------------------------------------------------------------------------
    00159 String GLSLShader::infoLog() const
    00160 {
    00161   VL_CHECK_OGL();
    00162   VL_CHECK( GLEW_Has_Shading_Language_20 )
    00163   if( !GLEW_Has_Shading_Language_20 )
    00164     return "OpenGL Shading Language not supported.\n";
    00165   VL_CHECK(handle())
    00166
    00167   int max_length = 0;
    00168   glGetShaderiv(handle(), GL_INFO_LOG_LENGTH, &max_length); VL_CHECK_OGL();
    00169   if (max_length != 0)
    00170   {
    00171     std::vector<GLchar> log_buffer;
    00172     log_buffer.resize(max_length);
    00173     glGetShaderInfoLog(handle(), max_length, NULL, &log_buffer[0]); VL_CHECK_OGL();
    00174     VL_CHECK_OGL();
    00175     return &log_buffer[0];
    00176   }
    00177   else
    00178     return String();
    00179 }
    00180 //-----------------------------------------------------------------------------
    00181 void GLSLShader::createShader()
    00182 {
    00183   VL_CHECK_OGL();
    00184   VL_CHECK( GLEW_Has_Shading_Language_20 )
    00185   if( !GLEW_Has_Shading_Language_20 )
    00186     return;
    00187   if (!handle())
    00188   {
    00189     mHandle = glCreateShader(mType);
    00190     mCompiled = false;
    00191   }
    00192   VL_CHECK(handle());
    00193   VL_CHECK_OGL();
    00194 }
    00195 //------------------------------------------------------------------------------
    00196 void GLSLShader::deleteShader()
    00197 {
    00198   // VL_CHECK_OGL();
    00199   VL_CHECK( GLEW_Has_Shading_Language_20 )
    00200   if( !GLEW_Has_Shading_Language_20 )
    00201     return;
    00202   if (handle())
    00203   {
    00204     glDeleteShader(handle()); // VL_CHECK_OGL();
    00205     mHandle = 0;
    00206     mCompiled = false;
    00207   }
    00208 }
    00209 //------------------------------------------------------------------------------
    00210 // GLSLProgram
    00211 //------------------------------------------------------------------------------
    00212 GLSLProgram::GLSLProgram()
    00213 {
    00214   VL_DEBUG_SET_OBJECT_NAME()
    00215   mScheduleLink = true;
    00216   mHandle = 0;
    00217   mGeometryVerticesOut = 0;
    00218   mGeometryInputType   = GIT_TRIANGLES;
    00219   mGeometryOutputType  = GOT_TRIANGLE_STRIP;
    00220   mProgramBinaryRetrievableHint = false;
    00221   mProgramSeparable = false;
    00222   m_vl_ModelViewMatrix = -1;
    00223   m_vl_ProjectionMatrix = -1;
    00224   m_vl_ModelViewProjectionMatrix = -1;
    00225   m_vl_NormalMatrix = -1;
    00226 }
    00227 //-----------------------------------------------------------------------------
    00228 GLSLProgram::~GLSLProgram()
    00229 {
    00230   if (handle())
    00231     deleteProgram();
    00232 }
    00233 //-----------------------------------------------------------------------------
    00234 void GLSLProgram::createProgram()
    00235 {
    00236   VL_CHECK_OGL();
    00237   VL_CHECK( GLEW_Has_Shading_Language_20 )
    00238   if( !GLEW_Has_Shading_Language_20 )
    00239     return;
    00240
    00241   if (handle() == 0)
    00242   {
    00243     scheduleRelinking();
    00244     mHandle = glCreateProgram(); VL_CHECK_OGL();
    00245     VL_CHECK(handle())
    00246   }
    00247 }
    00248 //-----------------------------------------------------------------------------
    00249 void GLSLProgram::deleteProgram()
    00250 {
    00251   // VL_CHECK_OGL();
    00252   VL_CHECK( GLEW_Has_Shading_Language_20 )
    00253   if( !GLEW_Has_Shading_Language_20 )
    00254     return;
    00255   if(handle())
    00256   {
    00257     glDeleteProgram(handle()); // VL_CHECK_OGL();
    00258     mHandle = 0;
    00259   }
    00260   scheduleRelinking();
    00261 }
    00262 //-----------------------------------------------------------------------------
    00263 bool GLSLProgram::attachShader(GLSLShader* shader)
    00264 {
    00265   VL_CHECK_OGL();
    00266   VL_CHECK( GLEW_Has_Shading_Language_20 )
    00267   if( !GLEW_Has_Shading_Language_20 )
    00268     return false;
    00269
    00270   scheduleRelinking();
    00271
    00272   #if 0
    00273     if(std::find(mShaders.begin(), mShaders.end(), shader) != mShaders.end())
    00274     {
    00275       if ( shader->handle() )
    00276         glDetachShader( handle(), shader->handle() ); VL_CHECK_OGL();
    00277     }
    00278     else
    00279       mShaders.push_back(shader);
    00280   #else
    00281     detachShader(shader);
    00282     mShaders.push_back(shader);
    00283   #endif
    00284
    00285   if ( shader->compile() )
    00286   {
    00287     createProgram();
    00288     glAttachShader( handle(), shader->handle() ); VL_CHECK_OGL();
    00289     return true;
    00290   }
    00291
    00292   VL_CHECK_OGL();
    00293   return false;
    00294
    00295 }
    00296 //-----------------------------------------------------------------------------
    00297 void GLSLProgram::detachAllShaders()
    00298 {
    00299   VL_CHECK_OGL();
    00300   for(size_t i=mShaders.size(); i--;)
    00301     detachShader(mShaders[i].get());
    00302 }
    00303 //-----------------------------------------------------------------------------
    00304 // detaching a shader that has not been attached is allowed, and is a No-Op
    00305 bool GLSLProgram::detachShader(GLSLShader* shader)
    00306 {
    00307   VL_CHECK_OGL();
    00308
    00309   VL_CHECK( GLEW_Has_Shading_Language_20 )
    00310   if( !GLEW_Has_Shading_Language_20 )
    00311     return false;
    00312
    00313   if (!handle() || !shader->handle())
    00314     return false;
    00315
    00316   // if it fails the shader has never been attached to any GLSL program
    00317   for(int i=0; i<(int)mShaders.size(); ++i)
    00318   {
    00319     if (mShaders[i] == shader)
    00320     {
    00321       if ( shader->handle() )
    00322         glDetachShader( handle(), shader->handle() ); VL_CHECK_OGL();
    00323       mShaders.erase(mShaders.begin() + i);
    00324       break;
    00325     }
    00326   }
    00327
    00328   return true;
    00329 }
    00330 //-----------------------------------------------------------------------------
    00331 void GLSLProgram::discardAllShaders()
    00332 {
    00333   VL_CHECK_OGL();
    00334   VL_CHECK( GLEW_Has_Shading_Language_20 )
    00335   if( !GLEW_Has_Shading_Language_20 )
    00336     return;
    00337
    00338   if (!handle())
    00339     return;
    00340
    00341   for(int i=0; i<(int)mShaders.size(); ++i)
    00342   {
    00343     if (mShaders[i]->handle())
    00344     {
    00345       glDetachShader( handle(), mShaders[i]->handle() ); VL_CHECK_OGL();
    00346       mShaders[i]->deleteShader();
    00347     }
    00348   }
    00349
    00350   mShaders.clear();
    00351 }
    00352 //-----------------------------------------------------------------------------
    00353 bool GLSLProgram::linkProgram(bool force_relink)
    00354 {
    00355   VL_CHECK_OGL();
    00356   VL_CHECK( GLEW_Has_Shading_Language_20 )
    00357   if( !GLEW_Has_Shading_Language_20 )
    00358     return false;
    00359
    00360   if (!linked() || force_relink)
    00361   {
    00362     if (shaderCount() == 0)
    00363     {
    00364       Log::bug("GLSLProgram::linkProgram() called on a GLSLProgram with no shaders! (" + String(objectName().c_str()) + ")\n");
    00365       VL_TRAP()
    00366       return false;
    00367     }
    00368
    00369     createProgram();
    00370
    00371     // pre-link operations
    00372     preLink();
    00373
    00374     // link the program
    00375
    00376     glLinkProgram(handle()); VL_CHECK_OGL();
    00377     mScheduleLink = !linkStatus();
    00378
    00379     // check link error
    00380     if(linked())
    00381     {
    00382       // post-link operations
    00383       postLink();
    00384
    00385       #ifndef NDEBUG
    00386         String log = infoLog();
    00387         if (!log.empty())
    00388           Log::warning( Say("%s\n%s\n\n") << objectName().c_str() << log );
    00389       #endif
    00390     }
    00391     else
    00392     {
    00393       Log::bug("GLSLProgram::linkProgram() failed! (" + String(objectName().c_str()) + ")\n");
    00394       Log::bug( Say("Info log:\n%s\n") << infoLog() );
    00395       VL_TRAP()
    00396       return false;
    00397     }
    00398   }
    00399
    00400   return true;
    00401 }
    00402 //-----------------------------------------------------------------------------
    00403 void GLSLProgram::preLink()
    00404 {
    00405   VL_CHECK_OGL();
    00406   // fragment shader color number binding
    00407
    00408   if (GLEW_EXT_gpu_shader4||GLEW_VERSION_3_0||GLEW_VERSION_4_0)
    00409   {
    00410     std::map<std::string, int>::iterator it = mFragDataLocation.begin();
    00411     while(it != mFragDataLocation.end())
    00412     {
    00413       VL_glBindFragDataLocation( handle(), it->second, it->first.c_str() ); VL_CHECK_OGL();
    00414       ++it;
    00415     }
    00416   }
    00417
    00418   // Note that OpenGL 3 and 4 do not use glProgramParameter to define the layout of the
    00419   // input/output geometry but something like this in the geometry shader:
    00420   //
    00421   // layout(triangles) in;
    00422   // layout(triangle_strip, max_vertices = 3) out;
    00423
    00424   if (GLEW_Has_Geometry_Shader && geometryVerticesOut() )
    00425   {
    00426     // if there is at least one geometry shader applies the geometry shader parameters
    00427     for(unsigned i=0; i<mShaders.size(); ++i)
    00428     {
    00429       if (mShaders[i]->type() == ST_GEOMETRY_SHADER)
    00430       {
    00431         VL_glProgramParameteri(handle(), GL_GEOMETRY_INPUT_TYPE_EXT,   geometryInputType()); VL_CHECK_OGL();
    00432         VL_glProgramParameteri(handle(), GL_GEOMETRY_OUTPUT_TYPE_EXT,  geometryOutputType()); VL_CHECK_OGL();
    00433         VL_glProgramParameteri(handle(), GL_GEOMETRY_VERTICES_OUT_EXT, geometryVerticesOut()); VL_CHECK_OGL();
    00434         break;
    00435       }
    00436     }
    00437   }
    00438
    00439   // OpenGL 4 program parameters
    00440
    00441   if(GLEW_ARB_get_program_binary)
    00442   {
    00443     VL_glProgramParameteri(handle(), GL_PROGRAM_BINARY_RETRIEVABLE_HINT, programBinaryRetrievableHint()?GL_TRUE:GL_FALSE); VL_CHECK_OGL();
    00444   }
    00445
    00446   if (GLEW_ARB_separate_shader_objects)
    00447   {
    00448     VL_glProgramParameteri(handle(), GL_PROGRAM_SEPARABLE, programSeparable()?GL_TRUE:GL_FALSE); VL_CHECK_OGL();
    00449   }
    00450
    00451   // automatically binds the specified attributes to the desired values
    00452
    00453   for( std::map<std::string, int>::iterator it = mAutoAttribLocation.begin(); it != mAutoAttribLocation.end(); ++it)
    00454   {
    00455     glBindAttribLocation(handle(),it->second,it->first.c_str()); VL_CHECK_OGL();
    00456   }
    00457 }
    00458 //-----------------------------------------------------------------------------
    00459 void GLSLProgram::postLink()
    00460 {
    00461   VL_CHECK_OGL();
    00462
    00463   // populate uniform binding map
    00464
    00465   mActiveUniformLocation.clear();
    00466
    00467   int uniform_count = 0;
    00468   glGetProgramiv(handle(), GL_ACTIVE_UNIFORMS, &uniform_count); VL_CHECK_OGL();
    00469   int uniform_len = 0;
    00470   glGetProgramiv(handle(), GL_ACTIVE_UNIFORM_MAX_LENGTH, &uniform_len); VL_CHECK_OGL();
    00471
    00472   std::vector<char> name;
    00473   name.resize(uniform_len);
    00474   if (name.size())
    00475   {
    00476     for(int i=0; i<uniform_count; ++i)
    00477     {
    00478       GLenum type;
    00479       int size;
    00480       glGetActiveUniform(handle(), i, uniform_len, NULL, &size, &type, &name[0]); VL_CHECK_OGL();
    00481       mActiveUniformLocation[&name[0]] = glGetUniformLocation(handle(), &name[0]);
    00482     }
    00483   }
    00484
    00485   // check for the predefined glsl uniform variables
    00486
    00487   m_vl_ModelViewMatrix           = glGetUniformLocation(handle(), "vl_ModelViewMatrix");
    00488   m_vl_ProjectionMatrix          = glGetUniformLocation(handle(), "vl_ProjectionMatrix");
    00489   m_vl_ModelViewProjectionMatrix = glGetUniformLocation(handle(), "vl_ModelViewProjectionMatrix");
    00490   m_vl_NormalMatrix              = glGetUniformLocation(handle(), "vl_NormalMatrix");
    00491 }
    00492 //-----------------------------------------------------------------------------
    00493 bool GLSLProgram::linkStatus() const
    00494 {
    00495   VL_CHECK_OGL();
    00496   VL_CHECK( GLEW_Has_Shading_Language_20 )
    00497   if( !GLEW_Has_Shading_Language_20 )
    00498     return false;
    00499
    00500   VL_CHECK(handle())
    00501
    00502   if (handle() == 0)
    00503     return false;
    00504
    00505   int status = 0;
    00506   glGetProgramiv(handle(), GL_LINK_STATUS, &status); VL_CHECK_OGL();
    00507   return status == GL_TRUE;
    00508 }
    00509 //-----------------------------------------------------------------------------
    00510 String GLSLProgram::infoLog() const
    00511 {
    00512   VL_CHECK_OGL();
    00513   VL_CHECK( GLEW_Has_Shading_Language_20 )
    00514   if( !GLEW_Has_Shading_Language_20 )
    00515     return "OpenGL Shading Language not supported!\n";
    00516
    00517   VL_CHECK(handle())
    00518
    00519   if (handle() == 0)
    00520     return "GLSLProgram::infoLog(): error! GLSL program object not yet created! (" + String(objectName().c_str()) + ")\n";
    00521
    00522   int max_length = 0;
    00523   glGetProgramiv(handle(), GL_INFO_LOG_LENGTH, &max_length); VL_CHECK_OGL();
    00524   std::vector<GLchar> log_buffer;
    00525   log_buffer.resize(max_length+1);
    00526   glGetProgramInfoLog(handle(), max_length, NULL, &log_buffer[0]); VL_CHECK_OGL();
    00527   return &log_buffer[0];
    00528 }
    00529 //-----------------------------------------------------------------------------
    00530 bool GLSLProgram::validateProgram() const
    00531 {
    00532   VL_CHECK_OGL();
    00533   VL_CHECK( GLEW_Has_Shading_Language_20 )
    00534   if( !GLEW_Has_Shading_Language_20 )
    00535     return false;
    00536
    00537   VL_CHECK(handle())
    00538
    00539   if (handle() == 0)
    00540     return false;
    00541
    00542   glValidateProgram(handle());
    00543   int status = 0;
    00544   glGetProgramiv(handle(), GL_VALIDATE_STATUS, &status); VL_CHECK_OGL();
    00545   return status == GL_TRUE;
    00546 }
    00547 //-----------------------------------------------------------------------------
    00548 void GLSLProgram::bindAttribLocation(unsigned int index, const std::string& name)
    00549 {
    00550   VL_CHECK_OGL();
    00551   VL_CHECK( GLEW_Has_Shading_Language_20 )
    00552
    00553   createProgram();
    00554   scheduleRelinking();
    00555   glBindAttribLocation(handle(), index, name.c_str()); VL_CHECK_OGL()
    00556 }
    00557 //-----------------------------------------------------------------------------
    00558 int GLSLProgram::maxVertexAttribs()
    00559 {
    00560   VL_CHECK_OGL();
    00561   VL_CHECK( GLEW_Has_Shading_Language_20 )
    00562   if( !GLEW_Has_Shading_Language_20 )
    00563     return 0;
    00564
    00565   int max = 0;
    00566   glGetIntegerv( GL_MAX_VERTEX_ATTRIBS, &max ); VL_CHECK_OGL()
    00567   return max;
    00568 }
    00569 //-----------------------------------------------------------------------------
    00570 bool GLSLProgram::useProgram() const
    00571 {
    00572   VL_CHECK_OGL()
    00573   VL_CHECK( GLEW_Has_Shading_Language_20 )
    00574   if( !GLEW_Has_Shading_Language_20 )
    00575     return false;
    00576
    00577   if (!handle())
    00578   {
    00579     Log::bug("GLSLProgram::useProgram() failed! GLSL program handle is null! (" + String(objectName().c_str()) + ")\n");
    00580     VL_TRAP()
    00581     return false;
    00582   }
    00583
    00584   if (!linked())
    00585   {
    00586     Log::bug("GLSLProgram::useProgram() failed! GLSL program not linked! (" + String(objectName().c_str()) + ")\n");
    00587     VL_TRAP()
    00588     return false;
    00589   }
    00590
    00591 // The program validation should be done only after all the uniforms have been applied, just before rendering an object.
    00592 //#ifndef NDEBUG
    00593 //  if (!validateProgram())
    00594 //  {
    00595 //    Log::bug("GLSLProgram::useProgram() failed validation! (" + String(objectName().c_str()) + ")\n");
    00596 //    Log::bug( Say("Info log:\n%s\n") << infoLog() );
    00597 //    VL_TRAP();
    00598 //    return false;
    00599 //  }
    00600 //#endif
    00601
    00602   // bind the GLSL program
    00603   glUseProgram(handle()); VL_CHECK_OGL()
    00604
    00605   return true;
    00606 }
    00607 //-----------------------------------------------------------------------------
    00608 void GLSLProgram::apply(const Camera*, OpenGLContext*) const
    00609 {
    00610   VL_CHECK_OGL();
    00611   if(GLEW_Has_Shading_Language_20)
    00612   {
    00613     if ( handle() )
    00614       useProgram();
    00615     else
    00616       glUseProgram(0); VL_CHECK_OGL();
    00617   }
    00618 }
    00619 //-----------------------------------------------------------------------------
    00620 bool GLSLProgram::applyUniformSet(const UniformSet* uniforms) const
    00621 {
    00622   VL_CHECK_OGL();
    00623   VL_CHECK( GLEW_Has_Shading_Language_20 )
    00624   if( !GLEW_Has_Shading_Language_20 )
    00625     return false;
    00626
    00627   if(!uniforms)
    00628     return false;
    00629
    00630   if (!linked())
    00631     return false;
    00632
    00633   if (!handle())
    00634     return false;
    00635
    00636 #ifndef NDEBUG
    00637   int current_glsl_program = -1;
    00638   glGetIntegerv(GL_CURRENT_PROGRAM, &current_glsl_program); VL_CHECK_OGL();
    00639   VL_CHECK(current_glsl_program == (int)handle())
    00640 #endif
    00641
    00642   for(size_t i=0, count=uniforms->uniforms().size(); i<count; ++i)
    00643   {
    00644     Uniform* uniform = uniforms->uniforms()[i].get();
    00645
    00646     #if 1
    00647       std::map<std::string, int>::const_iterator it = mActiveUniformLocation.find(uniform->name());
    00648       int location = it == mActiveUniformLocation.end() ? -1 : it->second;
    00649     #else
    00650       // for benchmarking purposes
    00651       int location = glGetUniformLocation(handle(), uniform->name().c_str());
    00652     #endif
    00653
    00654     if (location == -1)
    00655     {
    00656       // Check the following:
    00657       // (1) Is the uniform variable declared but not used in your GLSL program?
    00658       // (2) Double-check the spelling of the uniform variable name.
    00659       vl::Log::warning( vl::Say(
    00660         "warning:\n"
    00661         "GLSLProgram::applyUniformSet(): uniform '%s' not found!\n"
    00662         "Is the uniform variable declared but not used in your GLSL program?\n"
    00663         "Also double-check the spelling of the uniform variable name.\n") << uniform->name() );
    00664
    00665       // VL_TRAP();
    00666       // return false;
    00667       continue;
    00668     }
    00669
    00670     // finally transmits the uniform
    00671     // note: we don't perform delta binding per-uniform variable at the moment!
    00672
    00673     VL_CHECK_OGL();
    00674     switch(uniform->mType)
    00675     {
    00676       case UT_Int:     glUniform1iv(location, uniform->count(), uniform->intData()); VL_CHECK_OGL(); break;
    00677       case UT_Int2:    glUniform2iv(location, uniform->count(), uniform->intData()); VL_CHECK_OGL(); break;
    00678       case UT_Int3:    glUniform3iv(location, uniform->count(), uniform->intData()); VL_CHECK_OGL(); break;
    00679       case UT_Int4:    glUniform4iv(location, uniform->count(), uniform->intData()); VL_CHECK_OGL(); break;
    00680
    00681       case UT_UInt:    VL_glUniform1uiv(location, uniform->count(), uniform->uintData()); VL_CHECK_OGL(); break;
    00682       case UT_UInt2:   VL_glUniform2uiv(location, uniform->count(), uniform->uintData()); VL_CHECK_OGL(); break;
    00683       case UT_UInt3:   VL_glUniform3uiv(location, uniform->count(), uniform->uintData()); VL_CHECK_OGL(); break;
    00684       case UT_UInt4:   VL_glUniform4uiv(location, uniform->count(), uniform->uintData()); VL_CHECK_OGL(); break;
    00685
    00686       case UT_Float:   glUniform1fv(location, uniform->count(), uniform->floatData()); VL_CHECK_OGL(); break;
    00687       case UT_Float2:  glUniform2fv(location, uniform->count(), uniform->floatData()); VL_CHECK_OGL(); break;
    00688       case UT_Float3:  glUniform3fv(location, uniform->count(), uniform->floatData()); VL_CHECK_OGL(); break;
    00689       case UT_Float4:  glUniform4fv(location, uniform->count(), uniform->floatData()); VL_CHECK_OGL(); break;
    00690
    00691       case UT_Mat2F:   glUniformMatrix2fv(location, uniform->count(), GL_FALSE, uniform->floatData()); VL_CHECK_OGL(); break;
    00692       case UT_Mat3F:   glUniformMatrix3fv(location, uniform->count(), GL_FALSE, uniform->floatData()); VL_CHECK_OGL(); break;
    00693       case UT_Mat4F:   glUniformMatrix4fv(location, uniform->count(), GL_FALSE, uniform->floatData()); VL_CHECK_OGL(); break;
    00694
    00695       case UT_Mat2x3F: glUniformMatrix2x3fv(location, uniform->count(), GL_FALSE, uniform->floatData()); VL_CHECK_OGL(); break;
    00696       case UT_Mat3x2F: glUniformMatrix3x2fv(location, uniform->count(), GL_FALSE, uniform->floatData()); VL_CHECK_OGL(); break;
    00697       case UT_Mat2x4F: glUniformMatrix2x4fv(location, uniform->count(), GL_FALSE, uniform->floatData()); VL_CHECK_OGL(); break;
    00698       case UT_Mat4x2F: glUniformMatrix4x2fv(location, uniform->count(), GL_FALSE, uniform->floatData()); VL_CHECK_OGL(); break;
    00699       case UT_Mat3x4F: glUniformMatrix3x4fv(location, uniform->count(), GL_FALSE, uniform->floatData()); VL_CHECK_OGL(); break;
    00700       case UT_Mat4x3F: glUniformMatrix4x3fv(location, uniform->count(), GL_FALSE, uniform->floatData()); VL_CHECK_OGL(); break;
    00701
    00702       case UT_Double:  glUniform1dv(location, uniform->count(), uniform->doubleData()); VL_CHECK_OGL(); break;
    00703       case UT_Double2: glUniform2dv(location, uniform->count(), uniform->doubleData()); VL_CHECK_OGL(); break;
    00704       case UT_Double3: glUniform3dv(location, uniform->count(), uniform->doubleData()); VL_CHECK_OGL(); break;
    00705       case UT_Double4: glUniform4dv(location, uniform->count(), uniform->doubleData()); VL_CHECK_OGL(); break;
    00706
    00707       case UT_Mat2D:   glUniformMatrix2dv(location, uniform->count(), GL_FALSE, uniform->doubleData()); VL_CHECK_OGL(); break;
    00708       case UT_Mat3D:   glUniformMatrix3dv(location, uniform->count(), GL_FALSE, uniform->doubleData()); VL_CHECK_OGL(); break;
    00709       case UT_Mat4D:   glUniformMatrix4dv(location, uniform->count(), GL_FALSE, uniform->doubleData()); VL_CHECK_OGL(); break;
    00710
    00711       case UT_Mat2x3D: glUniformMatrix2x3dv(location, uniform->count(), GL_FALSE, uniform->doubleData()); VL_CHECK_OGL(); break;
    00712       case UT_Mat3x2D: glUniformMatrix3x2dv(location, uniform->count(), GL_FALSE, uniform->doubleData()); VL_CHECK_OGL(); break;
    00713       case UT_Mat2x4D: glUniformMatrix2x4dv(location, uniform->count(), GL_FALSE, uniform->doubleData()); VL_CHECK_OGL(); break;
    00714       case UT_Mat4x2D: glUniformMatrix4x2dv(location, uniform->count(), GL_FALSE, uniform->doubleData()); VL_CHECK_OGL(); break;
    00715       case UT_Mat3x4D: glUniformMatrix3x4dv(location, uniform->count(), GL_FALSE, uniform->doubleData()); VL_CHECK_OGL(); break;
    00716       case UT_Mat4x3D: glUniformMatrix4x3dv(location, uniform->count(), GL_FALSE, uniform->doubleData()); VL_CHECK_OGL(); break;
    00717
    00718       default:
    00719         // Probably you added a uniform to a Shader or Actor but you forgot to specify it's data!
    00720         vl::Log::bug( vl::Say("GLSLProgram::applyUniformSet(): uniform '%s' does not contain any data!\n") << uniform->name() );
    00721         VL_TRAP();
    00722         break;
    00723     }
    00724   }
    00725
    00726   VL_CHECK_OGL();
    00727   return true;
    00728 }
    00729 //-----------------------------------------------------------------------------
    00730 void GLSLProgram::bindFragDataLocation(int color_number, const std::string& name)
    00731 {
    00732   scheduleRelinking();
    00733   mFragDataLocation[name] = color_number;
    00734 }
    00735 //-----------------------------------------------------------------------------
    00736 void GLSLProgram::unbindFragDataLocation(const std::string& name)
    00737 {
    00738   scheduleRelinking();
    00739   mFragDataLocation.erase(name);
    00740 }
    00741 //-----------------------------------------------------------------------------
    00742 int GLSLProgram::fragDataLocationBinding(const std::string& name) const
    00743 {
    00744   std::map<std::string, int>::const_iterator it = mFragDataLocation.find(name);
    00745   if (it != mFragDataLocation.end())
    00746     return it->second;
    00747   else
    00748     return -1;
    00749 }
    00750 //-----------------------------------------------------------------------------
    00751 bool GLSLProgram::getProgramBinary(GLenum& binary_format, std::vector<unsigned char>& binary) const
    00752 {
    00753   VL_CHECK_OGL();
    00754   VL_CHECK(GLEW_ARB_get_program_binary)
    00755   if (!GLEW_ARB_get_program_binary)
    00756     return false;
    00757
    00758   binary.clear();
    00759   binary_format = (GLenum)-1;
    00760
    00761   if (handle())
    00762   {
    00763     int status = 0;
    00764     glGetProgramiv(handle(), GL_LINK_STATUS, &status); VL_CHECK_OGL();
    00765     if (status == GL_FALSE)
    00766       return false;
    00767     GLint length = 0;
    00768     glGetProgramiv(handle(), GL_PROGRAM_BINARY_LENGTH, &length); VL_CHECK_OGL();
    00769     if (length)
    00770     {
    00771       binary.resize(length);
    00772       glGetProgramBinary(handle(), length, NULL, &binary_format, &binary[0]); VL_CHECK_OGL();
    00773     }
    00774     return true;
    00775   }
    00776   else
    00777   {
    00778     VL_TRAP();
    00779     return false;
    00780   }
    00781 }
    00782 //-----------------------------------------------------------------------------
    00783 bool GLSLProgram::programBinary(GLenum binary_format, const void* binary, int length)
    00784 {
    00785   VL_CHECK_OGL();
    00786   VL_CHECK(GLEW_ARB_get_program_binary)
    00787   if (!GLEW_ARB_get_program_binary)
    00788     return false;
    00789
    00790   createProgram();
    00791
    00792   if (handle())
    00793   {
    00794     // pre-link operations
    00795     preLink();
    00796
    00797     // load glsl program and link
    00798     glProgramBinary(handle(), binary_format, binary, length); VL_CHECK_OGL();
    00799     mScheduleLink = !linkStatus();
    00800
    00801     // log error
    00802     if(linked())
    00803     {
    00804       // post-link operations
    00805       postLink();
    00806
    00807       #ifndef NDEBUG
    00808         String log = infoLog();
    00809         if (!log.empty())
    00810           Log::warning( Say("%s\n%s\n\n") << objectName().c_str() << log );
    00811       #endif
    00812     }
    00813     else
    00814     {
    00815       Log::bug("GLSLProgram::programBinary() failed! (" + String(objectName().c_str()) + ")\n");
    00816       Log::bug( Say("Info log:\n%s\n") << infoLog() );
    00817       VL_TRAP();
    00818     }
    00819
    00820     return linked();
    00821   }
    00822   else
    00823   {
    00824     VL_TRAP();
    00825     return false;
    00826   }
    00827 }
    00828 //-----------------------------------------------------------------------------

Visualization Library v2011.05.1142 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 26 2011 22:51:23.
Permission is granted to use this page to write and publish articles regarding Visualization Library.