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 glGetActiveUniform(handle(), i, (GLsizei)tmp_buf.size(), NULL, &size, &type, name); VL_CHECK_OGL();
00557
00558
00559
00560
00561 if (strstr(name, "gl_") != name)
00562 {
00563 GLint location = glGetUniformLocation(handle(), name);
00564 if(location == -1)
00565 Log::bug( Say("OpenGL driver bug: uniform '%s' not found! Please update your drivers or report the issue to your driver vendor.\n") << name);
00566 }
00567
00568
00569 ref<UniformInfo> uinfo = new UniformInfo(name, (EUniformType)type, size, glGetUniformLocation(handle(), name));
00570 mActiveUniforms[name] = uinfo;
00571 }
00572 }
00573
00574
00575
00576 mActiveAttribs.clear();
00577
00578 int attrib_len = 0;
00579 glGetProgramiv(handle(), GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &attrib_len); VL_CHECK_OGL();
00580 if (attrib_len)
00581 {
00582 std::vector<char> tmp_buf;
00583 tmp_buf.resize(attrib_len);
00584 char* name = &tmp_buf[0];
00585
00586 int attrib_count = 0;
00587 glGetProgramiv(handle(), GL_ACTIVE_ATTRIBUTES, &attrib_count); VL_CHECK_OGL();
00588 for(int i=0; i<attrib_count; ++i)
00589 {
00590 GLenum type;
00591 int size;
00592 glGetActiveAttrib(handle(), i, attrib_len, NULL, &size, &type, name); VL_CHECK_OGL();
00593 ref<AttribInfo> uinfo = new AttribInfo(name, (EAttributeType)type, size, glGetAttribLocation(handle(), name));
00594 mActiveAttribs[name] = uinfo;
00595 }
00596 }
00597
00598
00599
00600 m_vl_ModelViewMatrix = glGetUniformLocation(handle(), "vl_ModelViewMatrix");
00601 m_vl_ProjectionMatrix = glGetUniformLocation(handle(), "vl_ProjectionMatrix");
00602 m_vl_ModelViewProjectionMatrix = glGetUniformLocation(handle(), "vl_ModelViewProjectionMatrix");
00603 m_vl_NormalMatrix = glGetUniformLocation(handle(), "vl_NormalMatrix");
00604 }
00605
00606 bool GLSLProgram::linkStatus() const
00607 {
00608 VL_CHECK_OGL();
00609 VL_CHECK( Has_GLSL )
00610 if( !Has_GLSL )
00611 return false;
00612
00613 VL_CHECK(handle())
00614
00615 if (handle() == 0)
00616 return false;
00617
00618 int status = 0;
00619 glGetProgramiv(handle(), GL_LINK_STATUS, &status); VL_CHECK_OGL();
00620 return status == GL_TRUE;
00621 }
00622
00623 String GLSLProgram::infoLog() const
00624 {
00625 VL_CHECK_OGL();
00626 VL_CHECK( Has_GLSL )
00627 if( !Has_GLSL )
00628 return "OpenGL Shading Language not supported!\n";
00629
00630 VL_CHECK(handle())
00631
00632 if (handle() == 0)
00633 return "GLSLProgram::infoLog(): error! GLSL program object not yet created! (" + String(objectName().c_str()) + ")\n";
00634
00635 int max_length = 0;
00636 glGetProgramiv(handle(), GL_INFO_LOG_LENGTH, &max_length); VL_CHECK_OGL();
00637 std::vector<char> log_buffer;
00638 log_buffer.resize(max_length+1);
00639 glGetProgramInfoLog(handle(), max_length, NULL, &log_buffer[0]); VL_CHECK_OGL();
00640 return &log_buffer[0];
00641 }
00642
00643 bool GLSLProgram::validateProgram() const
00644 {
00645 VL_CHECK_OGL();
00646 VL_CHECK( Has_GLSL )
00647 if( !Has_GLSL )
00648 return false;
00649
00650 VL_CHECK(handle())
00651
00652 if (handle() == 0)
00653 return false;
00654
00655 glValidateProgram(handle());
00656 int status = 0;
00657 glGetProgramiv(handle(), GL_VALIDATE_STATUS, &status); VL_CHECK_OGL();
00658 return status == GL_TRUE;
00659 }
00660
00661 void GLSLProgram::bindAttribLocation(unsigned int index, const char* name)
00662 {
00663 VL_CHECK_OGL();
00664 VL_CHECK( Has_GLSL )
00665
00666 createProgram();
00667 scheduleRelinking();
00668 glBindAttribLocation(handle(), index, name); VL_CHECK_OGL()
00669 }
00670
00671 bool GLSLProgram::useProgram() const
00672 {
00673 VL_CHECK_OGL()
00674 VL_CHECK( Has_GLSL )
00675 if( !Has_GLSL )
00676 return false;
00677
00678 if (!handle())
00679 {
00680 Log::bug("GLSLProgram::useProgram() failed! GLSL program handle is null! (" + String(objectName().c_str()) + ")\n");
00681 VL_TRAP()
00682 return false;
00683 }
00684
00685 if (!linked())
00686 {
00687 Log::bug("GLSLProgram::useProgram() failed! GLSL program not linked! (" + String(objectName().c_str()) + ")\n");
00688 VL_TRAP()
00689 return false;
00690 }
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704 glUseProgram(handle()); VL_CHECK_OGL()
00705
00706 return true;
00707 }
00708
00709 void GLSLProgram::apply(int , const Camera*, OpenGLContext*) const
00710 {
00711 VL_CHECK_OGL();
00712 if(Has_GLSL)
00713 {
00714 if ( handle() )
00715 useProgram();
00716 else
00717 glUseProgram(0); VL_CHECK_OGL();
00718 }
00719 }
00720
00721 bool GLSLProgram::applyUniformSet(const UniformSet* uniforms) const
00722 {
00723 VL_CHECK_OGL();
00724 VL_CHECK( Has_GLSL )
00725 if( !Has_GLSL )
00726 return false;
00727
00728 if(!uniforms)
00729 return false;
00730
00731 if (!linked())
00732 return false;
00733
00734 if (!handle())
00735 return false;
00736
00737 #ifndef NDEBUG
00738 int current_glsl_program = -1;
00739 glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_glsl_program); VL_CHECK_OGL();
00740 VL_CHECK(current_glsl_program == (int)handle())
00741 #endif
00742
00743 for(size_t i=0, count=uniforms->uniforms().size(); i<count; ++i)
00744 {
00745 const Uniform* uniform = uniforms->uniforms()[i].get();
00746
00747 #if 1
00748 const UniformInfo* uinfo = activeUniformInfo(uniform->name().c_str());
00749 int location = uinfo ? uinfo->Location : -1;
00750
00751 #ifndef NDEBUG
00752 if (location == -1)
00753 {
00754 std::map<std::string, ref<UniformInfo> >::const_iterator it = activeUniforms().begin();
00755 Log::warning("\nActive uniforms:\n");
00756 for( ; it != activeUniforms().end(); ++it )
00757 Log::warning( Say("\t%s\n") << it->first.c_str() );
00758 }
00759 #endif
00760
00761 #else
00762 int location = glGetUniformLocation(handle(), uniform->name().c_str());
00763 #endif
00764
00765 if (location == -1)
00766 {
00767
00768
00769
00770 vl::Log::warning( vl::Say(
00771 "warning:\n"
00772 "GLSLProgram::applyUniformSet(): uniform '%s' not found!\n"
00773 "Is the uniform variable declared but not used in your GLSL program?\n"
00774 "Also double-check the spelling of the uniform variable name.\n") << uniform->name() );
00775 continue;
00776 }
00777
00778
00779
00780
00781 VL_CHECK_OGL();
00782 switch(uniform->mType)
00783 {
00784 case UT_INT: glUniform1iv(location, uniform->count(), uniform->intData()); VL_CHECK_OGL(); break;
00785 case UT_INT_VEC2: glUniform2iv(location, uniform->count(), uniform->intData()); VL_CHECK_OGL(); break;
00786 case UT_INT_VEC3: glUniform3iv(location, uniform->count(), uniform->intData()); VL_CHECK_OGL(); break;
00787 case UT_INT_VEC4: glUniform4iv(location, uniform->count(), uniform->intData()); VL_CHECK_OGL(); break;
00788
00789 case UT_UNSIGNED_INT: VL_glUniform1uiv(location, uniform->count(), uniform->uintData()); VL_CHECK_OGL(); break;
00790 case UT_UNSIGNED_INT_VEC2: VL_glUniform2uiv(location, uniform->count(), uniform->uintData()); VL_CHECK_OGL(); break;
00791 case UT_UNSIGNED_INT_VEC3: VL_glUniform3uiv(location, uniform->count(), uniform->uintData()); VL_CHECK_OGL(); break;
00792 case UT_UNSIGNED_INT_VEC4: VL_glUniform4uiv(location, uniform->count(), uniform->uintData()); VL_CHECK_OGL(); break;
00793
00794 case UT_FLOAT: glUniform1fv(location, uniform->count(), uniform->floatData()); VL_CHECK_OGL(); break;
00795 case UT_FLOAT_VEC2: glUniform2fv(location, uniform->count(), uniform->floatData()); VL_CHECK_OGL(); break;
00796 case UT_FLOAT_VEC3: glUniform3fv(location, uniform->count(), uniform->floatData()); VL_CHECK_OGL(); break;
00797 case UT_FLOAT_VEC4: glUniform4fv(location, uniform->count(), uniform->floatData()); VL_CHECK_OGL(); break;
00798
00799 case UT_FLOAT_MAT2: glUniformMatrix2fv(location, uniform->count(), GL_FALSE, uniform->floatData()); VL_CHECK_OGL(); break;
00800 case UT_FLOAT_MAT3: glUniformMatrix3fv(location, uniform->count(), GL_FALSE, uniform->floatData()); VL_CHECK_OGL(); break;
00801 case UT_FLOAT_MAT4: glUniformMatrix4fv(location, uniform->count(), GL_FALSE, uniform->floatData()); VL_CHECK_OGL(); break;
00802
00803 case UT_FLOAT_MAT2x3: glUniformMatrix2x3fv(location, uniform->count(), GL_FALSE, uniform->floatData()); VL_CHECK_OGL(); break;
00804 case UT_FLOAT_MAT3x2: glUniformMatrix3x2fv(location, uniform->count(), GL_FALSE, uniform->floatData()); VL_CHECK_OGL(); break;
00805 case UT_FLOAT_MAT2x4: glUniformMatrix2x4fv(location, uniform->count(), GL_FALSE, uniform->floatData()); VL_CHECK_OGL(); break;
00806 case UT_FLOAT_MAT4x2: glUniformMatrix4x2fv(location, uniform->count(), GL_FALSE, uniform->floatData()); VL_CHECK_OGL(); break;
00807 case UT_FLOAT_MAT3x4: glUniformMatrix3x4fv(location, uniform->count(), GL_FALSE, uniform->floatData()); VL_CHECK_OGL(); break;
00808 case UT_FLOAT_MAT4x3: glUniformMatrix4x3fv(location, uniform->count(), GL_FALSE, uniform->floatData()); VL_CHECK_OGL(); break;
00809
00810 case UT_DOUBLE: glUniform1dv(location, uniform->count(), uniform->doubleData()); VL_CHECK_OGL(); break;
00811 case UT_DOUBLE_VEC2: glUniform2dv(location, uniform->count(), uniform->doubleData()); VL_CHECK_OGL(); break;
00812 case UT_DOUBLE_VEC3: glUniform3dv(location, uniform->count(), uniform->doubleData()); VL_CHECK_OGL(); break;
00813 case UT_DOUBLE_VEC4: glUniform4dv(location, uniform->count(), uniform->doubleData()); VL_CHECK_OGL(); break;
00814
00815 case UT_DOUBLE_MAT2: glUniformMatrix2dv(location, uniform->count(), GL_FALSE, uniform->doubleData()); VL_CHECK_OGL(); break;
00816 case UT_DOUBLE_MAT3: glUniformMatrix3dv(location, uniform->count(), GL_FALSE, uniform->doubleData()); VL_CHECK_OGL(); break;
00817 case UT_DOUBLE_MAT4: glUniformMatrix4dv(location, uniform->count(), GL_FALSE, uniform->doubleData()); VL_CHECK_OGL(); break;
00818
00819 case UT_DOUBLE_MAT2x3: glUniformMatrix2x3dv(location, uniform->count(), GL_FALSE, uniform->doubleData()); VL_CHECK_OGL(); break;
00820 case UT_DOUBLE_MAT3x2: glUniformMatrix3x2dv(location, uniform->count(), GL_FALSE, uniform->doubleData()); VL_CHECK_OGL(); break;
00821 case UT_DOUBLE_MAT2x4: glUniformMatrix2x4dv(location, uniform->count(), GL_FALSE, uniform->doubleData()); VL_CHECK_OGL(); break;
00822 case UT_DOUBLE_MAT4x2: glUniformMatrix4x2dv(location, uniform->count(), GL_FALSE, uniform->doubleData()); VL_CHECK_OGL(); break;
00823 case UT_DOUBLE_MAT3x4: glUniformMatrix3x4dv(location, uniform->count(), GL_FALSE, uniform->doubleData()); VL_CHECK_OGL(); break;
00824 case UT_DOUBLE_MAT4x3: glUniformMatrix4x3dv(location, uniform->count(), GL_FALSE, uniform->doubleData()); VL_CHECK_OGL(); break;
00825
00826 case UT_NONE:
00827
00828 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() );
00829 VL_TRAP();
00830 break;
00831
00832 default:
00833 vl::Log::bug( vl::Say("GLSLProgram::applyUniformSet(): wrong uniform type for '%s'!\n") << uniform->name() );
00834 VL_TRAP();
00835 break;
00836 }
00837 }
00838
00839 VL_CHECK_OGL();
00840 return true;
00841 }
00842
00843 void GLSLProgram::bindFragDataLocation(int color_number, const char* name)
00844 {
00845 scheduleRelinking();
00846 mFragDataLocation[name] = color_number;
00847 }
00848
00849 void GLSLProgram::unbindFragDataLocation(const char* name)
00850 {
00851 scheduleRelinking();
00852 mFragDataLocation.erase(name);
00853 }
00854
00855 int GLSLProgram::fragDataLocation(const char* name) const
00856 {
00857 std::map<std::string, int>::const_iterator it = mFragDataLocation.find(name);
00858 if (it != mFragDataLocation.end())
00859 return it->second;
00860 else
00861 return -1;
00862 }
00863
00864 bool GLSLProgram::getProgramBinary(GLenum& binary_format, std::vector<unsigned char>& binary) const
00865 {
00866 VL_CHECK_OGL();
00867 VL_CHECK(Has_GL_ARB_get_program_binary)
00868 if (!Has_GL_ARB_get_program_binary)
00869 return false;
00870
00871 binary.clear();
00872 binary_format = (GLenum)-1;
00873
00874 if (handle())
00875 {
00876 int status = 0;
00877 glGetProgramiv(handle(), GL_LINK_STATUS, &status); VL_CHECK_OGL();
00878 if (status == GL_FALSE)
00879 return false;
00880 GLint length = 0;
00881 glGetProgramiv(handle(), GL_PROGRAM_BINARY_LENGTH, &length); VL_CHECK_OGL();
00882 if (length)
00883 {
00884 binary.resize(length);
00885 VL_glGetProgramBinary(handle(), length, NULL, &binary_format, &binary[0]); VL_CHECK_OGL();
00886 }
00887 return true;
00888 }
00889 else
00890 {
00891 VL_TRAP();
00892 return false;
00893 }
00894 }
00895
00896 bool GLSLProgram::programBinary(GLenum binary_format, const void* binary, int length)
00897 {
00898 VL_CHECK_OGL();
00899 VL_CHECK(Has_GL_ARB_get_program_binary)
00900 if (!Has_GL_ARB_get_program_binary)
00901 return false;
00902
00903 createProgram();
00904
00905 if (handle())
00906 {
00907
00908 preLink();
00909
00910
00911 VL_glProgramBinary(handle(), binary_format, binary, length); VL_CHECK_OGL();
00912 mScheduleLink = !linkStatus();
00913
00914
00915 if(linked())
00916 {
00917
00918 postLink();
00919
00920 #ifndef NDEBUG
00921 String log = infoLog();
00922 if (!log.empty())
00923 Log::warning( Say("%s\n%s\n\n") << objectName().c_str() << log );
00924 #endif
00925 }
00926 else
00927 {
00928 Log::bug("GLSLProgram::programBinary() failed! (" + String(objectName().c_str()) + ")\n");
00929 Log::bug( Say("Info log:\n%s\n") << infoLog() );
00930 VL_TRAP();
00931 }
00932
00933 return linked();
00934 }
00935 else
00936 {
00937 VL_TRAP();
00938 return false;
00939 }
00940 }
00941