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/GlobalSettings.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()
00045 {
00046 VL_DEBUG_SET_OBJECT_NAME()
00047 mType = ST_VERTEX_SHADER;
00048 mHandle = 0;
00049 mCompiled = false;
00050 }
00051
00052 GLSLShader::GLSLShader(EShaderType type, const String& source)
00053 {
00054 VL_DEBUG_SET_OBJECT_NAME()
00055 mType = type;
00056 mHandle = 0;
00057 mCompiled = false;
00058 setSource(source);
00059 }
00060
00061 GLSLShader::~GLSLShader()
00062 {
00063 deleteShader();
00064 }
00065
00066 std::string GLSLShader::getShaderSource() const
00067 {
00068 if (handle())
00069 {
00070 GLint len = 0;
00071 glGetShaderiv(handle(), GL_SHADER_SOURCE_LENGTH, &len);
00072 if (len)
00073 {
00074 std::vector<char> src;
00075 src.resize(len);
00076 GLint len_written = 0;
00077 glGetShaderSource(handle(), len, &len_written, &src[0]);
00078 return &src[0];
00079 }
00080 }
00081
00082 return "";
00083 }
00084
00085 void GLSLShader::setSource( const String& source_or_path )
00086 {
00087 std::string new_src = "ERROR";
00088
00089 if (source_or_path.empty())
00090 {
00091 mSource.clear();
00092 return;
00093 }
00094 else
00095 if (vl::locateFile(source_or_path))
00096 {
00097 new_src = vl::String::loadText(source_or_path).toStdString();
00098 setObjectName( source_or_path.toStdString().c_str() );
00099 setPath( source_or_path.toStdString().c_str() );
00100 }
00101 else
00102 {
00103 int cn = source_or_path.count('\n');
00104 int cr = source_or_path.count('\r');
00105 int cf = source_or_path.count('\f');
00106 int line_count = vl::max( vl::max( cn, cr ), cf );
00107 if(line_count == 0)
00108 {
00109 Log::error("GLSLShader::setSource('" + source_or_path + "') error: file not found!\n");
00110 mSource = "";
00111
00112 }
00113 else
00114 new_src = source_or_path.toStdString();
00115 }
00116
00117
00118 if (new_src != "ERROR" && new_src != mSource)
00119 {
00120 mSource = new_src;
00121 mCompiled = false;
00122 }
00123 }
00124
00125 bool GLSLShader::compile()
00126 {
00127 VL_CHECK_OGL();
00128 VL_CHECK( Has_GLSL )
00129 if( !Has_GLSL )
00130 return false;
00131
00132 if (mSource.empty())
00133 {
00134 Log::error("GLSLShader::compile() failed: shader source is empty!\n");
00135 VL_TRAP();
00136 return false;
00137 }
00138
00139 if (!mCompiled)
00140 {
00141
00142
00143 if (!handle())
00144 {
00145
00146 mHandle = glCreateShader(mType);
00147 }
00148
00149
00150
00151 const char* source[] = { mSource.c_str() };
00152 glShaderSource(handle(), 1, source, NULL);
00153
00154
00155
00156 glCompileShader(handle());
00157
00158 if ( compileStatus() )
00159 {
00160 mCompiled = true;
00161 #ifndef NDEBUG
00162 String log = infoLog();
00163 if (!log.empty())
00164 Log::warning( Say("%s\n%s\n\n") << objectName().c_str() << log );
00165 #endif
00166 }
00167 else
00168 {
00169 Log::bug( Say("\nGLSLShader::compile() failed! '%s':\n\n") << objectName().c_str() );
00170
00171 Log::bug( Say("Info log:\n%s\n\n") << infoLog() );
00172
00173 }
00174 }
00175
00176 VL_CHECK_OGL();
00177 return mCompiled;
00178 }
00179
00180 bool GLSLShader::compileStatus() const
00181 {
00182 VL_CHECK_OGL();
00183 VL_CHECK( Has_GLSL )
00184 if( !Has_GLSL )
00185 return false;
00186 VL_CHECK(handle())
00187
00188 int status = 0;
00189 glGetShaderiv(handle(), GL_COMPILE_STATUS, &status); VL_CHECK_OGL();
00190 return status == GL_TRUE;
00191 }
00192
00193 String GLSLShader::infoLog() const
00194 {
00195 VL_CHECK_OGL();
00196 VL_CHECK( Has_GLSL )
00197 if( !Has_GLSL )
00198 return "OpenGL Shading Language not supported.\n";
00199 VL_CHECK(handle())
00200
00201 int max_length = 0;
00202 glGetShaderiv(handle(), GL_INFO_LOG_LENGTH, &max_length); VL_CHECK_OGL();
00203 if (max_length != 0)
00204 {
00205 std::vector<char> log_buffer;
00206 log_buffer.resize(max_length);
00207 glGetShaderInfoLog(handle(), max_length, NULL, &log_buffer[0]); VL_CHECK_OGL();
00208 VL_CHECK_OGL();
00209 return &log_buffer[0];
00210 }
00211 else
00212 return String();
00213 }
00214
00215 void GLSLShader::createShader()
00216 {
00217 VL_CHECK_OGL();
00218 VL_CHECK( Has_GLSL )
00219 if( !Has_GLSL )
00220 return;
00221 if (!handle())
00222 {
00223 mHandle = glCreateShader(mType);
00224 mCompiled = false;
00225 }
00226 VL_CHECK(handle());
00227 VL_CHECK_OGL();
00228 }
00229
00230 void GLSLShader::deleteShader()
00231 {
00232
00233 VL_CHECK( Has_GLSL )
00234 if( !Has_GLSL )
00235 return;
00236 if (handle())
00237 {
00238 glDeleteShader(handle());
00239 mHandle = 0;
00240 mCompiled = false;
00241 }
00242 }
00243
00244
00245
00246 GLSLProgram::GLSLProgram()
00247 {
00248 VL_DEBUG_SET_OBJECT_NAME()
00249 mScheduleLink = true;
00250 mHandle = 0;
00251 mGeometryVerticesOut = 0;
00252 mGeometryInputType = GIT_TRIANGLES;
00253 mGeometryOutputType = GOT_TRIANGLE_STRIP;
00254 mProgramBinaryRetrievableHint = false;
00255 mProgramSeparable = false;
00256 m_vl_ModelViewMatrix = -1;
00257 m_vl_ProjectionMatrix = -1;
00258 m_vl_ModelViewProjectionMatrix = -1;
00259 m_vl_NormalMatrix = -1;
00260 }
00261
00262 GLSLProgram::~GLSLProgram()
00263 {
00264 if (handle())
00265 deleteProgram();
00266 }
00267
00268 GLSLProgram& GLSLProgram::operator=(const GLSLProgram& other)
00269 {
00270 super::operator=(other);
00271
00272
00273
00274 deleteProgram();
00275
00276
00277 mShaders.clear();
00278 for(size_t i=0; i<other.mShaders.size(); ++i)
00279 attachShader( other.mShaders[i].get_writable() );
00280
00281 mFragDataLocation = other.mFragDataLocation;
00282 mActiveUniforms.clear();
00283 mActiveAttribs.clear();
00284 mAutoAttribLocation = other.mAutoAttribLocation;
00285 if (other.mUniformSet)
00286 {
00287 if (mUniformSet.get() == NULL)
00288 mUniformSet = new UniformSet;
00289 *mUniformSet = *other.mUniformSet;
00290 }
00291 else
00292 mUniformSet = NULL;
00293
00294
00295 mGeometryVerticesOut = other.mGeometryVerticesOut;
00296 mGeometryInputType = other.mGeometryInputType;
00297 mGeometryOutputType = other.mGeometryOutputType;
00298 mProgramBinaryRetrievableHint = other.mProgramBinaryRetrievableHint;
00299 mProgramSeparable = other.mProgramSeparable;
00300
00301 m_vl_ModelViewMatrix = -1;
00302 m_vl_ProjectionMatrix = -1;
00303 m_vl_ModelViewProjectionMatrix = -1;
00304 m_vl_NormalMatrix = -1;
00305
00306 return *this;
00307 }
00308 void GLSLProgram::createProgram()
00309 {
00310 VL_CHECK_OGL();
00311 VL_CHECK( Has_GLSL )
00312 if( !Has_GLSL )
00313 return;
00314
00315 if (handle() == 0)
00316 {
00317 scheduleRelinking();
00318 mHandle = glCreateProgram(); VL_CHECK_OGL();
00319 VL_CHECK(handle())
00320 }
00321 }
00322
00323 void GLSLProgram::deleteProgram()
00324 {
00325
00326 VL_CHECK( Has_GLSL )
00327 if( !Has_GLSL )
00328 return;
00329 if(handle())
00330 {
00331 glDeleteProgram(handle());
00332 mHandle = 0;
00333 }
00334 scheduleRelinking();
00335 }
00336
00337 bool GLSLProgram::attachShader(GLSLShader* shader)
00338 {
00339 VL_CHECK_OGL();
00340 VL_CHECK( Has_GLSL )
00341 if( !Has_GLSL )
00342 return false;
00343
00344 scheduleRelinking();
00345
00346 #if 0
00347 if(std::find(mShaders.begin(), mShaders.end(), shader) != mShaders.end())
00348 {
00349 if ( shader->handle() )
00350 glDetachShader( handle(), shader->handle() ); VL_CHECK_OGL();
00351 }
00352 else
00353 mShaders.push_back(shader);
00354 #else
00355 detachShader(shader);
00356 mShaders.push_back(shader);
00357 #endif
00358
00359 if ( shader->compile() )
00360 {
00361 createProgram();
00362 glAttachShader( handle(), shader->handle() ); VL_CHECK_OGL();
00363 return true;
00364 }
00365
00366 VL_CHECK_OGL();
00367 return false;
00368
00369 }
00370
00371 void GLSLProgram::detachAllShaders()
00372 {
00373 VL_CHECK_OGL();
00374 for(size_t i=mShaders.size(); i--;)
00375 detachShader(mShaders[i].get());
00376 }
00377
00378
00379 bool GLSLProgram::detachShader(GLSLShader* shader)
00380 {
00381 VL_CHECK_OGL();
00382
00383 VL_CHECK( Has_GLSL )
00384 if( !Has_GLSL )
00385 return false;
00386
00387 if (!handle() || !shader->handle())
00388 return false;
00389
00390
00391 for(int i=0; i<(int)mShaders.size(); ++i)
00392 {
00393 if (mShaders[i] == shader)
00394 {
00395 if ( shader->handle() )
00396 glDetachShader( handle(), shader->handle() ); VL_CHECK_OGL();
00397 mShaders.erase(mShaders.begin() + i);
00398 break;
00399 }
00400 }
00401
00402 return true;
00403 }
00404
00405 void GLSLProgram::discardAllShaders()
00406 {
00407 VL_CHECK_OGL();
00408 VL_CHECK( Has_GLSL )
00409 if( !Has_GLSL )
00410 return;
00411
00412 if (!handle())
00413 return;
00414
00415 for(int i=0; i<(int)mShaders.size(); ++i)
00416 {
00417 if (mShaders[i]->handle())
00418 {
00419 glDetachShader( handle(), mShaders[i]->handle() ); VL_CHECK_OGL();
00420 mShaders[i]->deleteShader();
00421 }
00422 }
00423
00424 mShaders.clear();
00425 }
00426
00427 bool GLSLProgram::linkProgram(bool force_relink)
00428 {
00429 VL_CHECK_OGL();
00430 VL_CHECK( Has_GLSL )
00431 if( !Has_GLSL )
00432 return false;
00433
00434 if (!linked() || force_relink)
00435 {
00436 if (shaderCount() == 0)
00437 {
00438 Log::bug("GLSLProgram::linkProgram() called on a GLSLProgram with no shaders! (" + String(objectName().c_str()) + ")\n");
00439 VL_TRAP()
00440 return false;
00441 }
00442
00443 createProgram();
00444
00445
00446 preLink();
00447
00448
00449
00450 glLinkProgram(handle()); VL_CHECK_OGL();
00451 mScheduleLink = !linkStatus();
00452
00453
00454 if(linked())
00455 {
00456
00457 postLink();
00458
00459 #ifndef NDEBUG
00460 String log = infoLog();
00461 if (!log.empty())
00462 Log::warning( Say("%s\n%s\n\n") << objectName().c_str() << log );
00463 #endif
00464 }
00465 else
00466 {
00467 Log::bug("GLSLProgram::linkProgram() failed! (" + String(objectName().c_str()) + ")\n");
00468 Log::bug( Say("Info log:\n%s\n") << infoLog() );
00469 VL_TRAP()
00470 return false;
00471 }
00472 }
00473
00474 return true;
00475 }
00476
00477 void GLSLProgram::preLink()
00478 {
00479 VL_CHECK_OGL();
00480
00481
00482 if (Has_GL_EXT_gpu_shader4||Has_GL_Version_3_0||Has_GL_Version_4_0)
00483 {
00484 std::map<std::string, int>::iterator it = mFragDataLocation.begin();
00485 while(it != mFragDataLocation.end())
00486 {
00487 VL_glBindFragDataLocation( handle(), it->second, it->first.c_str() ); VL_CHECK_OGL();
00488 ++it;
00489 }
00490 }
00491
00492
00493
00494
00495
00496
00497
00498 if (Has_Geometry_Shader && geometryVerticesOut() )
00499 {
00500
00501 for(unsigned i=0; i<mShaders.size(); ++i)
00502 {
00503 if (mShaders[i]->type() == ST_GEOMETRY_SHADER)
00504 {
00505 VL_glProgramParameteri(handle(), GL_GEOMETRY_INPUT_TYPE_EXT, geometryInputType()); VL_CHECK_OGL();
00506 VL_glProgramParameteri(handle(), GL_GEOMETRY_OUTPUT_TYPE_EXT, geometryOutputType()); VL_CHECK_OGL();
00507 VL_glProgramParameteri(handle(), GL_GEOMETRY_VERTICES_OUT_EXT, geometryVerticesOut()); VL_CHECK_OGL();
00508 break;
00509 }
00510 }
00511 }
00512
00513
00514
00515 if(Has_GL_ARB_get_program_binary)
00516 {
00517 VL_glProgramParameteri(handle(), GL_PROGRAM_BINARY_RETRIEVABLE_HINT, programBinaryRetrievableHint()?GL_TRUE:GL_FALSE); VL_CHECK_OGL();
00518 }
00519
00520 if (Has_GL_ARB_separate_shader_objects)
00521 {
00522 VL_glProgramParameteri(handle(), GL_PROGRAM_SEPARABLE, programSeparable()?GL_TRUE:GL_FALSE); VL_CHECK_OGL();
00523 }
00524
00525
00526
00527 for( std::map<std::string, int>::iterator it = mAutoAttribLocation.begin(); it != mAutoAttribLocation.end(); ++it)
00528 {
00529 glBindAttribLocation(handle(),it->second,it->first.c_str()); VL_CHECK_OGL();
00530 }
00531 }
00532
00533 void GLSLProgram::postLink()
00534 {
00535 VL_CHECK_OGL();
00536
00537
00538
00539 mActiveUniforms.clear();
00540
00541 int uniform_len = 0;
00542 glGetProgramiv(handle(), GL_ACTIVE_UNIFORM_MAX_LENGTH, &uniform_len); VL_CHECK_OGL();
00543 if (uniform_len)
00544 {
00545 std::vector<char> tmp_buf;
00546 tmp_buf.resize(uniform_len+1);
00547 char* name = &tmp_buf[0];
00548
00549 int uniform_count = 0;
00550 glGetProgramiv(handle(), GL_ACTIVE_UNIFORMS, &uniform_count); VL_CHECK_OGL();
00551 for(int i=0; i<uniform_count; ++i)
00552 {
00553 GLenum type;
00554 int size;
00555 std::fill(tmp_buf.begin(), tmp_buf.end(), 0);
00556 int length = 0;
00557 glGetActiveUniform(handle(), i, (GLsizei)tmp_buf.size(), &length, &size, &type, name); VL_CHECK_OGL();
00558
00559
00560
00561 if (name[length-1] == ']')
00562 {
00563 char* bracket = strrchr(name, '[');
00564 if (bracket)
00565 {
00566 Log::warning( Say("Driver bug: glGetActiveUniform() returned a uniform name '%s' containing square brackets!\n"
00567 "VL will continue trimming them from the uniform's name.\n"
00568 "Please update your drivers and report the issue to your driver vendor.\n"
00569 "Driver info: vendor: %s, renderer: %s, OpenGL version: %s\n"
00570 ) << name << glGetString(GL_VENDOR) << glGetString(GL_RENDERER) << glGetString(GL_VERSION) );
00571 *bracket = 0;
00572 }
00573 }
00574
00575 ref<UniformInfo> uinfo = new UniformInfo(name, (EUniformType)type, size, glGetUniformLocation(handle(), name));
00576 mActiveUniforms[name] = uinfo;
00577 }
00578 }
00579
00580
00581
00582 mActiveAttribs.clear();
00583
00584 int attrib_len = 0;
00585 glGetProgramiv(handle(), GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &attrib_len); VL_CHECK_OGL();
00586 if (attrib_len)
00587 {
00588 std::vector<char> tmp_buf;
00589 tmp_buf.resize(attrib_len);
00590 char* name = &tmp_buf[0];
00591
00592 int attrib_count = 0;
00593 glGetProgramiv(handle(), GL_ACTIVE_ATTRIBUTES, &attrib_count); VL_CHECK_OGL();
00594 for(int i=0; i<attrib_count; ++i)
00595 {
00596 GLenum type;
00597 int size;
00598 glGetActiveAttrib(handle(), i, attrib_len, NULL, &size, &type, name); VL_CHECK_OGL();
00599 ref<AttribInfo> uinfo = new AttribInfo(name, (EAttributeType)type, size, glGetAttribLocation(handle(), name));
00600 mActiveAttribs[name] = uinfo;
00601 }
00602 }
00603
00604
00605
00606 m_vl_ModelViewMatrix = glGetUniformLocation(handle(), "vl_ModelViewMatrix");
00607 m_vl_ProjectionMatrix = glGetUniformLocation(handle(), "vl_ProjectionMatrix");
00608 m_vl_ModelViewProjectionMatrix = glGetUniformLocation(handle(), "vl_ModelViewProjectionMatrix");
00609 m_vl_NormalMatrix = glGetUniformLocation(handle(), "vl_NormalMatrix");
00610 }
00611
00612 bool GLSLProgram::linkStatus() const
00613 {
00614 VL_CHECK_OGL();
00615 VL_CHECK( Has_GLSL )
00616 if( !Has_GLSL )
00617 return false;
00618
00619 VL_CHECK(handle())
00620
00621 if (handle() == 0)
00622 return false;
00623
00624 int status = 0;
00625 glGetProgramiv(handle(), GL_LINK_STATUS, &status); VL_CHECK_OGL();
00626 return status == GL_TRUE;
00627 }
00628
00629 String GLSLProgram::infoLog() const
00630 {
00631 VL_CHECK_OGL();
00632 VL_CHECK( Has_GLSL )
00633 if( !Has_GLSL )
00634 return "OpenGL Shading Language not supported!\n";
00635
00636 VL_CHECK(handle())
00637
00638 if (handle() == 0)
00639 return "GLSLProgram::infoLog(): error! GLSL program object not yet created! (" + String(objectName().c_str()) + ")\n";
00640
00641 int max_length = 0;
00642 glGetProgramiv(handle(), GL_INFO_LOG_LENGTH, &max_length); VL_CHECK_OGL();
00643 std::vector<char> log_buffer;
00644 log_buffer.resize(max_length+1);
00645 glGetProgramInfoLog(handle(), max_length, NULL, &log_buffer[0]); VL_CHECK_OGL();
00646 return &log_buffer[0];
00647 }
00648
00649 bool GLSLProgram::validateProgram() const
00650 {
00651 VL_CHECK_OGL();
00652 VL_CHECK( Has_GLSL )
00653 if( !Has_GLSL )
00654 return false;
00655
00656 VL_CHECK(handle())
00657
00658 if (handle() == 0)
00659 return false;
00660
00661 glValidateProgram(handle());
00662 int status = 0;
00663 glGetProgramiv(handle(), GL_VALIDATE_STATUS, &status); VL_CHECK_OGL();
00664 return status == GL_TRUE;
00665 }
00666
00667 void GLSLProgram::bindAttribLocation(unsigned int index, const char* name)
00668 {
00669 VL_CHECK_OGL();
00670 VL_CHECK( Has_GLSL )
00671
00672 createProgram();
00673 scheduleRelinking();
00674 glBindAttribLocation(handle(), index, name); VL_CHECK_OGL()
00675 }
00676
00677 bool GLSLProgram::useProgram() const
00678 {
00679 VL_CHECK_OGL()
00680 VL_CHECK( Has_GLSL )
00681 if( !Has_GLSL )
00682 return false;
00683
00684 if (!handle())
00685 {
00686 Log::bug("GLSLProgram::useProgram() failed! GLSL program handle is null! (" + String(objectName().c_str()) + ")\n");
00687 VL_TRAP()
00688 return false;
00689 }
00690
00691 if (!linked())
00692 {
00693 Log::bug("GLSLProgram::useProgram() failed! GLSL program not linked! (" + String(objectName().c_str()) + ")\n");
00694 VL_TRAP()
00695 return false;
00696 }
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710 glUseProgram(handle()); VL_CHECK_OGL()
00711
00712 return true;
00713 }
00714
00715 void GLSLProgram::apply(int , const Camera*, OpenGLContext*) const
00716 {
00717 VL_CHECK_OGL();
00718 if(Has_GLSL)
00719 {
00720 if ( handle() )
00721 useProgram();
00722 else
00723 glUseProgram(0); VL_CHECK_OGL();
00724 }
00725 }
00726
00727 bool GLSLProgram::applyUniformSet(const UniformSet* uniforms) const
00728 {
00729 VL_CHECK_OGL();
00730 VL_CHECK( Has_GLSL )
00731 if( !Has_GLSL )
00732 return false;
00733
00734 if(!uniforms)
00735 return false;
00736
00737 if (!linked())
00738 return false;
00739
00740 if (!handle())
00741 return false;
00742
00743 #ifndef NDEBUG
00744 int current_glsl_program = -1;
00745 glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_glsl_program); VL_CHECK_OGL();
00746 VL_CHECK(current_glsl_program == (int)handle())
00747 #endif
00748
00749 for(size_t i=0, count=uniforms->uniforms().size(); i<count; ++i)
00750 {
00751 const Uniform* uniform = uniforms->uniforms()[i].get();
00752
00753 #if 1
00754 const UniformInfo* uinfo = activeUniformInfo(uniform->name().c_str());
00755 int location = uinfo ? uinfo->Location : -1;
00756
00757 #ifndef NDEBUG
00758 if (location == -1)
00759 {
00760 std::map<std::string, ref<UniformInfo> >::const_iterator it = activeUniforms().begin();
00761 Log::warning("\nActive uniforms:\n");
00762 for( ; it != activeUniforms().end(); ++it )
00763 Log::warning( Say("\t%s\n") << it->first.c_str() );
00764 }
00765 #endif
00766
00767 #else
00768 int location = glGetUniformLocation(handle(), uniform->name().c_str());
00769 #endif
00770
00771 if (location == -1)
00772 {
00773
00774
00775
00776 vl::Log::warning( vl::Say(
00777 "warning:\n"
00778 "GLSLProgram::applyUniformSet(): uniform '%s' not found!\n"
00779 "Is the uniform variable declared but not used in your GLSL program?\n"
00780 "Also double-check the spelling of the uniform variable name.\n") << uniform->name() );
00781 continue;
00782 }
00783
00784
00785
00786
00787 VL_CHECK_OGL();
00788 switch(uniform->mType)
00789 {
00790 case UT_INT: glUniform1iv(location, uniform->count(), uniform->intData()); VL_CHECK_OGL(); break;
00791 case UT_INT_VEC2: glUniform2iv(location, uniform->count(), uniform->intData()); VL_CHECK_OGL(); break;
00792 case UT_INT_VEC3: glUniform3iv(location, uniform->count(), uniform->intData()); VL_CHECK_OGL(); break;
00793 case UT_INT_VEC4: glUniform4iv(location, uniform->count(), uniform->intData()); VL_CHECK_OGL(); break;
00794
00795 case UT_UNSIGNED_INT: VL_glUniform1uiv(location, uniform->count(), uniform->uintData()); VL_CHECK_OGL(); break;
00796 case UT_UNSIGNED_INT_VEC2: VL_glUniform2uiv(location, uniform->count(), uniform->uintData()); VL_CHECK_OGL(); break;
00797 case UT_UNSIGNED_INT_VEC3: VL_glUniform3uiv(location, uniform->count(), uniform->uintData()); VL_CHECK_OGL(); break;
00798 case UT_UNSIGNED_INT_VEC4: VL_glUniform4uiv(location, uniform->count(), uniform->uintData()); VL_CHECK_OGL(); break;
00799
00800 case UT_FLOAT: glUniform1fv(location, uniform->count(), uniform->floatData()); VL_CHECK_OGL(); break;
00801 case UT_FLOAT_VEC2: glUniform2fv(location, uniform->count(), uniform->floatData()); VL_CHECK_OGL(); break;
00802 case UT_FLOAT_VEC3: glUniform3fv(location, uniform->count(), uniform->floatData()); VL_CHECK_OGL(); break;
00803 case UT_FLOAT_VEC4: glUniform4fv(location, uniform->count(), uniform->floatData()); VL_CHECK_OGL(); break;
00804
00805 case UT_FLOAT_MAT2: glUniformMatrix2fv(location, uniform->count(), GL_FALSE, uniform->floatData()); VL_CHECK_OGL(); break;
00806 case UT_FLOAT_MAT3: glUniformMatrix3fv(location, uniform->count(), GL_FALSE, uniform->floatData()); VL_CHECK_OGL(); break;
00807 case UT_FLOAT_MAT4: glUniformMatrix4fv(location, uniform->count(), GL_FALSE, uniform->floatData()); VL_CHECK_OGL(); break;
00808
00809 case UT_FLOAT_MAT2x3: glUniformMatrix2x3fv(location, uniform->count(), GL_FALSE, uniform->floatData()); VL_CHECK_OGL(); break;
00810 case UT_FLOAT_MAT3x2: glUniformMatrix3x2fv(location, uniform->count(), GL_FALSE, uniform->floatData()); VL_CHECK_OGL(); break;
00811 case UT_FLOAT_MAT2x4: glUniformMatrix2x4fv(location, uniform->count(), GL_FALSE, uniform->floatData()); VL_CHECK_OGL(); break;
00812 case UT_FLOAT_MAT4x2: glUniformMatrix4x2fv(location, uniform->count(), GL_FALSE, uniform->floatData()); VL_CHECK_OGL(); break;
00813 case UT_FLOAT_MAT3x4: glUniformMatrix3x4fv(location, uniform->count(), GL_FALSE, uniform->floatData()); VL_CHECK_OGL(); break;
00814 case UT_FLOAT_MAT4x3: glUniformMatrix4x3fv(location, uniform->count(), GL_FALSE, uniform->floatData()); VL_CHECK_OGL(); break;
00815
00816 case UT_DOUBLE: glUniform1dv(location, uniform->count(), uniform->doubleData()); VL_CHECK_OGL(); break;
00817 case UT_DOUBLE_VEC2: glUniform2dv(location, uniform->count(), uniform->doubleData()); VL_CHECK_OGL(); break;
00818 case UT_DOUBLE_VEC3: glUniform3dv(location, uniform->count(), uniform->doubleData()); VL_CHECK_OGL(); break;
00819 case UT_DOUBLE_VEC4: glUniform4dv(location, uniform->count(), uniform->doubleData()); VL_CHECK_OGL(); break;
00820
00821 case UT_DOUBLE_MAT2: glUniformMatrix2dv(location, uniform->count(), GL_FALSE, uniform->doubleData()); VL_CHECK_OGL(); break;
00822 case UT_DOUBLE_MAT3: glUniformMatrix3dv(location, uniform->count(), GL_FALSE, uniform->doubleData()); VL_CHECK_OGL(); break;
00823 case UT_DOUBLE_MAT4: glUniformMatrix4dv(location, uniform->count(), GL_FALSE, uniform->doubleData()); VL_CHECK_OGL(); break;
00824
00825 case UT_DOUBLE_MAT2x3: glUniformMatrix2x3dv(location, uniform->count(), GL_FALSE, uniform->doubleData()); VL_CHECK_OGL(); break;
00826 case UT_DOUBLE_MAT3x2: glUniformMatrix3x2dv(location, uniform->count(), GL_FALSE, uniform->doubleData()); VL_CHECK_OGL(); break;
00827 case UT_DOUBLE_MAT2x4: glUniformMatrix2x4dv(location, uniform->count(), GL_FALSE, uniform->doubleData()); VL_CHECK_OGL(); break;
00828 case UT_DOUBLE_MAT4x2: glUniformMatrix4x2dv(location, uniform->count(), GL_FALSE, uniform->doubleData()); VL_CHECK_OGL(); break;
00829 case UT_DOUBLE_MAT3x4: glUniformMatrix3x4dv(location, uniform->count(), GL_FALSE, uniform->doubleData()); VL_CHECK_OGL(); break;
00830 case UT_DOUBLE_MAT4x3: glUniformMatrix4x3dv(location, uniform->count(), GL_FALSE, uniform->doubleData()); VL_CHECK_OGL(); break;
00831
00832 case UT_NONE:
00833
00834 vl::Log::bug( vl::Say("GLSLProgram::applyUniformSet(): uniform '%s' does not contain any data! Did you forget to assign a value to it?\n") << uniform->name() );
00835 VL_TRAP();
00836 break;
00837
00838 default:
00839 vl::Log::bug( vl::Say("GLSLProgram::applyUniformSet(): wrong uniform type for '%s'!\n") << uniform->name() );
00840 VL_TRAP();
00841 break;
00842 }
00843 }
00844
00845 VL_CHECK_OGL();
00846 return true;
00847 }
00848
00849 void GLSLProgram::bindFragDataLocation(int color_number, const char* name)
00850 {
00851 scheduleRelinking();
00852 mFragDataLocation[name] = color_number;
00853 }
00854
00855 void GLSLProgram::unbindFragDataLocation(const char* name)
00856 {
00857 scheduleRelinking();
00858 mFragDataLocation.erase(name);
00859 }
00860
00861 int GLSLProgram::fragDataLocation(const char* name) const
00862 {
00863 std::map<std::string, int>::const_iterator it = mFragDataLocation.find(name);
00864 if (it != mFragDataLocation.end())
00865 return it->second;
00866 else
00867 return -1;
00868 }
00869
00870 bool GLSLProgram::getProgramBinary(GLenum& binary_format, std::vector<unsigned char>& binary) const
00871 {
00872 VL_CHECK_OGL();
00873 VL_CHECK(Has_GL_ARB_get_program_binary)
00874 if (!Has_GL_ARB_get_program_binary)
00875 return false;
00876
00877 binary.clear();
00878 binary_format = (GLenum)-1;
00879
00880 if (handle())
00881 {
00882 int status = 0;
00883 glGetProgramiv(handle(), GL_LINK_STATUS, &status); VL_CHECK_OGL();
00884 if (status == GL_FALSE)
00885 return false;
00886 GLint length = 0;
00887 glGetProgramiv(handle(), GL_PROGRAM_BINARY_LENGTH, &length); VL_CHECK_OGL();
00888 if (length)
00889 {
00890 binary.resize(length);
00891 VL_glGetProgramBinary(handle(), length, NULL, &binary_format, &binary[0]); VL_CHECK_OGL();
00892 }
00893 return true;
00894 }
00895 else
00896 {
00897 VL_TRAP();
00898 return false;
00899 }
00900 }
00901
00902 bool GLSLProgram::programBinary(GLenum binary_format, const void* binary, int length)
00903 {
00904 VL_CHECK_OGL();
00905 VL_CHECK(Has_GL_ARB_get_program_binary)
00906 if (!Has_GL_ARB_get_program_binary)
00907 return false;
00908
00909 createProgram();
00910
00911 if (handle())
00912 {
00913
00914 preLink();
00915
00916
00917 VL_glProgramBinary(handle(), binary_format, binary, length); VL_CHECK_OGL();
00918 mScheduleLink = !linkStatus();
00919
00920
00921 if(linked())
00922 {
00923
00924 postLink();
00925
00926 #ifndef NDEBUG
00927 String log = infoLog();
00928 if (!log.empty())
00929 Log::warning( Say("%s\n%s\n\n") << objectName().c_str() << log );
00930 #endif
00931 }
00932 else
00933 {
00934 Log::bug("GLSLProgram::programBinary() failed! (" + String(objectName().c_str()) + ")\n");
00935 Log::bug( Say("Info log:\n%s\n") << infoLog() );
00936 VL_TRAP();
00937 }
00938
00939 return linked();
00940 }
00941 else
00942 {
00943 VL_TRAP();
00944 return false;
00945 }
00946 }
00947