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
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045
00046 #include <OSGConfig.h>
00047
00048 #include <OSGGL.h>
00049 #include <OSGGLU.h>
00050 #include <OSGGLEXT.h>
00051 #include <OSGRemoteAspect.h>
00052 #include <OSGCamera.h>
00053 #include <OSGViewport.h>
00054 #include <OSGStereoCameraDecorator.h>
00055 #include <OSGRenderAction.h>
00056
00057 #include <OSGShaderParameter.h>
00058 #include <OSGShaderParameterBool.h>
00059 #include <OSGShaderParameterInt.h>
00060 #include <OSGShaderParameterReal.h>
00061 #include <OSGShaderParameterVec2f.h>
00062 #include <OSGShaderParameterVec3f.h>
00063 #include <OSGShaderParameterVec4f.h>
00064 #include <OSGShaderParameterMatrix.h>
00065
00066 #include <OSGShaderParameterMInt.h>
00067 #include <OSGShaderParameterMReal.h>
00068 #include <OSGShaderParameterMVec2f.h>
00069 #include <OSGShaderParameterMVec3f.h>
00070 #include <OSGShaderParameterMVec4f.h>
00071 #include <OSGShaderParameterMMatrix.h>
00072
00073 #include "OSGSHLChunk.h"
00074
00075 OSG_USING_NAMESPACE
00076
00081
00082
00083
00084
00085 StateChunkClass SHLChunk::_class("SHL");
00086
00087 UInt32 SHLChunk::_shl_extension;
00088 UInt32 SHLChunk::_cg_extension;
00089 UInt32 SHLChunk::_geometry_extension;
00090
00091 UInt32 SHLChunk::_funcCreateProgramObject = Window::invalidFunctionID;
00092 UInt32 SHLChunk::_funcProgramParameteri = Window::invalidFunctionID;
00093 UInt32 SHLChunk::_funcCreateShaderObject = Window::invalidFunctionID;
00094 UInt32 SHLChunk::_funcDeleteObject = Window::invalidFunctionID;
00095 UInt32 SHLChunk::_funcDetachObject = Window::invalidFunctionID;
00096 UInt32 SHLChunk::_funcAttachObject = Window::invalidFunctionID;
00097
00098 UInt32 SHLChunk::_funcShaderSource = Window::invalidFunctionID;
00099 UInt32 SHLChunk::_funcCompileShader = Window::invalidFunctionID;
00100 UInt32 SHLChunk::_funcLinkProgram = Window::invalidFunctionID;
00101 UInt32 SHLChunk::_funcGetInfoLog = Window::invalidFunctionID;
00102 UInt32 SHLChunk::_funcUseProgramObject = Window::invalidFunctionID;
00103
00104 UInt32 SHLChunk::_funcGetObjectParameteriv = Window::invalidFunctionID;
00105 UInt32 SHLChunk::_funcGetObjectParameterfv = Window::invalidFunctionID;
00106 UInt32 SHLChunk::_funcGetUniformLocation = Window::invalidFunctionID;
00107
00108 UInt32 SHLChunk::_funcBindAttribLocation = Window::invalidFunctionID;
00109 UInt32 SHLChunk::_funcGetAttribLocation = Window::invalidFunctionID;
00110
00111 UInt32 SHLChunk::_funcUniform1i = Window::invalidFunctionID;
00112 UInt32 SHLChunk::_funcUniform1iv = Window::invalidFunctionID;
00113 UInt32 SHLChunk::_funcUniform2iv = Window::invalidFunctionID;
00114 UInt32 SHLChunk::_funcUniform3iv = Window::invalidFunctionID;
00115 UInt32 SHLChunk::_funcUniform4iv = Window::invalidFunctionID;
00116
00117 UInt32 SHLChunk::_funcUniform1f = Window::invalidFunctionID;
00118 UInt32 SHLChunk::_funcUniform1fv = Window::invalidFunctionID;
00119 UInt32 SHLChunk::_funcUniform2fv = Window::invalidFunctionID;
00120 UInt32 SHLChunk::_funcUniform3fv = Window::invalidFunctionID;
00121 UInt32 SHLChunk::_funcUniform4fv = Window::invalidFunctionID;
00122
00123 UInt32 SHLChunk::_funcUniformMatrix4fv = Window::invalidFunctionID;
00124
00125 UInt32 SHLChunk::_funcGetUniformiv = Window::invalidFunctionID;
00126 UInt32 SHLChunk::_funcGetUniformfv = Window::invalidFunctionID;
00127
00128 Int32 SHLChunk::_clusterId = -1;
00129
00130 SHLChunk::parametercbfp SHLChunk::_userParametersCallback = NULL;
00131
00132
00133
00134 typedef GLuint (OSG_APIENTRY * OSGGLCREATEPROGRAMOBJECTARBPROC) (void);
00135 typedef void (OSG_APIENTRY * OSGGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value);
00136 typedef void (OSG_APIENTRY * OSGGLDELETEOBJECTARBPROC) (GLuint obj);
00137 typedef GLuint (OSG_APIENTRY * OSGGLCREATESHADEROBJECTARBPROC) (GLenum shaderType);
00138 typedef void (OSG_APIENTRY * OSGGLSHADERSOURCEARBPROC) (GLuint shaderObj, GLsizei count, const char **strings, const GLint *length);
00139 typedef void (OSG_APIENTRY * OSGGLCOMPILESHADERARBPROC) (GLuint shaderObj);
00140 typedef void (OSG_APIENTRY * OSGGLGETOBJECTPARAMETERIVARBPROC) (GLuint obj, GLenum pname, GLint *params);
00141 typedef void (OSG_APIENTRY * OSGGLGETINFOLOGARBPROC) (GLuint obj,GLsizei maxLength, GLsizei *length, char *infoLog);
00142 typedef void (OSG_APIENTRY * OSGGLATTACHOBJECTARBPROC) (GLuint containerObj, GLuint obj);
00143 typedef void (OSG_APIENTRY * OSGGLLINKPROGRAMARBPROC) (GLuint programObj);
00144 typedef void (OSG_APIENTRY * OSGGLUSEPROGRAMOBJECTARBPROC) (GLuint programObj);
00145
00146 typedef GLint (OSG_APIENTRY * OSGGLGETUNIFORMLOCATIONARBPROC) (GLuint programObj, const char *name);
00147
00148 typedef void (OSG_APIENTRY * OSGGLUNIFORM1IARBPROC) (GLint location, GLint value);
00149 typedef void (OSG_APIENTRY * OSGGLUNIFORMIVARBPROC) (GLint location, GLsizei count, GLint *value);
00150
00151 typedef void (OSG_APIENTRY * OSGGLUNIFORM1FARBPROC) (GLint location, GLfloat value);
00152 typedef void (OSG_APIENTRY * OSGGLUNIFORMFVARBPROC) (GLint location, GLsizei count, GLfloat *value);
00153
00154 typedef void (OSG_APIENTRY * OSGGLUNIFORMMATRIXFVARBPROC) (GLint location, GLsizei count, GLboolean transpose, GLfloat *value);
00155
00156 typedef void (OSG_APIENTRY * OSGGLGETUNIFORMFIARBPROC) (GLuint programObj, GLint location, GLint *value);
00157 typedef void (OSG_APIENTRY * OSGGLGETUNIFORMFVARBPROC) (GLuint programObj, GLint location, GLfloat *value);
00158
00159
00160
00161
00162
00163
00164 void SHLChunk::initMethod (void)
00165 {
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 SHLChunk::SHLChunk(void) :
00180 Inherited(),
00181 _osgParametersCallbacks(),
00182 _oldParameterSize(0),
00183 _userParameterCallbacks()
00184 {
00185 _shl_extension = Window::registerExtension("GL_ARB_shading_language_100");
00186 _cg_extension = Window::registerExtension("GL_EXT_Cg_shader");
00187 _geometry_extension = Window::registerExtension("GL_EXT_geometry_shader4");
00188
00189 _funcCreateProgramObject =
00190 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glCreateProgramObjectARB",
00191 _shl_extension);
00192
00193 _funcProgramParameteri =
00194 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glProgramParameteriEXT",
00195 _geometry_extension);
00196
00197 _funcCreateShaderObject =
00198 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glCreateShaderObjectARB",
00199 _shl_extension);
00200 _funcDeleteObject =
00201 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glDeleteObjectARB",
00202 _shl_extension);
00203
00204 _funcDetachObject =
00205 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glDetachObjectARB",
00206 _shl_extension);
00207
00208 _funcAttachObject =
00209 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glAttachObjectARB",
00210 _shl_extension);
00211
00212 _funcShaderSource =
00213 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glShaderSourceARB",
00214 _shl_extension);
00215
00216 _funcCompileShader =
00217 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glCompileShaderARB",
00218 _shl_extension);
00219
00220 _funcLinkProgram =
00221 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glLinkProgramARB",
00222 _shl_extension);
00223
00224 _funcGetInfoLog =
00225 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glGetInfoLogARB",
00226 _shl_extension);
00227
00228 _funcUseProgramObject =
00229 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glUseProgramObjectARB",
00230 _shl_extension);
00231
00232 _funcGetObjectParameteriv =
00233 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glGetObjectParameterivARB",
00234 _shl_extension);
00235
00236 _funcGetObjectParameterfv =
00237 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glGetObjectParameterfvARB",
00238 _shl_extension);
00239
00240 _funcGetUniformLocation =
00241 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glGetUniformLocationARB",
00242 _shl_extension);
00243
00244 _funcBindAttribLocation =
00245 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glBindAttribLocationARB",
00246 _shl_extension);
00247
00248 _funcGetAttribLocation =
00249 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glGetAttribLocationARB",
00250 _shl_extension);
00251
00252 _funcUniform1i =
00253 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glUniform1iARB",
00254 _shl_extension);
00255
00256 _funcUniform1iv =
00257 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glUniform1ivARB",
00258 _shl_extension);
00259
00260 _funcUniform2iv =
00261 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glUniform2ivARB",
00262 _shl_extension);
00263
00264 _funcUniform3iv =
00265 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glUniform3ivARB",
00266 _shl_extension);
00267
00268 _funcUniform4iv =
00269 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glUniform4ivARB",
00270 _shl_extension);
00271
00272 _funcUniform1f =
00273 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glUniform1fARB",
00274 _shl_extension);
00275
00276 _funcUniform1fv =
00277 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glUniform1fvARB",
00278 _shl_extension);
00279
00280 _funcUniform2fv =
00281 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glUniform2fvARB",
00282 _shl_extension);
00283
00284 _funcUniform3fv =
00285 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glUniform3fvARB",
00286 _shl_extension);
00287
00288 _funcUniform4fv =
00289 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glUniform4fvARB",
00290 _shl_extension);
00291
00292 _funcUniformMatrix4fv =
00293 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glUniformMatrix4fvARB",
00294 _shl_extension);
00295
00296 _funcGetUniformiv =
00297 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glGetUniformivARB",
00298 _shl_extension);
00299
00300 _funcGetUniformfv =
00301 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glGetUniformfvARB",
00302 _shl_extension);
00303 }
00304
00305 SHLChunk::SHLChunk(const SHLChunk &source) :
00306 Inherited(source),
00307 _osgParametersCallbacks(source._osgParametersCallbacks),
00308 _oldParameterSize(source._oldParameterSize),
00309 _userParameterCallbacks(source._userParameterCallbacks)
00310 {
00311 }
00312
00313 SHLChunk::~SHLChunk(void)
00314 {
00315 }
00316
00317 void SHLChunk::onCreate(const SHLChunk *source)
00318 {
00319 Inherited::onCreate(source);
00320
00321
00322 if(GlobalSystemState == Startup)
00323 return;
00324
00325
00326 RemoteAspect::addFieldFilter(SHLChunk::getClassType().getId(), SHLChunk::GLIdFieldMask);
00327
00328 SHLChunkPtr tmpPtr(*this);
00329
00330 if(Thread::getAspect() != _sfIgnoreGLForAspect.getValue())
00331 {
00332 beginEditCP(tmpPtr, SHLChunk::GLIdFieldMask);
00333 setGLId(Window::registerGLObject(osgTypedMethodVoidFunctor2ObjCPtrPtr<SHLChunkPtr,
00334 Window , UInt32>(tmpPtr, &SHLChunk::handleGL), 1));
00335 endEditCP(tmpPtr, SHLChunk::GLIdFieldMask);
00336 }
00337
00338
00339 }
00340
00341 void SHLChunk::onDestroy(void)
00342 {
00343 Inherited::onDestroy();
00344
00345 if(getGLId() > 0)
00346 Window::destroyGLObject(getGLId(), 1);
00347 }
00348
00349 const StateChunkClass *SHLChunk::getClass(void) const
00350 {
00351 return &_class;
00352 }
00353
00354
00355
00356 void SHLChunk::changed(BitVector whichField, UInt32 origin)
00357 {
00358 if(Thread::getAspect() != _sfIgnoreGLForAspect.getValue())
00359 {
00360 if(getGLId() == 0)
00361 {
00362 SHLChunkPtr tmpPtr(*this);
00363
00364 beginEditCP(tmpPtr, SHLChunk::GLIdFieldMask);
00365
00366 setGLId(
00367 Window::registerGLObject(
00368 osgTypedMethodVoidFunctor2ObjCPtrPtr<SHLChunkPtr,
00369 Window ,
00370 UInt32>(
00371 tmpPtr,
00372 &SHLChunk::handleGL),
00373 1));
00374
00375 endEditCP(tmpPtr, SHLChunk::GLIdFieldMask);
00376 }
00377 }
00378
00379 if((whichField & VertexProgramFieldMask) ||
00380 (whichField & FragmentProgramFieldMask) ||
00381 (whichField & GeometryProgramFieldMask) ||
00382 (whichField & CgFrontEndFieldMask))
00383 {
00384 if(Thread::getAspect() != _sfIgnoreGLForAspect.getValue())
00385 {
00386 Window::reinitializeGLObject(getGLId());
00387 }
00388 }
00389
00390 if((whichField & ParametersFieldMask) ||
00391 (whichField & ProgramParameterNamesFieldMask) ||
00392 (whichField & ProgramParameterValuesFieldMask))
00393 {
00394 if(Thread::getAspect() != _sfIgnoreGLForAspect.getValue())
00395 {
00396 Window::refreshGLObject(getGLId());
00397 }
00398 }
00399
00400 Inherited::changed(whichField, origin);
00401 }
00402
00403 void SHLChunk::dump( UInt32 ,
00404 const BitVector ) const
00405 {
00406 SLOG << "Dump SHLChunk NI" << std::endl;
00407 }
00408
00412 void SHLChunk::handleGL(Window *win, UInt32 idstatus)
00413 {
00414 Window::GLObjectStatusE mode;
00415 UInt32 id;
00416
00417 Window::unpackIdStatus(idstatus, id, mode);
00418
00419 if(!win->hasExtension(_shl_extension))
00420 {
00421 FWARNING(("OpenGL Shading Language is not supported, couldn't find extension 'GL_ARB_shading_language_100'!\n"));
00422 win->setGLObjectId(getGLId(), 0);
00423 return;
00424 }
00425
00426
00427 if(mode == Window::destroy)
00428 {
00429
00430
00431 GLuint program = (GLuint) win->getGLObjectId(id);
00432 if(program != 0)
00433 {
00434
00435 OSGGLDELETEOBJECTARBPROC deleteObject = (OSGGLDELETEOBJECTARBPROC)
00436 win->getFunction(_funcDeleteObject);
00437 deleteObject(program);
00438 win->setGLObjectId(id, 0);
00439 }
00440 }
00441 else if(mode == Window::finaldestroy)
00442 {
00443 ;
00444 }
00445 else if(mode == Window::initialize || mode == Window::reinitialize ||
00446 mode == Window::needrefresh)
00447 {
00448 if(mode != Window::needrefresh)
00449 {
00450 updateProgram(win);
00451 }
00452
00453 updateProgramParameters(win);
00454 updateParameters(win, getParameters(), true, true);
00455 }
00456 else
00457 {
00458 SWARNING << "SHLChunk(" << this << "::handleGL: Illegal mode: "
00459 << mode << " for id " << id << std::endl;
00460 }
00461 }
00462
00463 void SHLChunk::updateProgram(Window *win)
00464 {
00465
00466
00467
00468 OSGGLCREATEPROGRAMOBJECTARBPROC createProgramObject = (OSGGLCREATEPROGRAMOBJECTARBPROC)
00469 win->getFunction(_funcCreateProgramObject);
00470
00471
00472 OSGGLDELETEOBJECTARBPROC deleteObject = (OSGGLDELETEOBJECTARBPROC)
00473 win->getFunction(_funcDeleteObject);
00474
00475
00476 OSGGLCREATESHADEROBJECTARBPROC createShaderObject = (OSGGLCREATESHADEROBJECTARBPROC)
00477 win->getFunction(_funcCreateShaderObject);
00478
00479
00480 OSGGLSHADERSOURCEARBPROC shaderSource = (OSGGLSHADERSOURCEARBPROC)
00481 win->getFunction(_funcShaderSource);
00482
00483
00484 OSGGLCOMPILESHADERARBPROC compileShader = (OSGGLCOMPILESHADERARBPROC)
00485 win->getFunction(_funcCompileShader);
00486
00487
00488 OSGGLGETOBJECTPARAMETERIVARBPROC getObjectParameteriv = (OSGGLGETOBJECTPARAMETERIVARBPROC)
00489 win->getFunction(_funcGetObjectParameteriv);
00490
00491
00492 OSGGLGETINFOLOGARBPROC getInfoLog = (OSGGLGETINFOLOGARBPROC)
00493 win->getFunction(_funcGetInfoLog);
00494
00495
00496 OSGGLATTACHOBJECTARBPROC attachObject = (OSGGLATTACHOBJECTARBPROC)
00497 win->getFunction(_funcAttachObject);
00498
00499
00500 OSGGLLINKPROGRAMARBPROC linkProgram = (OSGGLLINKPROGRAMARBPROC)
00501 win->getFunction(_funcLinkProgram);
00502
00503
00504 OSGGLUSEPROGRAMOBJECTARBPROC useProgramObject = (OSGGLUSEPROGRAMOBJECTARBPROC)
00505 win->getFunction(_funcUseProgramObject);
00506
00507 GLuint program = (GLuint) win->getGLObjectId(getGLId());
00508
00509 if(program != 0)
00510 deleteObject(program);
00511 program = createProgramObject();
00512
00513 win->setGLObjectId(getGLId(), (UInt32) program);
00514
00515 UInt32 vShader = 0;
00516 GLint has_vertex = 0;
00517
00518 if(!getVertexProgram().empty())
00519 {
00520 GLenum shader_type = GL_VERTEX_SHADER_ARB;
00521 if(getCgFrontEnd())
00522 {
00523 if(win->hasExtension(_cg_extension))
00524 shader_type = GL_CG_VERTEX_SHADER_EXT;
00525 else
00526 FWARNING(("EXT_Cg_shader extension not supported, using GLSL front end!\n"));
00527 }
00528
00529 vShader = createShaderObject(shader_type);
00530 const char *source = getVertexProgram().c_str();
00531 shaderSource(vShader, 1, (const char **) &source, 0);
00532
00533 int success = 0;
00534 compileShader(vShader);
00535 getObjectParameteriv(vShader, GL_OBJECT_COMPILE_STATUS_ARB, &has_vertex);
00536
00537 if(has_vertex == 0)
00538 {
00539 char *debug;
00540 GLint debugLength;
00541 getObjectParameteriv(vShader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &debugLength);
00542
00543 debug = new char[debugLength];
00544 getInfoLog(vShader, debugLength, &debugLength, debug);
00545
00546 FFATAL(("Couldn't compile vertex program!\n%s\n", debug));
00547 delete [] debug;
00548 deleteObject(vShader);
00549 }
00550 }
00551
00552 UInt32 fShader = 0;
00553 GLint has_fragment = 0;
00554 if(!getFragmentProgram().empty())
00555 {
00556 GLenum shader_type = GL_FRAGMENT_SHADER_ARB;
00557 if(getCgFrontEnd())
00558 {
00559 if(win->hasExtension(_cg_extension))
00560 shader_type = GL_CG_FRAGMENT_SHADER_EXT;
00561 else
00562 FWARNING(("EXT_Cg_shader extension not supported, using GLSL front end!\n"));
00563 }
00564
00565 fShader = createShaderObject(shader_type);
00566 const char *source = getFragmentProgram().c_str();
00567 shaderSource(fShader, 1, (const char **) &source, 0);
00568
00569 compileShader(fShader);
00570 getObjectParameteriv(fShader, GL_OBJECT_COMPILE_STATUS_ARB, &has_fragment);
00571
00572 if(has_fragment == 0)
00573 {
00574 char *debug;
00575 GLint debugLength;
00576 getObjectParameteriv(fShader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &debugLength);
00577
00578 debug = new char[debugLength];
00579 getInfoLog(fShader, debugLength, &debugLength, debug);
00580
00581 FFATAL(("Couldn't compile fragment program!\n%s\n", debug));
00582 delete [] debug;
00583 deleteObject(fShader);
00584 }
00585 }
00586
00587 UInt32 gShader = 0;
00588 GLint has_geometry = 0;
00589
00590 if(!getGeometryProgram().empty())
00591 {
00592 if(win->hasExtension(_geometry_extension))
00593 {
00594 GLenum shader_type = GL_GEOMETRY_SHADER_EXT;
00595
00596 gShader = createShaderObject(shader_type);
00597 const char *source = getGeometryProgram().c_str();
00598 shaderSource(gShader, 1, (const char **) &source, 0);
00599
00600 int success = 0;
00601 compileShader(gShader);
00602 getObjectParameteriv(gShader, GL_OBJECT_COMPILE_STATUS_ARB, &has_geometry);
00603
00604 if(has_geometry == 0)
00605 {
00606 char *debug;
00607 GLint debugLength;
00608 getObjectParameteriv(gShader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &debugLength);
00609
00610 debug = new char[debugLength];
00611 getInfoLog(gShader, debugLength, &debugLength, debug);
00612
00613 FFATAL(("Couldn't compile geometry program!\n%s\n", debug));
00614 delete [] debug;
00615 deleteObject(gShader);
00616 }
00617 }
00618 else
00619 {
00620 FWARNING(("GL_EXT_geometry_shader4 extension not supported!\n"));
00621 }
00622 }
00623
00624 updateProgramParameters(win);
00625
00626 if(has_vertex || has_fragment || has_geometry)
00627 {
00628 if(has_vertex)
00629 {
00630 attachObject(program, vShader);
00631
00632 deleteObject(vShader);
00633 }
00634
00635 if(has_fragment)
00636 {
00637 attachObject(program, fShader);
00638
00639 deleteObject(fShader);
00640 }
00641
00642 if(has_geometry)
00643 {
00644 attachObject(program, gShader);
00645
00646 deleteObject(gShader);
00647 }
00648
00649 linkProgram(program);
00650
00651 GLint success = 0;
00652 getObjectParameteriv(program, GL_OBJECT_LINK_STATUS_ARB, &success);
00653 char *debug = NULL;
00654 GLint debugLength;
00655 getObjectParameteriv(program, GL_OBJECT_INFO_LOG_LENGTH_ARB, &debugLength);
00656 if(debugLength > 0)
00657 {
00658 debug = new char[debugLength];
00659 debug[0] = 0;
00660 getInfoLog(program, debugLength, &debugLength, debug);
00661 }
00662
00663 if(success)
00664 {
00665 if(debug != NULL && debug[0] != 0)
00666 FWARNING(("SHLChunk: link status: %s\n", debug));
00667 }
00668 else
00669 {
00670 if(debug != NULL && debug[0] != 0)
00671 FFATAL(("Couldn't link vertex and fragment program!\n%s\n", debug));
00672 deleteObject(program);
00673 win->setGLObjectId(getGLId(), 0);
00674 }
00675 if(debug != NULL)
00676 delete [] debug;
00677 }
00678 else
00679 {
00680 deleteObject(program);
00681 win->setGLObjectId(getGLId(), 0);
00682 }
00683
00684
00685 updateParameterLocations(win, getParameters());
00686
00687 updateParameters(win, getParameters());
00688 }
00689
00690 void SHLChunk::updateParameterLocation(Window *win, GLuint program,
00691 const ShaderParameterPtr ¶meter)
00692 {
00693 if(program == 0)
00694 {
00695 FNOTICE(("SHLChunk::updateParameterLocation: program == 0!\n"
00696 "This frame will probably be rendered wrong!\n"));
00697 return;
00698 }
00699
00700
00701 OSGGLGETUNIFORMLOCATIONARBPROC getUniformLocation = (OSGGLGETUNIFORMLOCATIONARBPROC)
00702 win->getFunction(_funcGetUniformLocation);
00703
00704
00705 parameter->setLocation(getUniformLocation(program, parameter->getName().c_str()));
00706 }
00707
00708 void SHLChunk::updateParameterLocations(Window *win,
00709 const MFShaderParameterPtr ¶meters)
00710 {
00711 GLuint program = (GLuint) win->getGLObjectId(getGLId());
00712
00713 if(program == 0)
00714 {
00715 FNOTICE(("SHLChunk::updateParameterLocations: program == 0!\n"
00716 "This frame will probably be rendered wrong!\n"));
00717 return;
00718 }
00719
00720 if(parameters.empty())
00721 return;
00722
00723
00724 OSGGLGETUNIFORMLOCATIONARBPROC getUniformLocation = (OSGGLGETUNIFORMLOCATIONARBPROC)
00725 win->getFunction(_funcGetUniformLocation);
00726
00727 for(UInt32 i = 0; i < parameters.size(); ++i)
00728 {
00729 ShaderParameterPtr parameter = parameters[i];
00730
00731
00732 parameter->setLocation(getUniformLocation(program, parameter->getName().c_str()));
00733 }
00734
00735
00736 checkOSGParameters(true);
00737 }
00738
00739 void SHLChunk::updateParameters(Window *win,
00740 const MFShaderParameterPtr ¶meters,
00741 bool useProgram, bool force,
00742 bool keepProgramActive)
00743 {
00744 GLuint program = (GLuint) win->getGLObjectId(getGLId());
00745
00746 if(program == 0)
00747 {
00748 FNOTICE(("SHLChunk::updateParameters: program == 0!\n"
00749 "This frame will probably be rendered wrong!\n"));
00750 return;
00751 }
00752
00753 checkOSGParameters();
00754
00755 if(parameters.empty())
00756 return;
00757
00758
00759 OSGGLUSEPROGRAMOBJECTARBPROC useProgramObject = (OSGGLUSEPROGRAMOBJECTARBPROC)
00760 win->getFunction(_funcUseProgramObject);
00761
00762 if(useProgram)
00763 useProgramObject(program);
00764
00765 for(UInt32 i = 0; i < parameters.size(); ++i)
00766 {
00767 ShaderParameterPtr parameter = parameters[i];
00768
00769
00770 if(parameter->getName().size() > 3 &&
00771 parameter->getName()[0] == 'O' &&
00772 parameter->getName()[1] == 'S' &&
00773 parameter->getName()[2] == 'G')
00774 {
00775 continue;
00776 }
00777
00778
00779
00780
00781
00782 if(!force)
00783 {
00784 if(!parameter->hasChanged())
00785 continue;
00786 parameter->resetChanged();
00787 }
00788
00789
00790
00791 switch(parameter->getTypeId())
00792 {
00793 case ShaderParameter::SHPTypeBool:
00794 {
00795 ShaderParameterBoolPtr p = ShaderParameterBoolPtr::dcast(parameter);
00796
00797 OSGGLUNIFORM1IARBPROC uniform1i = (OSGGLUNIFORM1IARBPROC)
00798 win->getFunction(_funcUniform1i);
00799
00800
00801 if(p->getLocation() == -1)
00802 updateParameterLocation(win, program, p);
00803 if(p->getLocation() != -1)
00804 uniform1i(p->getLocation(), (GLint) p->getValue());
00805 else
00806 FWARNING(("Unknown parameter '%s'!\n", p->getName().c_str()));
00807 }
00808 break;
00809 case ShaderParameter::SHPTypeInt:
00810 {
00811 ShaderParameterIntPtr p = ShaderParameterIntPtr::dcast(parameter);
00812
00813 OSGGLUNIFORM1IARBPROC uniform1i = (OSGGLUNIFORM1IARBPROC)
00814 win->getFunction(_funcUniform1i);
00815
00816
00817 if(p->getLocation() == -1)
00818 updateParameterLocation(win, program, p);
00819 if(p->getLocation() != -1)
00820 uniform1i(p->getLocation(), p->getValue());
00821 else
00822 FWARNING(("Unknown parameter '%s'!\n", p->getName().c_str()));
00823 }
00824 break;
00825 case ShaderParameter::SHPTypeReal:
00826 {
00827 ShaderParameterRealPtr p = ShaderParameterRealPtr::dcast(parameter);
00828
00829 OSGGLUNIFORM1FARBPROC uniform1f = (OSGGLUNIFORM1FARBPROC)
00830 win->getFunction(_funcUniform1f);
00831
00832
00833 if(p->getLocation() == -1)
00834 updateParameterLocation(win, program, p);
00835 if(p->getLocation() != -1)
00836 uniform1f(p->getLocation(), p->getValue());
00837 else
00838 FWARNING(("Unknown parameter '%s'!\n", p->getName().c_str()));
00839 }
00840 break;
00841 case ShaderParameter::SHPTypeVec2f:
00842 {
00843 ShaderParameterVec2fPtr p = ShaderParameterVec2fPtr::dcast(parameter);
00844
00845 OSGGLUNIFORMFVARBPROC uniform2fv = (OSGGLUNIFORMFVARBPROC)
00846 win->getFunction(_funcUniform2fv);
00847
00848 if(p->getLocation() == -1)
00849 updateParameterLocation(win, program, p);
00850 if(p->getLocation() != -1)
00851 uniform2fv(p->getLocation(), 1, p->getValue().getValues());
00852 else
00853 FWARNING(("Unknown parameter '%s'!\n", p->getName().c_str()));
00854 }
00855 break;
00856 case ShaderParameter::SHPTypeVec3f:
00857 {
00858 ShaderParameterVec3fPtr p = ShaderParameterVec3fPtr::dcast(parameter);
00859
00860 OSGGLUNIFORMFVARBPROC uniform3fv = (OSGGLUNIFORMFVARBPROC)
00861 win->getFunction(_funcUniform3fv);
00862
00863 if(p->getLocation() == -1)
00864 updateParameterLocation(win, program, p);
00865 if(p->getLocation() != -1)
00866 uniform3fv(p->getLocation(), 1, p->getValue().getValues());
00867 else
00868 FWARNING(("Unknown parameter '%s'!\n", p->getName().c_str()));
00869 }
00870 break;
00871 case ShaderParameter::SHPTypeVec4f:
00872 {
00873 ShaderParameterVec4fPtr p = ShaderParameterVec4fPtr::dcast(parameter);
00874
00875 OSGGLUNIFORMFVARBPROC uniform4fv = (OSGGLUNIFORMFVARBPROC)
00876 win->getFunction(_funcUniform4fv);
00877
00878 if(p->getLocation() == -1)
00879 updateParameterLocation(win, program, p);
00880 if(p->getLocation() != -1)
00881 uniform4fv(p->getLocation(), 1, p->getValue().getValues());
00882 else
00883 FWARNING(("Unknown parameter '%s'!\n", p->getName().c_str()));
00884 }
00885 break;
00886 case ShaderParameter::SHPTypeMatrix:
00887 {
00888 ShaderParameterMatrixPtr p = ShaderParameterMatrixPtr::dcast(parameter);
00889
00890 OSGGLUNIFORMMATRIXFVARBPROC uniformMatrix4fv = (OSGGLUNIFORMMATRIXFVARBPROC)
00891 win->getFunction(_funcUniformMatrix4fv);
00892
00893 if(p->getLocation() == -1)
00894 updateParameterLocation(win, program, p);
00895 if(p->getLocation() != -1)
00896 uniformMatrix4fv(p->getLocation(), 1, GL_FALSE, p->getValue().getValues());
00897 else
00898 FWARNING(("Unknown parameter '%s'!\n", p->getName().c_str()));
00899 }
00900 break;
00901
00902 case ShaderParameter::SHPTypeMInt:
00903 {
00904 ShaderParameterMIntPtr p = ShaderParameterMIntPtr::dcast(parameter);
00905
00906 OSGGLUNIFORMIVARBPROC uniform1iv = (OSGGLUNIFORMIVARBPROC)
00907 win->getFunction(_funcUniform1iv);
00908
00909
00910 if(p->getLocation() == -1)
00911 updateParameterLocation(win, program, p);
00912 if(p->getLocation() != -1 && !p->getValue().empty())
00913 ;
00914 else
00915 FWARNING(("Unknown parameter '%s'!\n", p->getName().c_str()));
00916 }
00917 break;
00918 case ShaderParameter::SHPTypeMReal:
00919 {
00920 ShaderParameterMRealPtr p = ShaderParameterMRealPtr::dcast(parameter);
00921
00922 OSGGLUNIFORMFVARBPROC uniform1fv = (OSGGLUNIFORMFVARBPROC)
00923 win->getFunction(_funcUniform1fv);
00924
00925
00926 if(p->getLocation() == -1)
00927 updateParameterLocation(win, program, p);
00928 if(p->getLocation() != -1 && !p->getValue().empty())
00929 uniform1fv(p->getLocation(), p->getValue().getSize(), &p->getValue()[0]);
00930 else
00931 FWARNING(("Unknown parameter '%s'!\n", p->getName().c_str()));
00932 }
00933 break;
00934 case ShaderParameter::SHPTypeMVec2f:
00935 {
00936 ShaderParameterMVec2fPtr p = ShaderParameterMVec2fPtr::dcast(parameter);
00937
00938 OSGGLUNIFORMFVARBPROC uniform2fv = (OSGGLUNIFORMFVARBPROC)
00939 win->getFunction(_funcUniform2fv);
00940
00941 if(p->getLocation() == -1)
00942 updateParameterLocation(win, program, p);
00943
00944 if(p->getLocation() != -1 && !p->getValue().empty())
00945 uniform2fv(p->getLocation(), p->getValue().getSize(), p->getValue()[0].getValues());
00946 else
00947 FWARNING(("Unknown parameter '%s'!\n", p->getName().c_str()));
00948 }
00949 break;
00950 case ShaderParameter::SHPTypeMVec3f:
00951 {
00952 ShaderParameterMVec3fPtr p = ShaderParameterMVec3fPtr::dcast(parameter);
00953
00954 OSGGLUNIFORMFVARBPROC uniform3fv = (OSGGLUNIFORMFVARBPROC)
00955 win->getFunction(_funcUniform3fv);
00956
00957 if(p->getLocation() == -1)
00958 updateParameterLocation(win, program, p);
00959 if(p->getLocation() != -1 && !p->getValue().empty())
00960 uniform3fv(p->getLocation(), p->getValue().getSize(), p->getValue()[0].getValues());
00961 else
00962 FWARNING(("Unknown parameter '%s'!\n", p->getName().c_str()));
00963 }
00964 break;
00965 case ShaderParameter::SHPTypeMVec4f:
00966 {
00967 ShaderParameterMVec4fPtr p = ShaderParameterMVec4fPtr::dcast(parameter);
00968
00969 OSGGLUNIFORMFVARBPROC uniform4fv = (OSGGLUNIFORMFVARBPROC)
00970 win->getFunction(_funcUniform4fv);
00971
00972 if(p->getLocation() == -1)
00973 updateParameterLocation(win, program, p);
00974 if(p->getLocation() != -1 && !p->getValue().empty())
00975 uniform4fv(p->getLocation(), p->getValue().getSize(), p->getValue()[0].getValues());
00976 else
00977 FWARNING(("Unknown parameter '%s'!\n", p->getName().c_str()));
00978 }
00979 break;
00980 case ShaderParameter::SHPTypeMMatrix:
00981 {
00982 ShaderParameterMMatrixPtr p = ShaderParameterMMatrixPtr::dcast(parameter);
00983
00984 OSGGLUNIFORMMATRIXFVARBPROC uniformMatrix4fv = (OSGGLUNIFORMMATRIXFVARBPROC)
00985 win->getFunction(_funcUniformMatrix4fv);
00986
00987 if(p->getLocation() == -1)
00988 updateParameterLocation(win, program, p);
00989 if(p->getLocation() != -1 && !p->getValue().empty())
00990 uniformMatrix4fv(p->getLocation(), p->getValue().getSize(), GL_FALSE, p->getValue()[0].getValues());
00991 else
00992 FWARNING(("Unknown parameter '%s'!\n", p->getName().c_str()));
00993 }
00994 break;
00995 default:
00996 FWARNING(("Parameter '%s' has unknown type %d!\n", parameter->getName().c_str(),
00997 parameter->getTypeId()));
00998 break;
00999 }
01000 }
01001
01002 if(useProgram && !keepProgramActive)
01003 useProgramObject(0);
01004 }
01005
01006 void SHLChunk::updateProgramParameters(Window *win)
01007 {
01008 if(!win->hasExtension(_geometry_extension))
01009 return;
01010
01011 GLuint program = (GLuint) win->getGLObjectId(getGLId());
01012
01013 if(program == 0)
01014 {
01015 FNOTICE(("SHLChunk::updateParameters: program == 0!\n"
01016 "This frame will probably be rendered wrong!\n"));
01017 return;
01018 }
01019
01020
01021 OSGGLPROGRAMPARAMETERIEXTPROC programParameteri =
01022 (OSGGLPROGRAMPARAMETERIEXTPROC) win->getFunction(_funcProgramParameteri);
01023
01024
01025 const MFGLenum &ppnames = getProgramParameterNames();
01026 const MFUInt32 &ppvalues = getProgramParameterValues();
01027 for(UInt32 i = 0; i < ppnames.size(); ++i)
01028 {
01029 if(i < ppvalues.size()) {
01030 programParameteri(program, ppnames[i], ppvalues[i]);
01031 }
01032 }
01033 }
01034
01035 void SHLChunk::checkOSGParameters(bool force)
01036 {
01037
01038
01039 if(!force &&
01040 getParameters().getSize() == _oldParameterSize)
01041 return;
01042
01043 _oldParameterSize = getParameters().getSize();
01044
01045 _osgParametersCallbacks.clear();
01046 const MFShaderParameterPtr ¶meters = getParameters();
01047 for(UInt32 i = 0; i < parameters.size(); ++i)
01048 {
01049 ShaderParameterPtr parameter = parameters[i];
01050 if(parameter->getName().size() > 3 &&
01051 parameter->getName()[0] == 'O' &&
01052 parameter->getName()[1] == 'S' &&
01053 parameter->getName()[2] == 'G')
01054 {
01055 if(parameter->getName() == "OSGWorldMatrix")
01056 {
01057
01058 parametercbfp oldfp = NULL;
01059 osgparametercbfp fp = updateWorldMatrix;
01060 _osgParametersCallbacks.push_back(
01061 std::make_pair(std::make_pair(oldfp, fp), parameter));
01062 }
01063 else if(parameter->getName() == "OSGInvWorldMatrix")
01064 {
01065 parametercbfp oldfp = NULL;
01066 osgparametercbfp fp = updateInvWorldMatrix;
01067 _osgParametersCallbacks.push_back(
01068 std::make_pair(std::make_pair(oldfp, fp), parameter));
01069 }
01070 else if(parameter->getName() == "OSGTransInvWorldMatrix")
01071 {
01072 parametercbfp oldfp = NULL;
01073 osgparametercbfp fp = updateTransInvWorldMatrix;
01074 _osgParametersCallbacks.push_back(
01075 std::make_pair(std::make_pair(oldfp, fp), parameter));
01076 }
01077 else if(parameter->getName() == "OSGCameraOrientation")
01078 {
01079 parametercbfp oldfp = NULL;
01080 osgparametercbfp fp = updateCameraOrientation;
01081 _osgParametersCallbacks.push_back(
01082 std::make_pair(std::make_pair(oldfp, fp), parameter));
01083 }
01084 else if(parameter->getName() == "OSGCameraPosition")
01085 {
01086 parametercbfp oldfp = NULL;
01087 osgparametercbfp fp = updateCameraPosition;
01088 _osgParametersCallbacks.push_back(
01089 std::make_pair(std::make_pair(oldfp, fp), parameter));
01090 }
01091 else if(parameter->getName() == "OSGViewMatrix")
01092 {
01093 parametercbfp oldfp = NULL;
01094 osgparametercbfp fp = updateViewMatrix;
01095 _osgParametersCallbacks.push_back(
01096 std::make_pair(std::make_pair(oldfp, fp), parameter));
01097 }
01098 else if(parameter->getName() == "OSGInvViewMatrix")
01099 {
01100 parametercbfp oldfp = NULL;
01101 osgparametercbfp fp = updateInvViewMatrix;
01102 _osgParametersCallbacks.push_back(
01103 std::make_pair(std::make_pair(oldfp, fp), parameter));
01104 }
01105 else if(parameter->getName() == "OSGStereoLeftEye")
01106 {
01107 parametercbfp oldfp = NULL;
01108 osgparametercbfp fp = updateStereoLeftEye;
01109 _osgParametersCallbacks.push_back(
01110 std::make_pair(std::make_pair(oldfp, fp), parameter));
01111 }
01112 else if(parameter->getName() == "OSGClusterId")
01113 {
01114 parametercbfp oldfp = NULL;
01115 osgparametercbfp fp = updateClusterId;
01116 _osgParametersCallbacks.push_back(
01117 std::make_pair(std::make_pair(oldfp, fp), parameter));
01118 }
01119 else if(parameter->getName() == "OSGActiveLightsMask")
01120 {
01121 parametercbfp oldfp = NULL;
01122 osgparametercbfp fp = updateActiveLightsMask;
01123 _osgParametersCallbacks.push_back(
01124 std::make_pair(std::make_pair(oldfp, fp), parameter));
01125 }
01126 else if(parameter->getName() == "OSGLight0Active")
01127 {
01128 parametercbfp oldfp = NULL;
01129 osgparametercbfp fp = updateLight0Active;
01130 _osgParametersCallbacks.push_back(
01131 std::make_pair(std::make_pair(oldfp, fp), parameter));
01132 }
01133 else if(parameter->getName() == "OSGLight1Active")
01134 {
01135 parametercbfp oldfp = NULL;
01136 osgparametercbfp fp = updateLight1Active;
01137 _osgParametersCallbacks.push_back(
01138 std::make_pair(std::make_pair(oldfp, fp), parameter));
01139 }
01140 else if(parameter->getName() == "OSGLight2Active")
01141 {
01142 parametercbfp oldfp = NULL;
01143 osgparametercbfp fp = updateLight2Active;
01144 _osgParametersCallbacks.push_back(
01145 std::make_pair(std::make_pair(oldfp, fp), parameter));
01146 }
01147 else if(parameter->getName() == "OSGLight3Active")
01148 {
01149 parametercbfp oldfp = NULL;
01150 osgparametercbfp fp = updateLight3Active;
01151 _osgParametersCallbacks.push_back(
01152 std::make_pair(std::make_pair(oldfp, fp), parameter));
01153 }
01154 else if(parameter->getName() == "OSGLight4Active")
01155 {
01156 parametercbfp oldfp = NULL;
01157 osgparametercbfp fp = updateLight4Active;
01158 _osgParametersCallbacks.push_back(
01159 std::make_pair(std::make_pair(oldfp, fp), parameter));
01160 }
01161 else if(parameter->getName() == "OSGLight5Active")
01162 {
01163 parametercbfp oldfp = NULL;
01164 osgparametercbfp fp = updateLight5Active;
01165 _osgParametersCallbacks.push_back(
01166 std::make_pair(std::make_pair(oldfp, fp), parameter));
01167 }
01168 else if(parameter->getName() == "OSGLight6Active")
01169 {
01170 parametercbfp oldfp = NULL;
01171 osgparametercbfp fp = updateLight6Active;
01172 _osgParametersCallbacks.push_back(
01173 std::make_pair(std::make_pair(oldfp, fp), parameter));
01174 }
01175 else if(parameter->getName() == "OSGLight7Active")
01176 {
01177 parametercbfp oldfp = NULL;
01178 osgparametercbfp fp = updateLight7Active;
01179 _osgParametersCallbacks.push_back(
01180 std::make_pair(std::make_pair(oldfp, fp), parameter));
01181 }
01182 else
01183 {
01184
01185 userParameterCallbacksMap::iterator it =
01186 _userParameterCallbacks.find(parameter->getName());
01187 if(it != _userParameterCallbacks.end())
01188 {
01189 parametercbfp oldfp = (*it).second.first;
01190 osgparametercbfp fp = (*it).second.second;
01191
01192 _osgParametersCallbacks.push_back(
01193 std::make_pair(std::make_pair(oldfp, fp), parameter));
01194 }
01195 else
01196 {
01197 FWARNING(("SHLChunk::checkOSGParameters : unknown osg parameter '%s'\n",
01198 parameter->getName().c_str()));
01199 }
01200 }
01201 }
01202 }
01203 }
01204
01205 void SHLChunk::addParameterCallback(const char *name, parametercbfp fp)
01206 {
01207 if(name == NULL || fp == NULL)
01208 return;
01209
01210
01211
01212 osgparametercbfp nullfp = NULL;
01213
01214 setUniformParameter(name, 0);
01215 _userParameterCallbacks.insert(
01216 std::make_pair(name, std::make_pair(fp, nullfp)));
01217 }
01218
01219 void SHLChunk::addParameterCallback(const char *name, osgparametercbfp fp)
01220 {
01221 if(name == NULL || fp == NULL)
01222 return;
01223
01224
01225
01226 parametercbfp nullfp = NULL;
01227
01228 setUniformParameter(name, 0);
01229 _userParameterCallbacks.insert(
01230 std::make_pair(name, std::make_pair(nullfp, fp)));
01231 }
01232
01233 void SHLChunk::setParameterCallback(parametercbfp fp)
01234 {
01235 _userParametersCallback = fp;
01236 }
01237
01238 void SHLChunk::addProgramParameter(GLenum name, UInt32 value)
01239 {
01240 getProgramParameterNames().push_back(name);
01241 getProgramParameterValues().push_back(value);
01242 }
01243
01244 void SHLChunk::subProgramParameter(GLenum name)
01245 {
01246 MFGLenum &ppnames = getProgramParameterNames();
01247 MFUInt32 &ppvalues = getProgramParameterValues();
01248
01249 for(UInt32 i = 0; i < ppnames.size(); ++i)
01250 {
01251 if(ppnames[i] == name && i < ppvalues.size())
01252 {
01253 ppnames.erase(ppnames.begin() + i);
01254 ppvalues.erase(ppvalues.begin() + i);
01255 break;
01256 }
01257 }
01258 }
01259
01260 void SHLChunk::setProgramParameter(GLenum name, UInt32 value)
01261 {
01262
01263 subProgramParameter(name);
01264
01265 addProgramParameter(name, value);
01266 }
01267
01268 UInt32 SHLChunk::getProgramParameter(GLenum name)
01269 {
01270 const MFGLenum &ppnames = getProgramParameterNames();
01271 const MFUInt32 &ppvalues = getProgramParameterValues();
01272
01273 for(UInt32 i = 0; i < ppnames.size(); ++i)
01274 {
01275 if(ppnames[i] == name && i < ppvalues.size())
01276 return ppvalues[i];
01277 }
01278 FWARNING(("SHLChunk::getProgramParameter : Couldn't find program parameter %u!\n",
01279 name));
01280 return 0;
01281 }
01282
01283 std::vector<std::pair<GLenum, UInt32> > SHLChunk::getProgramParameters(void)
01284 {
01285 std::vector<std::pair<GLenum, UInt32> > parameters;
01286
01287 const MFGLenum &ppnames = getProgramParameterNames();
01288 const MFUInt32 &ppvalues = getProgramParameterValues();
01289
01290 for(UInt32 i = 0; i < ppnames.size(); ++i)
01291 {
01292 if(i < ppvalues.size())
01293 parameters.push_back(std::make_pair(ppnames[i], ppvalues[i]));
01294 }
01295
01296 return parameters;
01297 }
01298
01299 void SHLChunk::clearProgramParameters(void)
01300 {
01301 getProgramParameterNames().clear();
01302 getProgramParameterValues().clear();
01303 }
01304
01305 void SHLChunk::updateOSGParameters(DrawActionBase *action, GLuint program,
01306 bool update)
01307 {
01308
01309 OSGGLGETUNIFORMLOCATIONARBPROC getUniformLocation = (OSGGLGETUNIFORMLOCATIONARBPROC)
01310 action->getWindow()->getFunction(_funcGetUniformLocation);
01311
01312 if(_userParametersCallback != NULL)
01313 _userParametersCallback(getUniformLocation, action, program);
01314
01315 if(_osgParametersCallbacks.empty())
01316 return;
01317
01318 for(UInt32 i=0;i<_osgParametersCallbacks.size();++i)
01319 {
01320 parametercbfp oldfp = _osgParametersCallbacks[i].first.first;
01321 osgparametercbfp fp = _osgParametersCallbacks[i].first.second;
01322 if(oldfp != NULL)
01323 {
01324 oldfp(getUniformLocation, action, program);
01325 }
01326 else if(fp != NULL)
01327 {
01328
01329
01330
01331 ShaderParameterPtr parameter = _osgParametersCallbacks[i].second;
01332 parameter->setFlags(update ? ShaderParameter::SHPFlagUpdate :
01333 ShaderParameter::SHPFlagNone);
01334 fp(parameter, action, program);
01335 }
01336 }
01337 }
01338
01339 void SHLChunk::updateWorldMatrix(const ShaderParameterPtr ¶meter,
01340 DrawActionBase *action, GLuint program)
01341 {
01342
01343
01344 if(action->getCamera() == NULL || action->getViewport() == NULL)
01345 {
01346 FWARNING(("SHLChunk::updateWorldMatrix : Can't update OSGWorldMatrix"
01347 "parameter, camera or viewport is NULL!\n"));
01348 return;
01349 }
01350
01351 Matrix m;
01352 RenderAction *ra = dynamic_cast<RenderAction *>(action);
01353 if(ra != NULL)
01354 m = ra->top_matrix();
01355
01356
01357 OSGGLUNIFORMMATRIXFVARBPROC uniformMatrix4fv = (OSGGLUNIFORMMATRIXFVARBPROC)
01358 action->getWindow()->getFunction(_funcUniformMatrix4fv);
01359 if(parameter->getLocation() == -1)
01360 updateParameterLocation(action->getWindow(), program, parameter);
01361 if(parameter->getLocation() != -1)
01362 uniformMatrix4fv(parameter->getLocation(), 1, GL_FALSE, m.getValues());
01363 }
01364
01365 void SHLChunk::updateInvWorldMatrix(const ShaderParameterPtr ¶meter,
01366 DrawActionBase *action, GLuint program)
01367 {
01368
01369
01370 if(action->getCamera() == NULL || action->getViewport() == NULL)
01371 {
01372 FWARNING(("SHLChunk::updateInvWorldMatrix : Can't update OSGInvWorldMatrix"
01373 "parameter, camera or viewport is NULL!\n"));
01374 return;
01375 }
01376
01377 Matrix m;
01378 RenderAction *ra = dynamic_cast<RenderAction *>(action);
01379 if(ra != NULL)
01380 m = ra->top_matrix();
01381 m.invert();
01382
01383
01384 OSGGLUNIFORMMATRIXFVARBPROC uniformMatrix4fv = (OSGGLUNIFORMMATRIXFVARBPROC)
01385 action->getWindow()->getFunction(_funcUniformMatrix4fv);
01386 if(parameter->getLocation() == -1)
01387 updateParameterLocation(action->getWindow(), program, parameter);
01388 if(parameter->getLocation() != -1)
01389 uniformMatrix4fv(parameter->getLocation(), 1, GL_FALSE, m.getValues());
01390 }
01391
01392 void SHLChunk::updateTransInvWorldMatrix(const ShaderParameterPtr ¶meter,
01393 DrawActionBase *action, GLuint program)
01394 {
01395
01396
01397 if(action->getCamera() == NULL || action->getViewport() == NULL)
01398 {
01399 FWARNING(("SHLChunk::updateTransInvWorldMatrix : Can't update OSGTransInvWorldMatrix"
01400 "parameter, camera or viewport is NULL!\n"));
01401 return;
01402 }
01403
01404 Matrix m;
01405 RenderAction *ra = dynamic_cast<RenderAction *>(action);
01406 if(ra != NULL)
01407 m = ra->top_matrix();
01408 m.invert();
01409 m.transpose();
01410
01411
01412 OSGGLUNIFORMMATRIXFVARBPROC uniformMatrix4fv = (OSGGLUNIFORMMATRIXFVARBPROC)
01413 action->getWindow()->getFunction(_funcUniformMatrix4fv);
01414 if(parameter->getLocation() == -1)
01415 updateParameterLocation(action->getWindow(), program, parameter);
01416 if(parameter->getLocation() != -1)
01417 uniformMatrix4fv(parameter->getLocation(), 1, GL_FALSE, m.getValues());
01418 }
01419
01420 void SHLChunk::updateCameraOrientation(const ShaderParameterPtr ¶meter,
01421 DrawActionBase *action, GLuint program)
01422 {
01423
01424 if(parameter->getFlags() & ShaderParameter::SHPFlagUpdate)
01425 return;
01426
01427 if(action->getCamera() == NULL || action->getViewport() == NULL)
01428 {
01429 FWARNING(("SHLChunk::updateCameraOrientation : Can't update OSGCameraOrientation"
01430 "parameter, camera or viewport is NULL!\n"));
01431 return;
01432 }
01433
01434 Matrix m;
01435 action->getCamera()->getViewing(m,
01436 action->getViewport()->getPixelWidth(),
01437 action->getViewport()->getPixelHeight());
01438 m.invert();
01439 m[3].setValues(0, 0, 0, 1);
01440
01441
01442 OSGGLUNIFORMMATRIXFVARBPROC uniformMatrix4fv = (OSGGLUNIFORMMATRIXFVARBPROC)
01443 action->getWindow()->getFunction(_funcUniformMatrix4fv);
01444 if(parameter->getLocation() == -1)
01445 updateParameterLocation(action->getWindow(), program, parameter);
01446 if(parameter->getLocation() != -1)
01447 uniformMatrix4fv(parameter->getLocation(), 1, GL_FALSE, m.getValues());
01448 }
01449
01450 void SHLChunk::updateCameraPosition(const ShaderParameterPtr ¶meter,
01451 DrawActionBase *action, GLuint program)
01452 {
01453 if(parameter->getFlags() & ShaderParameter::SHPFlagUpdate)
01454 return;
01455
01456 if(action->getCamera() == NULL || action->getViewport() == NULL)
01457 {
01458 FWARNING(("SHLChunk::updateCameraPosition : Can't update OSGCameraPosition"
01459 "parameter, camera or viewport is NULL!\n"));
01460 return;
01461 }
01462
01463 Matrix m;
01464 action->getCamera()->getViewing(m,
01465 action->getViewport()->getPixelWidth(),
01466 action->getViewport()->getPixelHeight());
01467 m.invert();
01468 Vec3f cameraPos(m[3][0], m[3][1], m[3][2]);
01469
01470
01471 OSGGLUNIFORMFVARBPROC uniform3fv = (OSGGLUNIFORMFVARBPROC)
01472 action->getWindow()->getFunction(_funcUniform3fv);
01473 if(parameter->getLocation() == -1)
01474 updateParameterLocation(action->getWindow(), program, parameter);
01475 if(parameter->getLocation() != -1)
01476 uniform3fv(parameter->getLocation(), 1, cameraPos.getValues());
01477 }
01478
01479 void SHLChunk::updateViewMatrix(const ShaderParameterPtr ¶meter,
01480 DrawActionBase *action, GLuint program)
01481 {
01482 if(parameter->getFlags() & ShaderParameter::SHPFlagUpdate)
01483 return;
01484
01485 if(action->getCamera() == NULL || action->getViewport() == NULL)
01486 {
01487 FWARNING(("SHLChunk::updateViewMatrix : Can't update OSGViewMatrix"
01488 "parameter, camera or viewport is NULL!\n"));
01489 return;
01490 }
01491
01492 Matrix m;
01493 action->getCamera()->getViewing(m,
01494 action->getViewport()->getPixelWidth(),
01495 action->getViewport()->getPixelHeight());
01496
01497
01498 OSGGLUNIFORMMATRIXFVARBPROC uniformMatrix4fv = (OSGGLUNIFORMMATRIXFVARBPROC)
01499 action->getWindow()->getFunction(_funcUniformMatrix4fv);
01500 if(parameter->getLocation() == -1)
01501 updateParameterLocation(action->getWindow(), program, parameter);
01502 if(parameter->getLocation() != -1)
01503 uniformMatrix4fv(parameter->getLocation(), 1, GL_FALSE, m.getValues());
01504 }
01505
01506 void SHLChunk::updateInvViewMatrix(const ShaderParameterPtr ¶meter,
01507 DrawActionBase *action, GLuint program)
01508 {
01509 if(parameter->getFlags() & ShaderParameter::SHPFlagUpdate)
01510 return;
01511
01512 if(action->getCamera() == NULL || action->getViewport() == NULL)
01513 {
01514 FWARNING(("SHLChunk::updateInvViewMatrix : Can't update OSGInvViewMatrix"
01515 "parameter, camera or viewport is NULL!\n"));
01516 return;
01517 }
01518
01519 Matrix m;
01520 action->getCamera()->getViewing(m,
01521 action->getViewport()->getPixelWidth(),
01522 action->getViewport()->getPixelHeight());
01523 m.invert();
01524
01525
01526 OSGGLUNIFORMMATRIXFVARBPROC uniformMatrix4fv = (OSGGLUNIFORMMATRIXFVARBPROC)
01527 action->getWindow()->getFunction(_funcUniformMatrix4fv);
01528 if(parameter->getLocation() == -1)
01529 updateParameterLocation(action->getWindow(), program, parameter);
01530 if(parameter->getLocation() != -1)
01531 uniformMatrix4fv(parameter->getLocation(), 1, GL_FALSE, m.getValues());
01532 }
01533
01534 void SHLChunk::updateStereoLeftEye(const ShaderParameterPtr ¶meter,
01535 DrawActionBase *action, GLuint program)
01536 {
01537 if(parameter->getFlags() & ShaderParameter::SHPFlagUpdate)
01538 return;
01539
01540 if(action->getCamera() == NULL || action->getViewport() == NULL)
01541 {
01542 FWARNING(("SHLChunk::updateStereoLeftEye : Can't update OSGStereoLeftEye"
01543 "parameter, camera or viewport is NULL!\n"));
01544 return;
01545 }
01546
01547
01548 Int32 leftEye = -1;
01549
01550 CameraPtr camera(*action->getCamera());
01551 CameraDecoratorPtr decorator = CameraDecoratorPtr::dcast(camera);
01552 while(decorator != NullFC)
01553 {
01554 StereoCameraDecoratorPtr stereoDecorator = StereoCameraDecoratorPtr::dcast(decorator);
01555 if(stereoDecorator != NullFC)
01556 {
01557 if(stereoDecorator->getLeftEye())
01558 leftEye = 1;
01559 else
01560 leftEye = 0;
01561 break;
01562 }
01563 decorator = CameraDecoratorPtr::dcast(decorator->getDecoratee());
01564 }
01565
01566
01567 OSGGLUNIFORM1IARBPROC uniform1i = (OSGGLUNIFORM1IARBPROC)
01568 action->getWindow()->getFunction(_funcUniform1i);
01569 if(parameter->getLocation() == -1)
01570 updateParameterLocation(action->getWindow(), program, parameter);
01571 if(parameter->getLocation() != -1)
01572 uniform1i(parameter->getLocation(), leftEye);
01573 }
01574
01575 void SHLChunk::setClusterId(Int32 id)
01576 {
01577 _clusterId = id;
01578 }
01579
01580 void SHLChunk::updateClusterId(const ShaderParameterPtr ¶meter,
01581 DrawActionBase *action, GLuint program)
01582 {
01583 if(parameter->getFlags() & ShaderParameter::SHPFlagUpdate)
01584 return;
01585
01586
01587 OSGGLUNIFORM1IARBPROC uniform1i = (OSGGLUNIFORM1IARBPROC)
01588 action->getWindow()->getFunction(_funcUniform1i);
01589 if(parameter->getLocation() == -1)
01590 updateParameterLocation(action->getWindow(), program, parameter);
01591 if(parameter->getLocation() != -1)
01592 uniform1i(parameter->getLocation(), (GLint) _clusterId);
01593 }
01594
01595 void SHLChunk::updateActiveLightsMask(const ShaderParameterPtr ¶meter,
01596 DrawActionBase *action, GLuint program)
01597 {
01598 RenderAction *ract = (RenderAction *) action;
01599
01600
01601 OSGGLUNIFORM1IARBPROC uniform1i = (OSGGLUNIFORM1IARBPROC)
01602 action->getWindow()->getFunction(_funcUniform1i);
01603 if(parameter->getLocation() == -1)
01604 updateParameterLocation(action->getWindow(), program, parameter);
01605 if(parameter->getLocation() != -1)
01606 uniform1i(parameter->getLocation(), (GLint) ract->getActiveLightsMask());
01607 }
01608
01609 void SHLChunk::updateLight0Active(const ShaderParameterPtr ¶meter,
01610 DrawActionBase *action, GLuint program)
01611 {
01612 RenderAction *ract = (RenderAction *) action;
01613
01614
01615 OSGGLUNIFORM1IARBPROC uniform1i = (OSGGLUNIFORM1IARBPROC)
01616 action->getWindow()->getFunction(_funcUniform1i);
01617 if(parameter->getLocation() == -1)
01618 updateParameterLocation(action->getWindow(), program, parameter);
01619 if(parameter->getLocation() != -1)
01620 uniform1i(parameter->getLocation(), (GLint) ract->getActiveLightsMask() & 1);
01621 }
01622
01623 void SHLChunk::updateLight1Active(const ShaderParameterPtr ¶meter,
01624 DrawActionBase *action, GLuint program)
01625 {
01626 RenderAction *ract = (RenderAction *) action;
01627
01628
01629 OSGGLUNIFORM1IARBPROC uniform1i = (OSGGLUNIFORM1IARBPROC)
01630 action->getWindow()->getFunction(_funcUniform1i);
01631 if(parameter->getLocation() == -1)
01632 updateParameterLocation(action->getWindow(), program, parameter);
01633 if(parameter->getLocation() != -1)
01634 uniform1i(parameter->getLocation(), (GLint) ract->getActiveLightsMask() & 2);
01635 }
01636
01637 void SHLChunk::updateLight2Active(const ShaderParameterPtr ¶meter,
01638 DrawActionBase *action, GLuint program)
01639 {
01640 RenderAction *ract = (RenderAction *) action;
01641
01642
01643 OSGGLUNIFORM1IARBPROC uniform1i = (OSGGLUNIFORM1IARBPROC)
01644 action->getWindow()->getFunction(_funcUniform1i);
01645 if(parameter->getLocation() == -1)
01646 updateParameterLocation(action->getWindow(), program, parameter);
01647 if(parameter->getLocation() != -1)
01648 uniform1i(parameter->getLocation(), (GLint) ract->getActiveLightsMask() & 4);
01649 }
01650
01651 void SHLChunk::updateLight3Active(const ShaderParameterPtr ¶meter,
01652 DrawActionBase *action, GLuint program)
01653 {
01654 RenderAction *ract = (RenderAction *) action;
01655
01656
01657 OSGGLUNIFORM1IARBPROC uniform1i = (OSGGLUNIFORM1IARBPROC)
01658 action->getWindow()->getFunction(_funcUniform1i);
01659 if(parameter->getLocation() == -1)
01660 updateParameterLocation(action->getWindow(), program, parameter);
01661 if(parameter->getLocation() != -1)
01662 uniform1i(parameter->getLocation(), (GLint) ract->getActiveLightsMask() & 8);
01663 }
01664
01665 void SHLChunk::updateLight4Active(const ShaderParameterPtr ¶meter,
01666 DrawActionBase *action, GLuint program)
01667 {
01668 RenderAction *ract = (RenderAction *) action;
01669
01670
01671 OSGGLUNIFORM1IARBPROC uniform1i = (OSGGLUNIFORM1IARBPROC)
01672 action->getWindow()->getFunction(_funcUniform1i);
01673 if(parameter->getLocation() == -1)
01674 updateParameterLocation(action->getWindow(), program, parameter);
01675 if(parameter->getLocation() != -1)
01676 uniform1i(parameter->getLocation(), (GLint) ract->getActiveLightsMask() & 16);
01677 }
01678
01679 void SHLChunk::updateLight5Active(const ShaderParameterPtr ¶meter,
01680 DrawActionBase *action, GLuint program)
01681 {
01682 RenderAction *ract = (RenderAction *) action;
01683
01684
01685 OSGGLUNIFORM1IARBPROC uniform1i = (OSGGLUNIFORM1IARBPROC)
01686 action->getWindow()->getFunction(_funcUniform1i);
01687 if(parameter->getLocation() == -1)
01688 updateParameterLocation(action->getWindow(), program, parameter);
01689 if(parameter->getLocation() != -1)
01690 uniform1i(parameter->getLocation(), (GLint) ract->getActiveLightsMask() & 32);
01691 }
01692
01693 void SHLChunk::updateLight6Active(const ShaderParameterPtr ¶meter,
01694 DrawActionBase *action, GLuint program)
01695 {
01696 RenderAction *ract = (RenderAction *) action;
01697
01698
01699 OSGGLUNIFORM1IARBPROC uniform1i = (OSGGLUNIFORM1IARBPROC)
01700 action->getWindow()->getFunction(_funcUniform1i);
01701 if(parameter->getLocation() == -1)
01702 updateParameterLocation(action->getWindow(), program, parameter);
01703 if(parameter->getLocation() != -1)
01704 uniform1i(parameter->getLocation(), (GLint) ract->getActiveLightsMask() & 64);
01705 }
01706
01707 void SHLChunk::updateLight7Active(const ShaderParameterPtr ¶meter,
01708 DrawActionBase *action, GLuint program)
01709 {
01710 RenderAction *ract = (RenderAction *) action;
01711
01712
01713 OSGGLUNIFORM1IARBPROC uniform1i = (OSGGLUNIFORM1IARBPROC)
01714 action->getWindow()->getFunction(_funcUniform1i);
01715 if(parameter->getLocation() == -1)
01716 updateParameterLocation(action->getWindow(), program, parameter);
01717 if(parameter->getLocation() != -1)
01718 uniform1i(parameter->getLocation(), (GLint) ract->getActiveLightsMask() & 128);
01719 }
01720
01721
01722
01723 void SHLChunk::update(DrawActionBase *action)
01724 {
01725 action->getWindow()->validateGLObject(getGLId());
01726
01727 GLuint program = (GLuint) action->getWindow()->getGLObjectId(getGLId());
01728 if(program == 0)
01729 return;
01730
01731 updateOSGParameters(action, program, true);
01732 }
01733
01734 void SHLChunk::activate(DrawActionBase *action, UInt32 )
01735 {
01736
01737 action->getWindow()->validateGLObject(getGLId());
01738
01739 GLuint program = (GLuint) action->getWindow()->getGLObjectId(getGLId());
01740 if(program == 0)
01741 return;
01742
01743
01744
01745
01746 OSGGLUSEPROGRAMOBJECTARBPROC useProgramObject = (OSGGLUSEPROGRAMOBJECTARBPROC)
01747 action->getWindow()->getFunction(_funcUseProgramObject);
01748
01749 useProgramObject(program);
01750
01751 updateOSGParameters(action, program);
01752
01753 if(getPointSize())
01754 {
01755 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
01756 }
01757 }
01758
01759 void SHLChunk::changeFrom(DrawActionBase *action, StateChunk * old_chunk,
01760 UInt32 )
01761 {
01762 SHLChunk *old = dynamic_cast<SHLChunk *>(old_chunk);
01763
01764 if(old == NULL)
01765 {
01766 FWARNING(( "SHLChunk::changeFrom: caught non-SHLChunk!\n"));
01767 return;
01768 }
01769
01770
01771 if(old == this)
01772 return;
01773
01774 action->getWindow()->validateGLObject(getGLId());
01775
01776
01777 OSGGLUSEPROGRAMOBJECTARBPROC useProgramObject = (OSGGLUSEPROGRAMOBJECTARBPROC)
01778 action->getWindow()->getFunction(_funcUseProgramObject);
01779
01780
01781
01782 GLuint program = (GLuint) action->getWindow()->getGLObjectId(getGLId());
01783
01784 if(program != 0)
01785 {
01786 useProgramObject(program);
01787 updateOSGParameters(action, program);
01788
01789 if(getPointSize())
01790 {
01791 if(!old->getPointSize())
01792 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
01793 }
01794 else
01795 {
01796 if(old->getPointSize())
01797 glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
01798 }
01799 }
01800 else
01801 {
01802 if(action->getWindow()->getGLObjectId(old->getGLId()) != 0)
01803 useProgramObject(0);
01804 }
01805 }
01806
01807
01808 void SHLChunk::deactivate(DrawActionBase *action, UInt32 )
01809 {
01810 if(action->getWindow()->getGLObjectId(getGLId()) == 0)
01811 return;
01812
01813
01814 OSGGLUSEPROGRAMOBJECTARBPROC useProgramObject = (OSGGLUSEPROGRAMOBJECTARBPROC)
01815 action->getWindow()->getFunction(_funcUseProgramObject);
01816
01817 useProgramObject(0);
01818
01819 if(getPointSize())
01820 {
01821 glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
01822 }
01823 }
01824
01825
01826
01827 Real32 SHLChunk::switchCost(StateChunk *OSG_CHECK_ARG(chunk))
01828 {
01829 return 0;
01830 }
01831
01832 bool SHLChunk::operator < (const StateChunk &other) const
01833 {
01834 return this < &other;
01835 }
01836
01837 bool SHLChunk::operator == (const StateChunk &other) const
01838 {
01839 SHLChunk const *tother = dynamic_cast<SHLChunk const*>(&other);
01840
01841 if(!tother)
01842 return false;
01843
01844 if(getVertexProgram() != tother->getVertexProgram() ||
01845 getFragmentProgram() != tother->getFragmentProgram() ||
01846 getParameters().size() != tother->getParameters().size())
01847 return false;
01848
01849 return true;
01850 }
01851
01852 bool SHLChunk::operator != (const StateChunk &other) const
01853 {
01854 return ! (*this == other);
01855 }
01856
01857
01858
01859
01860 #ifdef OSG_SGI_CC
01861 #pragma set woff 1174
01862 #endif
01863
01864 #ifdef OSG_LINUX_ICC
01865 #pragma warning( disable : 177 )
01866 #endif
01867
01868 namespace
01869 {
01870 static Char8 cvsid_cpp [] = "@(#)$Id: OSGSHLChunk.cpp,v 1.59 2007/03/12 19:46:39 jbehr Exp $";
01871 static Char8 cvsid_hpp [] = OSGSHLCHUNKBASE_HEADER_CVSID;
01872 static Char8 cvsid_inl [] = OSGSHLCHUNKBASE_INLINE_CVSID;
01873
01874 static Char8 cvsid_fields_hpp[] = OSGSHLCHUNKFIELDS_HEADER_CVSID;
01875 }
01876
01877 #ifdef __sgi
01878 #pragma reset woff 1174
01879 #endif