00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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
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
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
00108
00109 if (!handle())
00110 {
00111
00112 mHandle = glCreateShader(mType);
00113 }
00114
00115
00116
00117 const GLchar* source[] = { mSource.c_str() };
00118 glShaderSource(handle(), 1, source, NULL);
00119
00120
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
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
00199 VL_CHECK( GLEW_Has_Shading_Language_20 )
00200 if( !GLEW_Has_Shading_Language_20 )
00201 return;
00202 if (handle())
00203 {
00204 glDeleteShader(handle());
00205 mHandle = 0;
00206 mCompiled = false;
00207 }
00208 }
00209
00210
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
00252 VL_CHECK( GLEW_Has_Shading_Language_20 )
00253 if( !GLEW_Has_Shading_Language_20 )
00254 return;
00255 if(handle())
00256 {
00257 glDeleteProgram(handle());
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
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
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
00372 preLink();
00373
00374
00375
00376 glLinkProgram(handle()); VL_CHECK_OGL();
00377 mScheduleLink = !linkStatus();
00378
00379
00380 if(linked())
00381 {
00382
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
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
00419
00420
00421
00422
00423
00424 if (GLEW_Has_Geometry_Shader && geometryVerticesOut() )
00425 {
00426
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
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
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
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
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
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
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, ¤t_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
00651 int location = glGetUniformLocation(handle(), uniform->name().c_str());
00652 #endif
00653
00654 if (location == -1)
00655 {
00656
00657
00658
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
00666
00667 continue;
00668 }
00669
00670
00671
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
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
00795 preLink();
00796
00797
00798 glProgramBinary(handle(), binary_format, binary, length); VL_CHECK_OGL();
00799 mScheduleLink = !linkStatus();
00800
00801
00802 if(linked())
00803 {
00804
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