fixed: auto_ptr -> unique_ptr
[opensg.git] / Source / Contrib / ComputeBase / ComputeShader / OSGComputeShaderChunk.cpp
blobb99db0ced573d881ac79aa0c872b6c8d38b1fd25
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2000-2006 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
18 * *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
27 * *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30 * Changes *
31 * *
32 * *
33 * *
34 * *
35 * *
36 * *
37 \*---------------------------------------------------------------------------*/
39 //---------------------------------------------------------------------------
40 // Includes
41 //---------------------------------------------------------------------------
43 #include <cstdlib>
44 #include <cstdio>
46 #include "OSGConfig.h"
48 #include "OSGComputeShaderChunk.h"
49 #include "OSGDrawEnv.h"
51 #include "OSGShaderVariables.h"
52 #include "OSGConceptPropertyChecks.h"
54 #include <boost/bind.hpp>
56 OSG_BEGIN_NAMESPACE
58 // Documentation for this class is emitted in the
59 // OSGComputeShaderChunkBase.cpp file.
60 // To modify it, please change the .fcd file (OSGComputeShaderChunk.fcd) and
61 // regenerate the base file.
63 /***************************************************************************\
64 * Class variables *
65 \***************************************************************************/
67 StateChunkClass ComputeShaderChunk::_class("ShaderProgram", 1, 40);
69 volatile UInt16 ComputeShaderChunk::_uiChunkCounter = 1;
71 UInt32 ComputeShaderChunk::_arbComputeShader = Window::invalidExtensionID;
73 /***************************************************************************\
74 * Class methods *
75 \***************************************************************************/
77 void ComputeShaderChunk::initMethod(InitPhase ePhase)
79 Inherited::initMethod(ePhase);
81 if(ePhase == TypeObject::SystemPost)
83 _arbComputeShader =
84 Window::registerExtension("GL_ARB_compute_shader");
88 UInt32 ComputeShaderChunk::handleGL(DrawEnv *pEnv,
89 UInt32 id,
90 Window::GLObjectStatusE mode,
91 UInt64 uiOptions)
93 UInt32 returnValue = 0;
94 Window *pWin = pEnv->getWindow();
96 if(!pWin->hasExtOrVersion(_arbComputeShader, 0x0403, 0xFFFF))
98 FWARNING(("OpenGL compute shader is not supported, couldn't find "
99 "extension 'GL_ARB_compute_shader'!\n"));
101 pWin->setGLObjectId(getGLId(), 0);
103 return returnValue;
106 if(mode == Window::initialize ||
107 mode == Window::reinitialize ||
108 mode == Window::needrefresh )
110 GLuint uiProgram = GLuint(pWin->getGLObjectId(getGLId()));;
112 if(mode != Window::needrefresh)
114 if(uiProgram != 0)
116 OSGGETGLFUNCBYID_GL3_ES(glDeleteProgram,
117 osgGlDeleteProgram,
118 ShaderProgram::getFuncIdDeleteProgram(),
119 pWin);
121 osgGlDeleteProgram(uiProgram);
124 OSGGETGLFUNCBYID_GL3_ES(glCreateProgram,
125 osgGlCreateProgram,
126 ShaderProgram::getFuncIdCreateProgram(),
127 pWin);
129 OSGGETGLFUNCBYID_GL3_ES(glAttachShader,
130 osgGlAttachShader,
131 ShaderProgram::getFuncIdAttachShader(),
132 pWin);
134 OSGGETGLFUNCBYID_GL3_ES(glLinkProgram,
135 osgGlLinkProgram,
136 ShaderProgram::getFuncIdLinkProgram(),
137 pWin);
139 uiProgram = osgGlCreateProgram();
141 ComputeShaderIt vIt = _mfComputeShader.begin();
142 ComputeShaderIt vEnd = _mfComputeShader.end ();
144 for(; vIt != vEnd; ++vIt)
146 (*vIt)->validate(pEnv);
148 GLuint uiShader =
149 GLuint(pWin->getGLObjectId((*vIt)->getGLId()));
151 if(uiShader != 0)
152 osgGlAttachShader(uiProgram, uiShader);
155 osgGlLinkProgram(uiProgram);
157 GLint iInfoLength;
158 Char8 *szInfoBuffer = NULL;
160 OSGGETGLFUNCBYID_GL3_ES(glGetProgramiv,
161 osgGlGetProgramiv,
162 ShaderProgram::getFuncIdGetProgramiv(),
163 pWin);
165 osgGlGetProgramiv(uiProgram,
166 GL_OBJECT_INFO_LOG_LENGTH_ARB,
167 &iInfoLength);
169 if(iInfoLength > 0)
171 szInfoBuffer = new Char8[iInfoLength];
172 szInfoBuffer[0] = '\0';
174 OSGGETGLFUNCBYID_GL3_ES(
175 glGetProgramInfoLog,
176 osgGlGetProgramInfoLog,
177 ShaderProgram::getFuncIdGetProgramInfoLog(),
178 pWin);
180 osgGlGetProgramInfoLog( uiProgram,
181 iInfoLength,
182 &iInfoLength,
183 szInfoBuffer);
186 GLint iStatus = 0;
188 osgGlGetProgramiv(uiProgram, GL_LINK_STATUS, &iStatus);
190 if(iStatus == 0)
192 if(szInfoBuffer != NULL && szInfoBuffer[0] != '\0')
194 FFATAL(("Couldn't link compute program!\n%s\n",
195 szInfoBuffer));
197 else
199 FFATAL(("Couldn't link compute program!\n"
200 "No further info available\n"));
203 OSGGETGLFUNCBYID_GL3_ES(glDeleteProgram,
204 osgGlDeleteProgram,
205 ShaderProgram::getFuncIdDeleteProgram(),
206 pWin);
208 osgGlDeleteProgram(uiProgram);
210 uiProgram = 0;
212 else
214 if(szInfoBuffer != NULL && szInfoBuffer[0] != '\0')
216 FWARNING(("ComputeShaderChunk: link status: %s\n",
217 szInfoBuffer));
221 pWin->setGLObjectId(getGLId(), uiProgram);
223 updateVariableLocations(pEnv, uiProgram);
226 if(uiProgram != 0)
228 OSGGETGLFUNCBYID_GL3_ES(glUseProgram,
229 osgGlUseProgram,
230 ShaderProgram::getFuncIdUseProgram(),
231 pWin);
233 osgGlUseProgram(uiProgram);
235 updateVariables(pEnv, uiProgram);
237 if(0x0000 == (uiOptions & KeepProgActive))
239 osgGlUseProgram(0);
241 else
243 returnValue |= ProgActive;
248 return returnValue;
251 void ComputeShaderChunk::handleDestroyGL(DrawEnv *pEnv,
252 UInt32 id,
253 Window::GLObjectStatusE mode)
255 Window *pWin = pEnv->getWindow();
257 if(!pWin->hasExtOrVersion(_arbComputeShader, 0x0403, 0xFFFF))
259 FWARNING(("OpenGL Shading Language is not supported, couldn't find "
260 "extension 'GL_ARB_shading_language_100'!\n"));
262 pWin->setGLObjectId(id, 0);
264 return;
267 // BUG this is not called for every window!
268 if(mode == Window::destroy)
270 GLuint uiProgram = GLuint(pWin->getGLObjectId(id));
272 if(uiProgram != 0)
274 OSGGETGLFUNCBYID_GL3_ES(glDeleteProgram,
275 osgGlDeleteProgram,
276 ShaderProgram::getFuncIdDeleteProgram(),
277 pWin);
279 osgGlDeleteProgram(uiProgram);
281 pWin->setGLObjectId(id, 0);
284 else if(mode == Window::finaldestroy)
286 ;//SWARNING << "Last program user destroyed" << std::endl;
290 /***************************************************************************\
291 * Instance methods *
292 \***************************************************************************/
294 /*-------------------------------------------------------------------------*\
295 - private -
296 \*-------------------------------------------------------------------------*/
298 /*----------------------- constructors & destructors ----------------------*/
300 ComputeShaderChunk::ComputeShaderChunk(void) :
301 Inherited( ),
302 _uiChunkId(0)
306 ComputeShaderChunk::ComputeShaderChunk(const ComputeShaderChunk &source) :
307 Inherited(source),
308 _uiChunkId(0 )
312 ComputeShaderChunk::~ComputeShaderChunk(void)
316 void ComputeShaderChunk::onCreate(const ComputeShaderChunk *source)
318 Inherited::onCreate(source);
320 // ignore prototypes.
321 if(GlobalSystemState == Startup)
322 return;
324 setGLId(
325 Window::registerGLObject(
326 boost::bind(&ComputeShaderChunk::handleGL,
327 ComputeShaderChunkMTUncountedPtr(this),
328 _1, _2, _3, _4),
329 &ComputeShaderChunk::handleDestroyGL));
331 _uiChunkId = ComputeShaderChunk::_uiChunkCounter++;
334 void ComputeShaderChunk::onCreateAspect(const ComputeShaderChunk *createAspect,
335 const ComputeShaderChunk *source )
337 Inherited::onCreateAspect(createAspect, source);
339 _uiChunkId = createAspect->_uiChunkId;
342 void ComputeShaderChunk::onDestroy(UInt32 uiId)
344 if(getGLId() > 0)
345 Window::destroyGLObject(getGLId(), 1);
347 Inherited::onDestroy(uiId);
350 const StateChunkClass *ComputeShaderChunk::getClass(void) const
352 return &_class;
355 UInt16 ComputeShaderChunk::getChunkId(void)
357 return _uiChunkId;
360 /*----------------------------- class specific ----------------------------*/
362 void ComputeShaderChunk::changed(ConstFieldMaskArg whichField,
363 UInt32 origin,
364 BitVector details)
366 bool bMarkChanged = false;
368 if(0x0000 != (whichField & ComputeProgramFieldMask) &&
369 0 != _sfComputeProgram.getValue().size() )
371 if(_mfComputeShader.size() == 0)
373 ShaderProgramUnrecPtr pProg = ShaderProgram::createDependent(
374 this->getFieldFlags()->_bNamespaceMask);
376 pProg->setShaderType(GL_COMPUTE_SHADER);
378 addComputeShader(pProg);
380 pProg->setVariables(this->getVariables());
382 else if(_mfComputeShader.size() > 1)
384 editMFComputeShader()->resize(1);
387 _mfComputeShader[0]->setProgram(_sfComputeProgram.getValue());
389 bMarkChanged = true;
391 Window::reinitializeGLObject(this->getGLId());
395 if(0x0000 != (whichField & VariablesFieldMask))
397 ShaderProgramVariables *pVars = _sfVariables.getValue();
399 if(pVars != NULL)
401 if(details == 0x0001)
403 // be save reset all locations
405 if(pVars->getMFVariables()->size() == 0)
407 editMFVariableLocations()->clear();
409 else
411 editMFVariableLocations()->resize(
412 pVars->getMFVariables()->size(),
413 -1);
415 std::fill(editMFVariableLocations()->begin(),
416 editMFVariableLocations()->end (),
417 -1);
420 // be save reset all locations
422 if(pVars->getMFProceduralVariables()->size() == 0 )
424 editMFProceduralVariableLocations()->clear();
426 else
428 editMFProceduralVariableLocations()->resize(
429 pVars->getMFProceduralVariables()->size(),
430 -1);
432 std::fill(editMFProceduralVariableLocations()->begin(),
433 editMFProceduralVariableLocations()->end (),
434 -1);
439 Window::refreshGLObject(this->getGLId());
442 if(0x0000 != (whichField & ComputeShaderFieldMask))
444 bMarkChanged = true;
446 Window::reinitializeGLObject(this->getGLId());
449 if(bMarkChanged == true)
451 // be save reset all locations
453 std::fill(editMFVariableLocations()->begin(),
454 editMFVariableLocations()->end (),
455 -1);
457 std::fill(editMFProceduralVariableLocations()->begin(),
458 editMFProceduralVariableLocations()->end (),
459 -1);
461 if(_sfVariables.getValue() != NULL)
463 _sfVariables.getValue()->markAllChanged();
467 Inherited::changed(whichField, origin, details);
470 void ComputeShaderChunk::activate(DrawEnv *pEnv,
471 UInt32 uiIdx)
473 Window *pWin = pEnv->getWindow();
475 UInt32 uiValRes = pWin->validateGLObject(getGLId(),
476 pEnv,
477 KeepProgActive);
479 GLuint uiProgId = GLuint(pWin->getGLObjectId(getGLId()));
481 if(uiProgId == 0)
482 return;
484 pEnv->setActiveShader(uiProgId);
486 if(0x0000 == (uiValRes & ProgActive))
488 OSGGETGLFUNCBYID_GL3_ES(glUseProgram,
489 osgGlUseProgram,
490 ShaderProgram::getFuncIdUseProgram(),
491 pWin);
493 osgGlUseProgram(uiProgId);
496 pEnv->incNumShaderChanges();
498 updateProceduralVariables(pEnv, ShaderProcVariable::SHDAll);
502 void ComputeShaderChunk::changeFrom(DrawEnv *pEnv,
503 StateChunk *pOther,
504 UInt32 uiIdx)
506 ComputeShaderChunk *pOld = dynamic_cast<ComputeShaderChunk *>(pOther);
508 // pOther can be a ShaderExecutableChunk, since we share the StateClass id
509 // with it
510 if(pOld != NULL)
512 Window *pWin = pEnv->getWindow();
513 GLuint uiProgId = GLuint(pWin->getGLObjectId(getGLId()));
515 UInt32 uiDep = ShaderProcVariable::SHDObject;
517 if(uiProgId != pEnv->getActiveShader())
519 UInt32 uiValRes = pWin->validateGLObject(getGLId(),
520 pEnv,
521 KeepProgActive);
523 uiProgId = GLuint(pWin->getGLObjectId(getGLId()));
525 if(uiProgId == 0)
526 return;
528 pEnv->setActiveShader(uiProgId);
530 if(0x0000 == (uiValRes & ProgActive))
532 OSGGETGLFUNCBYID_GL3_ES(glUseProgram,
533 osgGlUseProgram,
534 ShaderProgram::getFuncIdUseProgram(),
535 pWin);
537 osgGlUseProgram(uiProgId);
540 uiDep = ShaderProcVariable::SHDAll;
542 pEnv->incNumShaderChanges();
545 updateProceduralVariables(pEnv, uiDep);
547 else
549 pOther->deactivate(pEnv, uiIdx);
550 activate (pEnv, uiIdx);
552 pEnv->incNumShaderChanges();
556 void ComputeShaderChunk::deactivate(DrawEnv *pEnv,
557 UInt32 uiIdx)
559 if(pEnv->getWindow()->getGLObjectId(getGLId()) == 0)
560 return;
562 pEnv->setActiveShader(0);
564 OSGGETGLFUNC_GL3_ES(glUseProgram,
565 osgGlUseProgram,
566 ShaderProgram::getFuncIdUseProgram());
568 osgGlUseProgram(0);
571 void ComputeShaderChunk::dump( UInt32 ,
572 const BitVector ) const
574 SLOG << "Dump ComputeShaderChunk NI" << std::endl;
577 bool ComputeShaderChunk::readComputeProgram(const Char8 *file)
579 return readProgram(editSFComputeProgram()->getValue(), file);
582 bool ComputeShaderChunk::readProgram( std::string &szTarget,
583 const Char8 *szFilename)
585 std::ifstream s(szFilename);
587 if(s.good())
589 return readProgram(szTarget, s);
591 else
593 FWARNING(("ShaderChunk::readProgram: couldn't open '%s' "
594 "for reading!\n", szFilename));
596 return false;
601 bool ComputeShaderChunk::readProgram(std::string &szTarget,
602 std::istream &iStream)
604 #define BUFSIZE 200
606 szTarget.erase();
608 Char8 buf[BUFSIZE];
610 if(!iStream.good())
612 FWARNING(("SHLChunk::readProgram: stream is not good!\n"));
614 return false;
619 iStream.read(buf, BUFSIZE);
621 szTarget.append(buf, iStream.gcount());
623 while(!iStream.eof());
625 return true;
628 bool ComputeShaderChunk::subUniformVariable(const Char8 *name)
630 if(_sfVariables.getValue() != NULL)
632 return _sfVariables.getValue()->subUniformVariable(
633 name,
634 editMFVariableLocations(),
635 editMFProceduralVariableLocations());
639 return false;
642 void ComputeShaderChunk::clearUniformVariables(void)
644 if(_sfVariables.getValue() != NULL)
646 _sfVariables.getValue()->clearUniformVariables();
649 editMFVariableLocations ()->clear();
650 editMFProceduralVariableLocations()->clear();
653 bool ComputeShaderChunk::addOSGVariable(const Char8 *name)
655 if(_sfVariables.getValue() == NULL)
657 ShaderProgramVariablesUnrecPtr pVar =
658 ShaderProgramVariables::createDependent(
659 this->getFieldFlags()->_bNamespaceMask);
661 setVariables(pVar);
663 if(_mfComputeShader.size() > 0)
665 _mfComputeShader[0]->setVariables(this->getVariables());
669 return _sfVariables.getValue()->addOSGVariable(
670 name,
671 editMFProceduralVariableLocations());
674 bool ComputeShaderChunk::addProceduralVariable(
675 const Char8 *name,
676 ProcVarFunctor pFunc,
677 UInt32 uiDependency)
679 if(_sfVariables.getValue() == NULL)
681 ShaderProgramVariablesUnrecPtr pParam =
682 ShaderProgramVariables::createDependent(
683 this->getFieldFlags()->_bNamespaceMask);
685 setVariables(pParam);
687 if(_mfComputeShader.size() > 0)
689 _mfComputeShader[0]->setVariables(this->getVariables());
693 return _sfVariables.getValue()->addProceduralVariable(
694 name,
695 pFunc,
696 uiDependency,
697 editMFProceduralVariableLocations());
700 bool ComputeShaderChunk::updateNodeProceduralVariable(
701 const Char8 *name,
702 ProcVarNodeFunctor pFunc,
703 UInt32 uiDependency)
705 if(_sfVariables.getValue() == NULL)
707 ShaderProgramVariablesUnrecPtr pParam =
708 ShaderProgramVariables::createDependent(
709 this->getFieldFlags()->_bNamespaceMask);
711 setVariables(pParam);
713 if(_mfComputeShader.size() > 0)
715 _mfComputeShader[0]->setVariables(this->getVariables());
719 return _sfVariables.getValue()->updateNodeProceduralVariable(name,
720 pFunc,
721 uiDependency);
724 bool ComputeShaderChunk::addNodeProceduralVariable(
725 const Char8 *name,
726 ProcVarNodeFunctor pFunc,
727 UInt32 uiDependency)
729 if(_sfVariables.getValue() == NULL)
731 ShaderProgramVariablesUnrecPtr pParam =
732 ShaderProgramVariables::createDependent(
733 this->getFieldFlags()->_bNamespaceMask);
735 setVariables(pParam);
737 if(_mfComputeShader.size() > 0)
739 _mfComputeShader[0]->setVariables(this->getVariables());
743 return _sfVariables.getValue()->addNodeProceduralVariable(
744 name,
745 pFunc,
746 uiDependency,
747 editMFProceduralVariableLocations());
750 bool ComputeShaderChunk::updateProceduralVariable(
751 const Char8 *name,
752 ProcVarFunctor pFunc,
753 UInt32 uiDependency)
755 if(_sfVariables.getValue() == NULL)
757 ShaderProgramVariablesUnrecPtr pParam =
758 ShaderProgramVariables::createDependent(
759 this->getFieldFlags()->_bNamespaceMask);
761 setVariables(pParam);
763 if(_mfComputeShader.size() > 0)
765 _mfComputeShader[0]->setVariables(this->getVariables());
769 return _sfVariables.getValue()->updateProceduralVariable(name,
770 pFunc,
771 uiDependency);
774 #if 0
775 void ComputeShaderChunk::updateParameters(
776 Window *win,
777 const UInt32 &parameters,
778 bool useProgram,
779 bool force,
780 bool keepProgramActive)
784 const UInt32 *ComputeShaderChunk::getMFParameters(void) const
786 static UInt32 foo;
788 return &foo;
790 #endif
792 void ComputeShaderChunk::updateVariableLocations(DrawEnv *pEnv,
793 UInt32 uiProgram)
795 if(uiProgram == 0)
796 return;
798 const ShaderProgramVariables::MFVariablesType *pMFVars = NULL;
799 const ShaderProgramVariables::MFProceduralVariablesType *pMFProcVars = NULL;
801 if(_sfVariables.getValue() != NULL)
803 pMFVars = _sfVariables.getValue()->getMFVariables ();
804 pMFProcVars = _sfVariables.getValue()->getMFProceduralVariables();
807 if(pMFVars != NULL && pMFVars->size() != 0)
809 MFInt32 &vVarLocations = *this->editMFVariableLocations();
811 OSG_ASSERT(pMFVars->size() == vVarLocations.size());
813 MFInt32::iterator mLocIt = vVarLocations.begin();
815 ShaderProgramVariables::MFVariablesType::const_iterator mVarIt =
816 pMFVars->begin();
817 ShaderProgramVariables::MFVariablesType::const_iterator mVarEnd =
818 pMFVars->end ();
820 OSGGETGLFUNC_GL3_ES(glGetUniformLocation,
821 osgGlGetUniformLocation,
822 ShaderProgram::getFuncIdGetUniformLocation());
824 for(; mVarIt != mVarEnd; ++mVarIt, ++mLocIt)
826 *mLocIt = osgGlGetUniformLocation(uiProgram,
827 (*mVarIt)->getName().c_str());
831 if(pMFProcVars != NULL && pMFProcVars->size() != 0)
833 MFInt32 &vVarLocations = *this->editMFProceduralVariableLocations();
835 OSG_ASSERT(pMFProcVars->size() == vVarLocations.size());
837 MFInt32::iterator mLocIt = vVarLocations.begin();
839 ShaderProgramVariables::MFProceduralVariablesType::const_iterator
840 mVarIt = pMFProcVars->begin();
841 ShaderProgramVariables::MFProceduralVariablesType::const_iterator
842 mVarEnd = pMFProcVars->end ();
844 OSGGETGLFUNC_GL3_ES(glGetUniformLocation,
845 osgGlGetUniformLocation,
846 ShaderProgram::getFuncIdGetUniformLocation());
848 for(; mVarIt != mVarEnd; ++mVarIt, ++mLocIt)
850 *mLocIt = osgGlGetUniformLocation(uiProgram,
851 (*mVarIt)->getName().c_str());
856 void ComputeShaderChunk::updateVariables(DrawEnv *pEnv,
857 UInt32 uiProgram)
859 if(uiProgram == 0)
860 return;
862 const ShaderProgramVariables::MFVariablesType *pMFVars = NULL;
863 ShaderProgramVariables::MFVariableChangedType *pMFVarChg = NULL;
865 if(_sfVariables.getValue() != NULL)
867 pMFVars = _sfVariables.getValue()->getMFVariables ();
868 pMFVarChg = _sfVariables.getValue()->editMFVariableChanged();
871 if(pMFVars == NULL || pMFVars->size() == 0 || pMFVarChg == NULL)
873 return;
876 OSG_ASSERT(pMFVars->size() == pMFVarChg->size());
878 MFInt32 &vVarLocations = *this->editMFVariableLocations();
880 OSG_ASSERT(pMFVars->size() == vVarLocations.size());
882 MFInt32::iterator mLocIt = vVarLocations.begin();
884 ShaderProgramVariables::MFVariablesType::const_iterator mVarIt =
885 pMFVars->begin();
886 ShaderProgramVariables::MFVariablesType::const_iterator mVarEnd =
887 pMFVars->end ();
889 ShaderProgramVariables::MFVariableChangedType::iterator mVarChgIt =
890 pMFVarChg->begin();
892 bool warnUnknown = ShaderVariable::WarnUnknown;
894 for(; mVarIt != mVarEnd; ++mVarIt, ++mLocIt, ++mVarChgIt)
896 ShaderVariable *pVar = *mVarIt;
898 if(pVar == NULL)
899 continue;
901 if(*mVarChgIt == false)
902 continue;
904 *mVarChgIt = false;
906 osgUniformShaderVariableSwitch(pEnv, pVar,
907 *mLocIt, uiProgram, warnUnknown);
911 void ComputeShaderChunk::updateProceduralVariables(
912 DrawEnv *pEnv,
913 UInt32 uiUpdateDependents)
915 UInt32 uiProgram = pEnv->getActiveShader();
917 if(uiProgram == 0)
918 return;
920 const ShaderProgramVariables::MFProceduralVariablesType *pMFVars = NULL;
922 if(_sfVariables.getValue() != NULL)
924 pMFVars = _sfVariables.getValue()->getMFProceduralVariables();
927 if(pMFVars == NULL || pMFVars->size() == 0)
929 return;
932 MFInt32 &vVarLocations = *this->editMFProceduralVariableLocations();
934 OSG_ASSERT(pMFVars->size() == vVarLocations.size());
936 MFInt32::iterator mLocIt = vVarLocations.begin();
938 ShaderProgramVariables::MFProceduralVariablesType::const_iterator mVarIt =
939 pMFVars->begin();
940 ShaderProgramVariables::MFProceduralVariablesType::const_iterator mVarEnd =
941 pMFVars->end ();
943 Window *pWin = pEnv->getWindow();
945 osgSinkUnusedWarning(pWin);
947 for(; mVarIt != mVarEnd; ++mVarIt, ++mLocIt)
949 ShaderVariable *pVar = *mVarIt;
951 switch(pVar->getTypeId())
953 case ShaderVariable::SHVTypeOSG:
955 ShaderVariableOSG *p =
956 dynamic_cast<ShaderVariableOSG *>(pVar);
958 if(0x0000 == (p->getDependency() & uiUpdateDependents))
959 continue;
961 if(*mLocIt == -1)
963 OSGGETGLFUNCBYID_GL3_ES(
964 glGetUniformLocation,
965 osgGlGetUniformLocation,
966 ShaderProgram::getFuncIdGetUniformLocation(),
967 pWin);
969 *mLocIt = osgGlGetUniformLocation(uiProgram,
970 p->getName().c_str());
973 p->evaluate(pEnv, *mLocIt);
975 break;
977 case ShaderVariable::SHVTypeFunctor:
979 ShaderVariableFunctor *p =
980 dynamic_cast<ShaderVariableFunctor *>(pVar);
982 if(0x0000 == (p->getDependency() & uiUpdateDependents))
983 continue;
985 if(*mLocIt == -1)
987 OSGGETGLFUNCBYID_GL3_ES(
988 glGetUniformLocation,
989 osgGlGetUniformLocation,
990 ShaderProgram::getFuncIdGetUniformLocation(),
991 pWin);
993 *mLocIt = osgGlGetUniformLocation(uiProgram,
994 p->getName().c_str());
997 p->evaluate(pEnv, *mLocIt);
999 break;
1001 default:
1002 break;
1008 OSG_END_NAMESPACE