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