Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

OSGSHLChunk.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *               Copyright (C) 2000-2002 by the OpenSG Forum                 *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038 
00039 //---------------------------------------------------------------------------
00040 //  Includes
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 "OSGSHLChunk.h"
00067 
00068 OSG_USING_NAMESPACE
00069 
00074 /***************************************************************************\
00075  *                           Class variables                               *
00076 \***************************************************************************/
00077 
00078 StateChunkClass SHLChunk::_class("SHL");
00079 
00080 UInt32 SHLChunk::_shl_extension;
00081 UInt32 SHLChunk::_cg_extension;
00082 
00083 UInt32 SHLChunk::_funcCreateProgramObject = Window::invalidFunctionID;
00084 UInt32 SHLChunk::_funcCreateShaderObject = Window::invalidFunctionID;
00085 UInt32 SHLChunk::_funcDeleteObject = Window::invalidFunctionID;
00086 UInt32 SHLChunk::_funcDetachObject = Window::invalidFunctionID;
00087 UInt32 SHLChunk::_funcAttachObject = Window::invalidFunctionID;
00088 
00089 UInt32 SHLChunk::_funcShaderSource = Window::invalidFunctionID;
00090 UInt32 SHLChunk::_funcCompileShader = Window::invalidFunctionID;
00091 UInt32 SHLChunk::_funcLinkProgram = Window::invalidFunctionID;
00092 UInt32 SHLChunk::_funcGetInfoLog = Window::invalidFunctionID;
00093 UInt32 SHLChunk::_funcUseProgramObject = Window::invalidFunctionID;
00094 
00095 UInt32 SHLChunk::_funcGetObjectParameteriv = Window::invalidFunctionID;
00096 UInt32 SHLChunk::_funcGetObjectParameterfv = Window::invalidFunctionID;
00097 UInt32 SHLChunk::_funcGetUniformLocation = Window::invalidFunctionID;
00098 
00099 UInt32 SHLChunk::_funcBindAttribLocation = Window::invalidFunctionID;
00100 UInt32 SHLChunk::_funcGetAttribLocation = Window::invalidFunctionID;
00101 
00102 UInt32 SHLChunk::_funcUniform1i = Window::invalidFunctionID;
00103 UInt32 SHLChunk::_funcUniform2iv = Window::invalidFunctionID;
00104 UInt32 SHLChunk::_funcUniform3iv = Window::invalidFunctionID;
00105 UInt32 SHLChunk::_funcUniform4iv = Window::invalidFunctionID;
00106 
00107 UInt32 SHLChunk::_funcUniform1f = Window::invalidFunctionID;
00108 UInt32 SHLChunk::_funcUniform2fv = Window::invalidFunctionID;
00109 UInt32 SHLChunk::_funcUniform3fv = Window::invalidFunctionID;
00110 UInt32 SHLChunk::_funcUniform4fv = Window::invalidFunctionID;
00111 
00112 UInt32 SHLChunk::_funcUniformMatrix4fv = Window::invalidFunctionID;
00113 
00114 UInt32 SHLChunk::_funcGetUniformiv = Window::invalidFunctionID;
00115 UInt32 SHLChunk::_funcGetUniformfv = Window::invalidFunctionID;
00116 
00117 Int32 SHLChunk::_clusterId = -1;
00118 
00119 // prototypes
00120 
00121 typedef GLuint  (OSG_APIENTRY * PFNGLCREATEPROGRAMOBJECTARBPROC) (void);
00122 typedef void    (OSG_APIENTRY * PFNGLDELETEOBJECTARBPROC) (GLuint obj);
00123 typedef GLuint  (OSG_APIENTRY * PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType);
00124 typedef void    (OSG_APIENTRY * PFNGLSHADERSOURCEARBPROC) (GLuint shaderObj, GLsizei count, const char **strings, const GLint *length);
00125 typedef void    (OSG_APIENTRY * PFNGLCOMPILESHADERARBPROC) (GLuint shaderObj);
00126 typedef void    (OSG_APIENTRY * PFNGLGETOBJECTPARAMETERIVARBPROC) (GLuint obj, GLenum pname, GLint *params);
00127 typedef void    (OSG_APIENTRY * PFNGLGETINFOLOGARBPROC) (GLuint obj,GLsizei maxLength, GLsizei *length, char *infoLog);
00128 typedef void    (OSG_APIENTRY * PFNGLATTACHOBJECTARBPROC) (GLuint containerObj, GLuint obj);
00129 typedef void    (OSG_APIENTRY * PFNGLLINKPROGRAMARBPROC) (GLuint programObj);
00130 typedef void    (OSG_APIENTRY * PFNGLUSEPROGRAMOBJECTARBPROC) (GLuint programObj);
00131 
00132 //typedef GLint   (OSG_APIENTRY * PFNGLGETUNIFORMLOCATIONARBPROC) (GLuint programObj, const char *name);
00133 
00134 typedef void   (OSG_APIENTRY * PFNGLUNIFORM1IARBPROC) (GLint location, GLint value);
00135 typedef void   (OSG_APIENTRY * PFNGLUNIFORMIVARBPROC) (GLint location, GLsizei count, GLint *value);
00136 
00137 typedef void   (OSG_APIENTRY * PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat value);
00138 typedef void   (OSG_APIENTRY * PFNGLUNIFORMFVARBPROC) (GLint location, GLsizei count, GLfloat *value);
00139 
00140 typedef void   (OSG_APIENTRY * PFNGLUNIFORMMATRIXFVARBPROC) (GLint location, GLsizei count, GLboolean transpose, GLfloat *value);
00141 
00142 typedef void   (OSG_APIENTRY * PFNGLGETUNIFORMFIARBPROC) (GLuint programObj, GLint location, GLint *value);
00143 typedef void   (OSG_APIENTRY * PFNGLGETUNIFORMFVARBPROC) (GLuint programObj, GLint location, GLfloat *value);
00144 
00145 
00146 /***************************************************************************\
00147  *                           Class methods                                 *
00148 \***************************************************************************/
00149 
00150 void SHLChunk::initMethod (void)
00151 {
00152 }
00153 
00154 
00155 /***************************************************************************\
00156  *                           Instance methods                              *
00157 \***************************************************************************/
00158 
00159 /*-------------------------------------------------------------------------*\
00160  -  private                                                                 -
00161 \*-------------------------------------------------------------------------*/
00162 
00163 /*----------------------- constructors & destructors ----------------------*/
00164 
00165 SHLChunk::SHLChunk(void) :
00166     Inherited(),
00167     _osgParametersCallbacks(),
00168     _oldParameterSize(0),
00169     _userParameterCallbacks()
00170 {
00171     _shl_extension = Window::registerExtension("GL_ARB_shading_language_100");
00172     _cg_extension = Window::registerExtension("GL_EXT_Cg_shader");
00173 
00174     _funcCreateProgramObject =
00175         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glCreateProgramObjectARB", 
00176                                   _shl_extension);
00177 
00178     _funcCreateShaderObject =
00179         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glCreateShaderObjectARB", 
00180                                   _shl_extension);
00181     _funcDeleteObject =
00182         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glDeleteObjectARB", 
00183                                   _shl_extension);
00184     
00185     _funcDetachObject =
00186         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glDetachObjectARB", 
00187                                   _shl_extension);
00188     
00189     _funcAttachObject =
00190         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glAttachObjectARB", 
00191                                   _shl_extension);
00192 
00193     _funcShaderSource =
00194         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glShaderSourceARB", 
00195                                   _shl_extension);
00196                                   
00197     _funcCompileShader =
00198         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glCompileShaderARB", 
00199                                   _shl_extension);
00200                                   
00201     _funcLinkProgram =
00202         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glLinkProgramARB", 
00203                                   _shl_extension);
00204                                   
00205     _funcGetInfoLog =
00206         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glGetInfoLogARB", 
00207                                   _shl_extension);
00208                                   
00209     _funcUseProgramObject =
00210         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glUseProgramObjectARB", 
00211                                   _shl_extension);
00212     
00213     _funcGetObjectParameteriv =
00214         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glGetObjectParameterivARB", 
00215                                   _shl_extension);
00216 
00217     _funcGetObjectParameterfv =
00218         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glGetObjectParameterfvARB", 
00219                                   _shl_extension);
00220 
00221     _funcGetUniformLocation =
00222         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glGetUniformLocationARB", 
00223                                   _shl_extension);
00224     
00225     _funcBindAttribLocation =
00226         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glBindAttribLocationARB", 
00227                                   _shl_extension);
00228 
00229     _funcGetAttribLocation =
00230         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glGetAttribLocationARB", 
00231                                   _shl_extension);
00232     
00233     _funcUniform1i =
00234         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glUniform1iARB", 
00235                                   _shl_extension);
00236 
00237     _funcUniform2iv =
00238         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glUniform2ivARB", 
00239                                   _shl_extension);
00240                                   
00241     _funcUniform3iv =
00242         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glUniform3ivARB", 
00243                                   _shl_extension);
00244                                   
00245     _funcUniform4iv =
00246         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glUniform4ivARB", 
00247                                   _shl_extension);
00248 
00249     _funcUniform1f =
00250         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glUniform1fARB", 
00251                                   _shl_extension);
00252 
00253     _funcUniform2fv =
00254         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glUniform2fvARB", 
00255                                   _shl_extension);
00256 
00257     _funcUniform3fv =
00258         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glUniform3fvARB", 
00259                                   _shl_extension);
00260 
00261     _funcUniform4fv =
00262         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glUniform4fvARB", 
00263                                   _shl_extension);
00264 
00265     _funcUniformMatrix4fv =
00266         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glUniformMatrix4fvARB", 
00267                                   _shl_extension);
00268 
00269     _funcGetUniformiv =
00270         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glGetUniformivARB", 
00271                                   _shl_extension);
00272     
00273     _funcGetUniformfv =
00274         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glGetUniformfvARB", 
00275                                   _shl_extension);
00276 }
00277 
00278 SHLChunk::SHLChunk(const SHLChunk &source) :
00279     Inherited(source),
00280     _osgParametersCallbacks(source._osgParametersCallbacks),
00281     _oldParameterSize(source._oldParameterSize),
00282     _userParameterCallbacks(source._userParameterCallbacks)
00283 {
00284 }
00285 
00286 SHLChunk::~SHLChunk(void)
00287 {
00288 }
00289 
00290 void SHLChunk::onCreate(const SHLChunk *source)
00291 {
00292     Inherited::onCreate(source);
00293 
00294     // ignore prototypes.
00295     if(GlobalSystemState == Startup)
00296         return;
00297 
00298     // we need this for clustering without it handleGL is never called.
00299     RemoteAspect::addFieldFilter(SHLChunk::getClassType().getId(), SHLChunk::GLIdFieldMask);
00300 
00301     SHLChunkPtr tmpPtr(*this);
00302     beginEditCP(tmpPtr, SHLChunk::GLIdFieldMask);
00303         setGLId(Window::registerGLObject(osgTypedMethodVoidFunctor2ObjCPtrPtr<SHLChunkPtr,
00304                                          Window , UInt32>(tmpPtr, &SHLChunk::handleGL), 1));
00305     endEditCP(tmpPtr, SHLChunk::GLIdFieldMask);
00306 
00307     //printf("SHLChunk::onCreate : glId %u\n", getGLId());
00308 }
00309 
00310 void SHLChunk::onDestroy(void)
00311 {
00312     Inherited::onDestroy();
00313 
00314     if(getGLId() > 0)
00315         Window::destroyGLObject(getGLId(), 1);
00316 }
00317 
00318 const StateChunkClass *SHLChunk::getClass(void) const
00319 {
00320     return &_class;
00321 }
00322 
00323 /*----------------------------- class specific ----------------------------*/
00324 
00325 void SHLChunk::changed(BitVector whichField, UInt32 origin)
00326 {
00327     if((whichField & VertexProgramFieldMask) ||
00328        (whichField & FragmentProgramFieldMask) ||
00329        (whichField & CgFrontEndFieldMask))
00330     {
00331         Window::reinitializeGLObject(getGLId());
00332     }
00333 
00334     if(whichField & ParametersFieldMask)
00335     {
00336         Window::refreshGLObject(getGLId());
00337     }
00338 
00339     Inherited::changed(whichField, origin);
00340 }
00341 
00342 void SHLChunk::dump(      UInt32    ,
00343                          const BitVector ) const
00344 {
00345     SLOG << "Dump SHLChunk NI" << std::endl;
00346 }
00347 
00351 void SHLChunk::handleGL(Window *win, UInt32 idstatus)
00352 {
00353     Window::GLObjectStatusE mode;
00354     UInt32 id;
00355 
00356     Window::unpackIdStatus(idstatus, id, mode);
00357 
00358     if(!win->hasExtension(_shl_extension))
00359     {
00360         FWARNING(("OpenGL Shading Language is not supported, couldn't find extension 'GL_ARB_shading_language_100'!\n"));
00361         return;
00362     }
00363 
00364     // BUG this is not called for every window!
00365     if(mode == Window::destroy)
00366     {
00367         // This is called after the destructor so getGLId() doesn't work anymore!
00368         //printf("Window::destroy: %p %u %x\n", win, id, win->getGLObjectId(id));
00369         GLuint program = (GLuint) win->getGLObjectId(id);
00370         if(program != 0)
00371         {
00372             // get "glDeleteObjectARB" function pointer
00373             PFNGLDELETEOBJECTARBPROC deleteObject = (PFNGLDELETEOBJECTARBPROC)
00374                 win->getFunction(_funcDeleteObject);
00375             deleteObject(program);
00376             win->setGLObjectId(id, 0);
00377         }
00378     }
00379     else if(mode == Window::finaldestroy)
00380     {
00381         ;//SWARNING << "Last program user destroyed" << std::endl;
00382     }
00383     else if(mode == Window::initialize || mode == Window::reinitialize ||
00384             mode == Window::needrefresh)
00385     {
00386         if(mode != Window::needrefresh)
00387         {
00388             updateProgram(win);
00389         }
00390 
00391         updateParameters(win, getParameters(), true, true/*mode != Window::needrefresh*/);
00392     }
00393     else
00394     {
00395         SWARNING << "SHLChunk(" << this << "::handleGL: Illegal mode: "
00396              << mode << " for id " << id << std::endl;
00397     }
00398 }
00399 
00400 void SHLChunk::updateProgram(Window *win)
00401 {
00402     //printf("SHLChunk::updateProgram glid %u\n", getGLId());
00403 
00404     // get "glCreateProgramObjectARB" function pointer
00405     PFNGLCREATEPROGRAMOBJECTARBPROC createProgramObject = (PFNGLCREATEPROGRAMOBJECTARBPROC)
00406         win->getFunction(_funcCreateProgramObject);
00407 
00408     // get "glDeleteObjectARB" function pointer
00409     PFNGLDELETEOBJECTARBPROC deleteObject = (PFNGLDELETEOBJECTARBPROC)
00410         win->getFunction(_funcDeleteObject);
00411 
00412     // get "glCreateShaderObjectARB" function pointer
00413     PFNGLCREATESHADEROBJECTARBPROC createShaderObject = (PFNGLCREATESHADEROBJECTARBPROC)
00414         win->getFunction(_funcCreateShaderObject);
00415 
00416     // get "glShaderSourceARB" function pointer
00417     PFNGLSHADERSOURCEARBPROC shaderSource = (PFNGLSHADERSOURCEARBPROC)
00418         win->getFunction(_funcShaderSource);
00419 
00420     // get "glCompileShaderARB" function pointer
00421     PFNGLCOMPILESHADERARBPROC compileShader = (PFNGLCOMPILESHADERARBPROC)
00422         win->getFunction(_funcCompileShader);
00423 
00424     // get "glGetObjectParameterivARB" function pointer
00425     PFNGLGETOBJECTPARAMETERIVARBPROC getObjectParameteriv = (PFNGLGETOBJECTPARAMETERIVARBPROC)
00426         win->getFunction(_funcGetObjectParameteriv);
00427 
00428     // get "glGetInfoLogARB" function pointer
00429     PFNGLGETINFOLOGARBPROC getInfoLog = (PFNGLGETINFOLOGARBPROC)
00430         win->getFunction(_funcGetInfoLog);
00431 
00432     // get "glAttachObjectARB" function pointer
00433     PFNGLATTACHOBJECTARBPROC attachObject = (PFNGLATTACHOBJECTARBPROC)
00434         win->getFunction(_funcAttachObject);
00435 
00436     // get "glLinkProgramARB" function pointer
00437     PFNGLLINKPROGRAMARBPROC linkProgram = (PFNGLLINKPROGRAMARBPROC)
00438         win->getFunction(_funcLinkProgram);
00439 
00440     // get "glUseProgramObjectARB" function pointer
00441     PFNGLUSEPROGRAMOBJECTARBPROC useProgramObject = (PFNGLUSEPROGRAMOBJECTARBPROC)
00442         win->getFunction(_funcUseProgramObject);
00443 
00444     GLuint program = (GLuint) win->getGLObjectId(getGLId());
00445     // delete old program.
00446     if(program != 0)
00447         deleteObject(program);
00448     program = createProgramObject();
00449     //printf("updateProgram create: %p %u %x\n", win, getGLId(), program);
00450     win->setGLObjectId(getGLId(), (UInt32) program);
00451 
00452     UInt32 vShader = 0;
00453     GLint has_vertex = 0;
00454     // reload programs
00455     if(!getVertexProgram().empty())
00456     {
00457         GLenum shader_type = GL_VERTEX_SHADER_ARB;
00458         if(getCgFrontEnd())
00459         {
00460             if(win->hasExtension(_cg_extension))
00461                 shader_type = GL_CG_VERTEX_SHADER_EXT;
00462             else
00463                 FWARNING(("EXT_Cg_shader extension not supported, using GLSL front end!\n"));
00464         }
00465 
00466         vShader = createShaderObject(shader_type);
00467         const char *source = getVertexProgram().c_str();
00468         shaderSource(vShader, 1, (const char **) &source, 0);
00469 
00470         int success = 0;
00471         compileShader(vShader);
00472         getObjectParameteriv(vShader, GL_OBJECT_COMPILE_STATUS_ARB, &has_vertex);
00473         
00474         if(has_vertex == 0)
00475         {
00476             char *debug;
00477             GLint debugLength;
00478             getObjectParameteriv(vShader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &debugLength);
00479               
00480             debug = new char[debugLength];
00481             getInfoLog(vShader, debugLength, &debugLength, debug);
00482         
00483             FFATAL(("Couldn't compile vertex program!\n%s\n", debug));
00484             delete [] debug;
00485             deleteObject(vShader);
00486         }
00487     }
00488 
00489     UInt32 fShader = 0;
00490     GLint has_fragment = 0;
00491     if(!getFragmentProgram().empty())
00492     {
00493         GLenum shader_type = GL_FRAGMENT_SHADER_ARB;
00494         if(getCgFrontEnd())
00495         {
00496             if(win->hasExtension(_cg_extension))
00497                 shader_type = GL_CG_FRAGMENT_SHADER_EXT;
00498             else
00499                 FWARNING(("EXT_Cg_shader extension not supported, using GLSL front end!\n"));
00500         }
00501 
00502         fShader = createShaderObject(shader_type);
00503         const char *source = getFragmentProgram().c_str();
00504         shaderSource(fShader, 1, (const char **) &source, 0);
00505 
00506         compileShader(fShader);
00507         getObjectParameteriv(fShader, GL_OBJECT_COMPILE_STATUS_ARB, &has_fragment);
00508         
00509         if(has_fragment == 0)
00510         {
00511             char *debug;
00512             GLint debugLength;
00513             getObjectParameteriv(fShader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &debugLength);
00514               
00515             debug = new char[debugLength];
00516             getInfoLog(fShader, debugLength, &debugLength, debug);
00517         
00518             FFATAL(("Couldn't compile fragment program!\n%s\n", debug));
00519             delete [] debug;
00520             deleteObject(fShader);
00521         }
00522     }
00523 
00524     if(has_vertex || has_fragment)
00525     {
00526         if(has_vertex)
00527         {
00528             attachObject(program, vShader);
00529             // just flagged for deletion
00530             deleteObject(vShader);
00531         }
00532 
00533         if(has_fragment)
00534         {
00535             attachObject(program, fShader);
00536             // just flagged for deletion
00537             deleteObject(fShader);
00538         }
00539 
00540         linkProgram(program);
00541         
00542         GLint success = 0;
00543         getObjectParameteriv(program, GL_OBJECT_LINK_STATUS_ARB, &success);
00544         if(!success)
00545         {
00546             char *debug;
00547             GLint debugLength;
00548             getObjectParameteriv(program, GL_OBJECT_INFO_LOG_LENGTH_ARB, &debugLength);
00549               
00550             debug = new char[debugLength];
00551             getInfoLog(program, debugLength, &debugLength, debug);
00552         
00553             FFATAL(("Couldn't link vertex and fragment program!\n%s\n", debug));
00554             delete [] debug;
00555             deleteObject(program);
00556             win->setGLObjectId(getGLId(), 0);
00557         }
00558     }
00559     else
00560     {
00561         deleteObject(program);
00562         win->setGLObjectId(getGLId(), 0);
00563     }
00564     // update all parameters.
00565     updateParameters(win, getParameters());
00566 }
00567 
00568 void SHLChunk::updateParameters(Window *win,
00569                                 const MFShaderParameterPtr &parameters,
00570                                 bool useProgram, bool force,
00571                                 bool keepProgramActive)
00572 {
00573     GLuint program = (GLuint) win->getGLObjectId(getGLId());
00574 
00575     if(program == 0)
00576         return;
00577 
00578     checkOSGParameters();
00579 
00580     if(parameters.empty())
00581         return;
00582 
00583     // get "glUseProgramObjectARB" function pointer
00584     PFNGLUSEPROGRAMOBJECTARBPROC useProgramObject = (PFNGLUSEPROGRAMOBJECTARBPROC)
00585         win->getFunction(_funcUseProgramObject);
00586 
00587     if(useProgram)
00588         useProgramObject(program);
00589 
00590     // get "glGetUniformLocationARB" function pointer
00591     PFNGLGETUNIFORMLOCATIONARBPROC getUniformLocation = (PFNGLGETUNIFORMLOCATIONARBPROC)
00592         win->getFunction(_funcGetUniformLocation);
00593 
00594     // just a example showing how to get parameter values.
00595 #if 0
00596     // get "glGetUniformfvARB" function pointer
00597     PFNGLGETUNIFORMFVARBPROC getUniformfv = (PFNGLGETUNIFORMFVARBPROC)
00598         win->getFunction(_funcGetUniformfv);
00599     GLfloat values[2];
00600     getUniformfv(program, location, values);
00601 #endif
00602 
00603     for(UInt32 i = 0; i < parameters.size(); ++i)
00604     {
00605         ShaderParameterPtr parameter = parameters[i];
00606 
00607         // ignore special osg parameters
00608         if(parameter->getName().size() > 3 &&
00609            parameter->getName()[0] == 'O' &&
00610            parameter->getName()[1] == 'S' &&
00611            parameter->getName()[2] == 'G')
00612         {
00613             continue;
00614         }
00615         
00616         // works also but is not possible with a switch and a switch is much faster.
00617         //UInt16 groupid = parameter->getType().getGroupId();
00618         //if(groupid == ShaderParameterInt::getClassType().getGroupId())
00619         
00620         if(!force)
00621         {
00622             if(!parameter->hasChanged())
00623                 continue;
00624             parameter->resetChanged();
00625         }
00626 
00627         //printf("seeting parameter: '%s'\n", parameter->getName().c_str());
00628 
00629         switch(parameter->getTypeId())
00630         {
00631             case ShaderParameter::SHPTypeBool:
00632             {
00633                 ShaderParameterBoolPtr p = ShaderParameterBoolPtr::dcast(parameter);
00634                 // get "glUniform1iARB" function pointer
00635                 PFNGLUNIFORM1IARBPROC uniform1i = (PFNGLUNIFORM1IARBPROC)
00636                     win->getFunction(_funcUniform1i);
00637     
00638                 //printf("setting: %s %d\n", p->getName().c_str(), p->getValue());
00639                 GLint location = getUniformLocation(program, p->getName().c_str());
00640                 if(location != -1)
00641                     uniform1i(location, (GLint) p->getValue());
00642                 else
00643                     FWARNING(("Unknown parameter '%s'!\n", p->getName().c_str()));
00644             }
00645             break;
00646             case ShaderParameter::SHPTypeInt:
00647             {
00648                 ShaderParameterIntPtr p = ShaderParameterIntPtr::dcast(parameter);
00649                 // get "glUniform1iARB" function pointer
00650                 PFNGLUNIFORM1IARBPROC uniform1i = (PFNGLUNIFORM1IARBPROC)
00651                     win->getFunction(_funcUniform1i);
00652     
00653                 //printf("setting: %s %d\n", p->getName().c_str(), p->getValue());
00654                 GLint location = getUniformLocation(program, p->getName().c_str());
00655                 if(location != -1)
00656                     uniform1i(location, p->getValue());
00657                 else
00658                     FWARNING(("Unknown parameter '%s'!\n", p->getName().c_str()));
00659             }
00660             break;
00661             case ShaderParameter::SHPTypeReal:
00662             {
00663                 ShaderParameterRealPtr p = ShaderParameterRealPtr::dcast(parameter);
00664                 // get "glUniform1fARB" function pointer
00665                 PFNGLUNIFORM1FARBPROC uniform1f = (PFNGLUNIFORM1FARBPROC)
00666                     win->getFunction(_funcUniform1f);
00667 
00668                 //printf("setting: %s %f\n", p->getName().c_str(), p->getValue());
00669                 GLint location = getUniformLocation(program, p->getName().c_str());
00670                 if(location != -1)
00671                     uniform1f(location, p->getValue());
00672                 else
00673                     FWARNING(("Unknown parameter '%s'!\n", p->getName().c_str()));
00674             }
00675             break;
00676             case ShaderParameter::SHPTypeVec2f:
00677             {
00678                 ShaderParameterVec2fPtr p = ShaderParameterVec2fPtr::dcast(parameter);
00679                 // get "glUniform2fvARB" function pointer
00680                 PFNGLUNIFORMFVARBPROC uniform2fv = (PFNGLUNIFORMFVARBPROC)
00681                     win->getFunction(_funcUniform2fv);
00682     
00683                 GLint location = getUniformLocation(program, p->getName().c_str());
00684                 if(location != -1)
00685                     uniform2fv(location, 1, p->getValue().getValues());
00686                 else
00687                     FWARNING(("Unknown parameter '%s'!\n", p->getName().c_str()));
00688             }
00689             break;
00690             case ShaderParameter::SHPTypeVec3f:
00691             {
00692                 ShaderParameterVec3fPtr p = ShaderParameterVec3fPtr::dcast(parameter);
00693                 // get "glUniform3fvARB" function pointer
00694                 PFNGLUNIFORMFVARBPROC uniform3fv = (PFNGLUNIFORMFVARBPROC)
00695                     win->getFunction(_funcUniform3fv);
00696     
00697                 GLint location = getUniformLocation(program, p->getName().c_str());
00698                 if(location != -1)
00699                     uniform3fv(location, 1, p->getValue().getValues());
00700                 else
00701                     FWARNING(("Unknown parameter '%s'!\n", p->getName().c_str()));
00702             }
00703             break;
00704             case ShaderParameter::SHPTypeVec4f:
00705             {
00706                 ShaderParameterVec4fPtr p = ShaderParameterVec4fPtr::dcast(parameter);
00707                 // get "glUniform4fvARB" function pointer
00708                 PFNGLUNIFORMFVARBPROC uniform4fv = (PFNGLUNIFORMFVARBPROC)
00709                     win->getFunction(_funcUniform4fv);
00710     
00711                 GLint location = getUniformLocation(program, p->getName().c_str());
00712                 if(location != -1)
00713                     uniform4fv(location, 1, p->getValue().getValues());
00714                 else
00715                     FWARNING(("Unknown parameter '%s'!\n", p->getName().c_str()));
00716             }
00717             break;
00718             case ShaderParameter::SHPTypeMatrix:
00719             {
00720                 ShaderParameterMatrixPtr p = ShaderParameterMatrixPtr::dcast(parameter);
00721                 // get "glUniformMatrix4fvARB" function pointer
00722                 PFNGLUNIFORMMATRIXFVARBPROC uniformMatrix4fv = (PFNGLUNIFORMMATRIXFVARBPROC)
00723                     win->getFunction(_funcUniformMatrix4fv);
00724     
00725                 GLint location = getUniformLocation(program, p->getName().c_str());
00726                 if(location != -1)
00727                     uniformMatrix4fv(location, 1, GL_FALSE, p->getValue().getValues());
00728                 else
00729                     FWARNING(("Unknown parameter '%s'!\n", p->getName().c_str()));
00730             }
00731             break;
00732             default:
00733                 FWARNING(("Parameter '%s' has unknown tpye %d!\n", parameter->getName().c_str(),
00734                                                                    parameter->getTypeId()));
00735             break;
00736         }
00737     }
00738 
00739     if(useProgram && !keepProgramActive)
00740         useProgramObject(0);
00741 }
00742 
00743 void SHLChunk::checkOSGParameters(void)
00744 {
00745     // ok this can go wrong if you sub and add a parameter
00746     // between one begin/endEditCP ...
00747     if(getParameters().getSize() == _oldParameterSize)
00748         return;
00749     _oldParameterSize = getParameters().getSize();
00750 
00751     _osgParametersCallbacks.clear();
00752     const MFShaderParameterPtr &parameters = getParameters();
00753     for(UInt32 i = 0; i < parameters.size(); ++i)
00754     {
00755         ShaderParameterPtr parameter = parameters[i];
00756         if(parameter->getName().size() > 3 &&
00757            parameter->getName()[0] == 'O' &&
00758            parameter->getName()[1] == 'S' &&
00759            parameter->getName()[2] == 'G')
00760         {
00761             if(parameter->getName() == "OSGCameraOrientation")
00762             {
00763                 // .net compiler needs this workaround in opt mode ...
00764                 paramtercbfp fp = updateCameraOrientation;
00765                 _osgParametersCallbacks.push_back(fp);
00766             }
00767             else if(parameter->getName() == "OSGCameraPosition")
00768             {
00769                 paramtercbfp fp = updateCameraPosition;
00770                 _osgParametersCallbacks.push_back(fp);
00771             }
00772             else if(parameter->getName() == "OSGViewMatrix")
00773             {
00774                 paramtercbfp fp = updateViewMatrix;
00775                 _osgParametersCallbacks.push_back(fp);
00776             }
00777             else if(parameter->getName() == "OSGInvViewMatrix")
00778             {
00779                 paramtercbfp fp = updateInvViewMatrix;
00780                 _osgParametersCallbacks.push_back(fp);
00781             }
00782             else if(parameter->getName() == "OSGStereoLeftEye")
00783             {
00784                 paramtercbfp fp = updateStereoLeftEye;
00785                 _osgParametersCallbacks.push_back(fp);
00786             }
00787             else if(parameter->getName() == "OSGClusterId")
00788             {
00789                 paramtercbfp fp = updateClusterId;
00790                 _osgParametersCallbacks.push_back(fp);
00791             }
00792             else if(parameter->getName() == "OSGActiveLightsMask")
00793             {
00794                 paramtercbfp fp = updateActiveLightsMask;
00795                 _osgParametersCallbacks.push_back(fp);
00796             }
00797             else if(parameter->getName() == "OSGLight0Active")
00798             {
00799                 paramtercbfp fp = updateLight0Active;
00800                 _osgParametersCallbacks.push_back(fp);
00801             }
00802             else if(parameter->getName() == "OSGLight1Active")
00803             {
00804                 paramtercbfp fp = updateLight1Active;
00805                 _osgParametersCallbacks.push_back(fp);
00806             }
00807             else if(parameter->getName() == "OSGLight2Active")
00808             {
00809                 paramtercbfp fp = updateLight2Active;
00810                 _osgParametersCallbacks.push_back(fp);
00811             }
00812             else if(parameter->getName() == "OSGLight3Active")
00813             {
00814                 paramtercbfp fp = updateLight3Active;
00815                 _osgParametersCallbacks.push_back(fp);
00816             }
00817             else if(parameter->getName() == "OSGLight4Active")
00818             {
00819                 paramtercbfp fp = updateLight4Active;
00820                 _osgParametersCallbacks.push_back(fp);
00821             }
00822             else if(parameter->getName() == "OSGLight5Active")
00823             {
00824                 paramtercbfp fp = updateLight5Active;
00825                 _osgParametersCallbacks.push_back(fp);
00826             }
00827             else if(parameter->getName() == "OSGLight6Active")
00828             {
00829                 paramtercbfp fp = updateLight6Active;
00830                 _osgParametersCallbacks.push_back(fp);
00831             }
00832             else if(parameter->getName() == "OSGLight7Active")
00833             {
00834                 paramtercbfp fp = updateLight7Active;
00835                 _osgParametersCallbacks.push_back(fp);
00836             }
00837             else
00838             {
00839                 // check user parameter callbacks.
00840                 userParameterCallbacksMap::iterator it =
00841                     _userParameterCallbacks.find(parameter->getName());
00842                 if(it != _userParameterCallbacks.end())
00843                 {
00844                     paramtercbfp fp = (*it).second;
00845                     _osgParametersCallbacks.push_back(fp);
00846                 }
00847                 else
00848                 {
00849                     FWARNING(("SHLChunk::checkOSGParameters : unknown osg parameter '%s'\n",
00850                               parameter->getName().c_str()));
00851                 }
00852             }
00853         }
00854     }
00855 }
00856 
00857 void SHLChunk::addParameterCallback(const char *name, paramtercbfp fp)
00858 {
00859     if(name == NULL)
00860         return;
00861 
00862     setUniformParameter(name, 0);
00863     _userParameterCallbacks.insert(std::make_pair(name, fp));
00864 }
00865 
00866 void SHLChunk::updateOSGParameters(DrawActionBase *action, GLuint program)
00867 {
00868     if(_osgParametersCallbacks.empty())
00869         return;
00870 
00871     // get "glGetUniformLocationARB" function pointer
00872     PFNGLGETUNIFORMLOCATIONARBPROC getUniformLocation = (PFNGLGETUNIFORMLOCATIONARBPROC)
00873         action->getWindow()->getFunction(_funcGetUniformLocation);
00874 
00875     for(UInt32 i=0;i<_osgParametersCallbacks.size();++i)
00876         _osgParametersCallbacks[i](getUniformLocation, action, program);
00877 }
00878 
00879 void SHLChunk::updateCameraOrientation(PFNGLGETUNIFORMLOCATIONARBPROC getUniformLocation,
00880                                        DrawActionBase *action, GLuint program)
00881 {
00882     if(action->getCamera() == NULL || action->getViewport() == NULL)
00883     {
00884         FWARNING(("SHLChunk::updateCameraOrientation : Can't update OSGCameraOrientation"
00885                   "parameter, camera or viewport is NULL!\n"));
00886         return;
00887     }
00888 
00889     Matrix m;
00890     action->getCamera()->getViewing(m,
00891                                 action->getViewport()->getPixelWidth(),
00892                                 action->getViewport()->getPixelHeight());
00893     m.invert();
00894     m[3].setValues(0, 0, 0, 1);
00895 
00896     // get "glUniformMatrix4fvARB" function pointer
00897     PFNGLUNIFORMMATRIXFVARBPROC uniformMatrix4fv = (PFNGLUNIFORMMATRIXFVARBPROC)
00898         action->getWindow()->getFunction(_funcUniformMatrix4fv);
00899     GLint location = getUniformLocation(program, "OSGCameraOrientation");
00900     if(location != -1)
00901         uniformMatrix4fv(location, 1, GL_FALSE, m.getValues());
00902 }
00903 
00904 void SHLChunk::updateCameraPosition(PFNGLGETUNIFORMLOCATIONARBPROC getUniformLocation,
00905                                     DrawActionBase *action, GLuint program)
00906 {
00907     if(action->getCamera() == NULL || action->getViewport() == NULL)
00908     {
00909         FWARNING(("SHLChunk::updateCameraPosition : Can't update OSGCameraPosition"
00910                   "parameter, camera or viewport is NULL!\n"));
00911         return;
00912     }
00913 
00914     Matrix m;
00915     action->getCamera()->getViewing(m,
00916                                 action->getViewport()->getPixelWidth(),
00917                                 action->getViewport()->getPixelHeight());
00918     m.invert();
00919     Vec3f cameraPos(m[3][0], m[3][1], m[3][2]);
00920 
00921     // get "glUniform3fvARB" function pointer
00922     PFNGLUNIFORMFVARBPROC uniform3fv = (PFNGLUNIFORMFVARBPROC)
00923         action->getWindow()->getFunction(_funcUniform3fv);
00924     GLint location = getUniformLocation(program, "OSGCameraPosition");
00925     if(location != -1)
00926         uniform3fv(location, 1, cameraPos.getValues());
00927 }
00928 
00929 void SHLChunk::updateViewMatrix(PFNGLGETUNIFORMLOCATIONARBPROC getUniformLocation,
00930                                 DrawActionBase *action, GLuint program)
00931 {
00932     if(action->getCamera() == NULL || action->getViewport() == NULL)
00933     {
00934         FWARNING(("SHLChunk::updateViewMatrix : Can't update OSGViewMatrix"
00935                   "parameter, camera or viewport is NULL!\n"));
00936         return;
00937     }
00938 
00939     Matrix m;
00940     action->getCamera()->getViewing(m,
00941                                 action->getViewport()->getPixelWidth(),
00942                                 action->getViewport()->getPixelHeight());
00943 
00944     // get "glUniformMatrix4fvARB" function pointer
00945     PFNGLUNIFORMMATRIXFVARBPROC uniformMatrix4fv = (PFNGLUNIFORMMATRIXFVARBPROC)
00946         action->getWindow()->getFunction(_funcUniformMatrix4fv);
00947     GLint location = getUniformLocation(program, "OSGViewMatrix");
00948     if(location != -1)
00949         uniformMatrix4fv(location, 1, GL_FALSE, m.getValues());
00950 }
00951 
00952 void SHLChunk::updateInvViewMatrix(PFNGLGETUNIFORMLOCATIONARBPROC getUniformLocation,
00953                                    DrawActionBase *action, GLuint program)
00954 {
00955     if(action->getCamera() == NULL || action->getViewport() == NULL)
00956     {
00957         FWARNING(("SHLChunk::updateInvViewMatrix : Can't update OSGInvViewMatrix"
00958                   "parameter, camera or viewport is NULL!\n"));
00959         return;
00960     }
00961 
00962     Matrix m;
00963     action->getCamera()->getViewing(m,
00964                                 action->getViewport()->getPixelWidth(),
00965                                 action->getViewport()->getPixelHeight());
00966     m.invert();
00967 
00968     // get "glUniformMatrix4fvARB" function pointer
00969     PFNGLUNIFORMMATRIXFVARBPROC uniformMatrix4fv = (PFNGLUNIFORMMATRIXFVARBPROC)
00970         action->getWindow()->getFunction(_funcUniformMatrix4fv);
00971     GLint location = getUniformLocation(program, "OSGInvViewMatrix");
00972     if(location != -1)
00973         uniformMatrix4fv(location, 1, GL_FALSE, m.getValues());
00974 }
00975 
00976 void SHLChunk::updateStereoLeftEye(PFNGLGETUNIFORMLOCATIONARBPROC getUniformLocation,
00977                                    DrawActionBase *action, GLuint program)
00978 {
00979     if(action->getCamera() == NULL || action->getViewport() == NULL)
00980     {
00981         FWARNING(("SHLChunk::updateStereoLeftEye : Can't update OSGStereoLeftEye"
00982                   "parameter, camera or viewport is NULL!\n"));
00983         return;
00984     }
00985 
00986     // ok -1 is mono
00987     Int32 leftEye = -1;
00988     // now search for a stereo camera decorator and get the eye.
00989