1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000-2006 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
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. *
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. *
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. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
39 //---------------------------------------------------------------------------
41 //---------------------------------------------------------------------------
46 #include <boost/bind.hpp>
48 #include "OSGConfig.h"
50 #include "OSGShaderExecutableChunk.h"
51 #include "OSGShaderProgramChunk.h"
52 #include "OSGShaderVariables.h"
54 #include "OSGGLFuncProtos.h"
55 #include "OSGConceptPropertyChecks.h"
59 // Documentation for this class is emitted in the
60 // OSGShaderExecutableChunkBase.cpp file.
61 // To modify it, please change the .fcd file (OSGShaderExecutableChunk.fcd) and
62 // regenerate the base file.
64 /***************************************************************************\
66 \***************************************************************************/
68 StateChunkClass
ShaderExecutableChunk::_class("ShaderExecutable", 1, 7);
69 volatile UInt16
ShaderExecutableChunk::_uiChunkCounter
= 1;
71 UInt32
ShaderExecutableChunk::_extSHL
= Window::invalidExtensionID
;
73 /***************************************************************************\
75 \***************************************************************************/
77 void ShaderExecutableChunk::initMethod(InitPhase ePhase
)
79 Inherited::initMethod(ePhase
);
81 if(ePhase
== TypeObject::SystemPost
)
83 _extSHL
= Window::registerExtension("GL_ARB_shading_language_100");
87 void ShaderExecutableChunk::resolveLinks(void)
89 FragmentShaderIt fIt
= _mfFragmentShader
.begin();
90 FragmentShaderIt fEnd
= _mfFragmentShader
.end ();
92 for(; fIt
!= fEnd
; ++fIt
)
95 (*fIt
)->subParent(this);
98 GeometryShaderIt gIt
= _mfGeometryShader
.begin();
99 GeometryShaderIt gEnd
= _mfGeometryShader
.end ();
101 for(; gIt
!= gEnd
; ++gIt
)
104 (*gIt
)->subParent(this);
107 TessEvalShaderIt teIt
= _mfTessEvaluationShader
.begin();
108 TessEvalShaderIt teEnd
= _mfTessEvaluationShader
.end ();
110 for(; teIt
!= teEnd
; ++teIt
)
113 (*teIt
)->subParent(this);
116 TessControlShaderIt tcIt
= _mfTessControlShader
.begin();
117 TessControlShaderIt tcEnd
= _mfTessControlShader
.end ();
119 for(; tcIt
!= tcEnd
; ++tcIt
)
122 (*tcIt
)->subParent(this);
125 VertexShaderIt vIt
= _mfVertexShader
.begin();
126 VertexShaderIt vEnd
= _mfVertexShader
.end ();
128 for(; vIt
!= vEnd
; ++vIt
)
131 (*vIt
)->subParent(this);
134 Inherited::resolveLinks();
137 /***************************************************************************\
139 \***************************************************************************/
141 /*-------------------------------------------------------------------------*\
143 \*-------------------------------------------------------------------------*/
145 /*----------------------- constructors & destructors ----------------------*/
147 ShaderExecutableChunk::ShaderExecutableChunk(void) :
153 ShaderExecutableChunk::ShaderExecutableChunk(
154 const ShaderExecutableChunk
&source
) :
161 ShaderExecutableChunk::~ShaderExecutableChunk(void)
165 void ShaderExecutableChunk::onCreate(const ShaderExecutableChunk
*source
)
167 Inherited::onCreate(source
);
169 // ignore prototypes.
170 if(GlobalSystemState
== Startup
)
174 Window::registerGLObject(
175 boost::bind(&ShaderExecutableChunk::handleGL
,
176 ShaderExecutableChunkMTUncountedPtr(this),
178 &ShaderExecutableChunk::handleDestroyGL
));
180 _uiChunkId
= _uiChunkCounter
++;
183 void ShaderExecutableChunk::onCreateAspect(
184 const ShaderExecutableChunk
*createAspect
,
185 const ShaderExecutableChunk
*source
)
187 Inherited::onCreateAspect(createAspect
, source
);
189 _uiChunkId
= createAspect
->_uiChunkId
;
192 void ShaderExecutableChunk::onDestroy(UInt32 uiId
)
195 Window::destroyGLObject(getGLId(), 1);
197 Inherited::onDestroy(uiId
);
200 const StateChunkClass
*ShaderExecutableChunk::getClass(void) const
205 UInt16
ShaderExecutableChunk::getChunkId(void)
210 UInt32
ShaderExecutableChunk::handleGL(DrawEnv
*pEnv
,
212 Window::GLObjectStatusE mode
,
215 UInt32 returnValue
= 0;
216 Window
*pWin
= pEnv
->getWindow();
218 if(!pWin
->hasExtOrVersion(_extSHL
, 0x0200, 0x0200))
220 FWARNING(("OpenGL Shading Language is not supported, couldn't find "
221 "extension 'GL_ARB_shading_language_100'!\n"));
223 pWin
->setGLObjectId(getGLId(), 0);
228 if(mode
== Window::initialize
||
229 mode
== Window::reinitialize
||
230 mode
== Window::needrefresh
)
232 GLuint uiProgram
= GLuint(pWin
->getGLObjectId(getGLId()));;
234 if(mode
!= Window::needrefresh
)
238 OSGGETGLFUNCBYID_GL3_ES(
241 ShaderProgram::getFuncIdDeleteProgram(),
244 osgGlDeleteProgram(uiProgram
);
247 OSGGETGLFUNCBYID_GL3_ES(glCreateProgram
,
249 ShaderProgram::getFuncIdCreateProgram(),
252 OSGGETGLFUNCBYID_GL3_ES(glAttachShader
,
254 ShaderProgram::getFuncIdAttachShader(),
257 OSGGETGLFUNCBYID_GL3_ES(glLinkProgram
,
259 ShaderProgram::getFuncIdLinkProgram(),
262 uiProgram
= osgGlCreateProgram();
264 FragmentShaderIt fIt
= _mfFragmentShader
.begin();
265 FragmentShaderIt fEnd
= _mfFragmentShader
.end ();
267 for(; fIt
!= fEnd
; ++fIt
)
269 (*fIt
)->validate(pEnv
);
272 GLuint(pWin
->getGLObjectId((*fIt
)->getGLId()));
275 osgGlAttachShader(uiProgram
, uiShader
);
278 std::vector
<const Char8
*> vTFVaryings
;
279 UInt32 uiVaryingBufferIndex
= 0;
281 GeometryShaderIt gIt
= _mfGeometryShader
.begin();
282 GeometryShaderIt gEnd
= _mfGeometryShader
.end ();
284 for(; gIt
!= gEnd
; ++gIt
)
286 (*gIt
)->validate(pEnv
);
289 GLuint(pWin
->getGLObjectId((*gIt
)->getGLId()));
293 osgGlAttachShader(uiProgram
, uiShader
);
295 (*gIt
)->accumulateFeedback(pEnv
,
298 uiVaryingBufferIndex
);
302 TessEvalShaderIt teIt
= _mfTessEvaluationShader
.begin();
303 TessEvalShaderIt teEnd
= _mfTessEvaluationShader
.end ();
305 for(; teIt
!= teEnd
; ++teIt
)
307 (*teIt
)->validate(pEnv
);
310 GLuint(pWin
->getGLObjectId((*teIt
)->getGLId()));
313 osgGlAttachShader(uiProgram
, uiShader
);
317 TessControlShaderIt tcIt
= _mfTessControlShader
.begin();
318 TessControlShaderIt tcEnd
= _mfTessControlShader
.end ();
320 for(; tcIt
!= tcEnd
; ++tcIt
)
322 (*tcIt
)->validate(pEnv
);
325 GLuint(pWin
->getGLObjectId((*tcIt
)->getGLId()));
328 osgGlAttachShader(uiProgram
, uiShader
);
332 VertexShaderIt vIt
= _mfVertexShader
.begin();
333 VertexShaderIt vEnd
= _mfVertexShader
.end ();
335 for(; vIt
!= vEnd
; ++vIt
)
337 (*vIt
)->validate(pEnv
);
340 GLuint(pWin
->getGLObjectId((*vIt
)->getGLId()));
343 osgGlAttachShader(uiProgram
, uiShader
);
346 if(vTFVaryings
.size() != 0)
348 OSGGETGLFUNCBYID_GL3(
349 glTransformFeedbackVaryings
,
350 osgGlTransformFeedbackVaryings
,
351 ShaderProgram::getFuncIdTransformFeedbackVaryings(),
354 osgGlTransformFeedbackVaryings(uiProgram
,
355 GLsizei(vTFVaryings
.size()),
356 &(vTFVaryings
.front()),
357 GL_INTERLEAVED_ATTRIBS
);
360 // attribute binding must be done before linking
361 updateAttribBindings(pEnv
, uiProgram
);
363 // parameters must be set before linking
364 updateParameters(pEnv
, uiProgram
);
366 osgGlLinkProgram(uiProgram
);
369 Char8
*szInfoBuffer
= NULL
;
371 OSGGETGLFUNCBYID_GL3_ES(glGetProgramiv
,
373 ShaderProgram::getFuncIdGetProgramiv(),
376 osgGlGetProgramiv(uiProgram
,
377 GL_OBJECT_INFO_LOG_LENGTH_ARB
,
382 szInfoBuffer
= new Char8
[iInfoLength
];
383 szInfoBuffer
[0] = '\0';
385 OSGGETGLFUNCBYID_GL3_ES(
387 osgGlGetProgramInfoLog
,
388 ShaderProgram::getFuncIdGetProgramInfoLog(),
391 osgGlGetProgramInfoLog( uiProgram
,
399 osgGlGetProgramiv(uiProgram
, GL_LINK_STATUS
, &iStatus
);
401 GLint iNumAttribs
= 0;
402 GLint iMaxAttribLength
= 0;
404 osgGlGetProgramiv(uiProgram
, GL_ACTIVE_ATTRIBUTES
, &iNumAttribs
);
406 osgGlGetProgramiv( uiProgram
,
407 GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
,
410 if(iMaxAttribLength
> 0)
412 Char8
*szAttribBuffer
= NULL
;
417 szAttribBuffer
= new Char8
[iMaxAttribLength
];
418 szAttribBuffer
[0] = '\0';
420 OSGGETGLFUNCBYID_GL3_ES(
422 osgGlGetActiveAttrib
,
423 ShaderProgram::getFuncIdGetActiveAttrib(),
426 for(GLint i
= 0; i
< iNumAttribs
; ++i
)
428 osgGlGetActiveAttrib( uiProgram
,
438 if(iNameLength
< 3 ||
439 szAttribBuffer
[0] != 'g' ||
440 szAttribBuffer
[1] != 'l' ||
441 szAttribBuffer
[2] != '_' )
443 pWin
->setGLObjectInfo(getGLId(), UsesAttribs
);
451 delete [] szAttribBuffer
;
456 if(szInfoBuffer
!= NULL
&& szInfoBuffer
[0] != '\0')
458 FFATAL(("Couldn't link vertex and fragment program!\n%s\n",
462 if(!getMFVertexShader()->empty())
464 SINFO
<< "Vertex Shader Code:\n";
466 vIt
= getMFVertexShader()->begin();
467 vEnd
= getMFVertexShader()->end ();
469 for(; vIt
!= vEnd
; ++vIt
)
471 PINFO
<< (*vIt
)->getProgram()
476 if(!getMFTessControlShader()->empty())
478 SINFO
<< "TessControl Shader Code:\n";
480 tcIt
= getMFTessControlShader()->begin();
481 tcEnd
= getMFTessControlShader()->end ();
483 for(; tcIt
!= tcEnd
; ++tcIt
)
485 PINFO
<< (*tcIt
)->getProgram()
490 if(!getMFTessEvaluationShader()->empty())
492 SINFO
<< "TessEvaluation Shader Code:\n";
494 teIt
= getMFTessEvaluationShader()->begin();
495 teEnd
= getMFTessEvaluationShader()->end ();
497 for(; teIt
!= teEnd
; ++teIt
)
499 PINFO
<< (*teIt
)->getProgram()
504 if(!getMFGeometryShader()->empty())
506 SINFO
<< "Geometry Shader Code:\n";
508 gIt
= getMFGeometryShader()->begin();
509 gEnd
= getMFGeometryShader()->end ();
511 for(; gIt
!= gEnd
; ++gIt
)
513 PINFO
<< (*gIt
)->getProgram()
518 if(!getMFFragmentShader()->empty())
520 SINFO
<< "Fragment Shader Code:\n";
522 fIt
= getMFFragmentShader()->begin();
523 fEnd
= getMFFragmentShader()->end ();
525 for(; fIt
!= fEnd
; ++fIt
)
527 PINFO
<< (*fIt
)->getProgram()
535 FFATAL(("Couldn't link vertex and fragment program!\n"
536 "No further info available\n"));
539 OSGGETGLFUNCBYID_GL3_ES(glDeleteProgram
,
541 ShaderProgram::getFuncIdDeleteProgram(),
544 osgGlDeleteProgram(uiProgram
);
550 if(szInfoBuffer
!= NULL
&& szInfoBuffer
[0] != '\0')
552 FWARNING(("SHLChunk: link status: %s\n", szInfoBuffer
));
556 pWin
->setGLObjectId(getGLId(), uiProgram
);
558 updateVariableLocations(pEnv
, uiProgram
);
560 delete [] szInfoBuffer
;
565 OSGGETGLFUNCBYID_GL3_ES(glUseProgram
,
567 ShaderProgram::getFuncIdUseProgram(),
570 pEnv
->setActiveShader(uiProgram
);
571 osgGlUseProgram (uiProgram
);
573 updateVariables(pEnv
, uiProgram
);
575 if(0x0000 == (uiOptions
& KeepProgActive
))
577 pEnv
->setActiveShader(0);
582 returnValue
|= ProgActive
;
590 void ShaderExecutableChunk::handleDestroyGL(DrawEnv
*pEnv
,
592 Window::GLObjectStatusE mode
)
594 Window
*pWin
= pEnv
->getWindow();
596 if(!pWin
->hasExtOrVersion(_extSHL
, 0x0200, 0x0200))
598 FWARNING(("OpenGL Shading Language is not supported, couldn't find "
599 "extension 'GL_ARB_shading_language_100'!\n"));
601 pWin
->setGLObjectId(id
, 0);
606 // BUG this is not called for every window!
607 if(mode
== Window::destroy
)
609 GLuint uiProgram
= GLuint(pWin
->getGLObjectId(id
));
613 OSGGETGLFUNCBYID_GL3_ES(glDeleteProgram
,
615 ShaderProgram::getFuncIdDeleteProgram(),
618 osgGlDeleteProgram(uiProgram
);
620 pWin
->setGLObjectId(id
, 0);
623 else if(mode
== Window::finaldestroy
)
625 ;//SWARNING << "Last program user destroyed" << std::endl;
629 /*----------------------------- class specific ----------------------------*/
631 void ShaderExecutableChunk::changed(ConstFieldMaskArg whichField
,
635 bool bMarkChanged
= false;
637 if(0x0000 != (whichField
& VariablesFieldMask
))
639 ShaderProgramVariables
*pVars
= _sfVariables
.getValue();
643 if(details
== 0x0001)
645 // be save reset all locations
647 if(pVars
->getMFVariables()->size() == 0)
649 editMFVariableLocations()->clear();
653 editMFVariableLocations()->resize(
654 pVars
->getMFVariables()->size(),
657 std::fill(editMFVariableLocations()->begin(),
658 editMFVariableLocations()->end (),
662 // be save reset all locations
664 if(pVars
->getMFProceduralVariables()->size() == 0 )
666 editMFProceduralVariableLocations()->clear();
670 editMFProceduralVariableLocations()->resize(
671 pVars
->getMFProceduralVariables()->size(),
674 std::fill(editMFProceduralVariableLocations()->begin(),
675 editMFProceduralVariableLocations()->end (),
681 Window::refreshGLObject(this->getGLId());
684 if(0x0000 != (whichField
& (VertexShaderFieldMask
|
685 GeometryShaderFieldMask
|
686 FragmentShaderFieldMask
)))
688 if(details
== ShaderProgram::ProgramFieldMask
)
690 Window::reinitializeGLObject(this->getGLId());
693 else if(details
== ShaderProgram::VariablesFieldMask
)
695 this->remergeVariables();
697 Window::refreshGLObject(this->getGLId());
703 if(0x0000 != (whichField
& (GeometryVerticesOutFieldMask
|
704 GeometryInputTypeFieldMask
|
705 GeometryOutputTypeFieldMask
)))
707 // changing parameters requires re-linking the shader
708 Window::reinitializeGLObject(this->getGLId());
711 if(bMarkChanged
== true)
713 // be save reset all locations
715 std::fill(editMFVariableLocations()->begin(),
716 editMFVariableLocations()->end (),
719 std::fill(editMFProceduralVariableLocations()->begin(),
720 editMFProceduralVariableLocations()->end (),
723 if(_sfVariables
.getValue() != NULL
)
725 _sfVariables
.getValue()->markAllChanged();
729 Inherited::changed(whichField
, origin
, details
);
732 void ShaderExecutableChunk::dump( UInt32
,
733 const BitVector
) const
735 SLOG
<< "Dump ShaderExecutableChunk NI" << std::endl
;
738 void ShaderExecutableChunk::activate(DrawEnv
*pEnv
,
741 Window
*pWin
= pEnv
->getWindow();
742 UInt32 uiValRes
= pWin
->validateGLObject(getGLId(),
746 GLuint uiProgId
= GLuint(pWin
->getGLObjectId(getGLId()));
751 if(0x0000 == (uiValRes
& ProgActive
))
753 OSGGETGLFUNCBYID_GL3_ES(glUseProgram
,
755 ShaderProgram::getFuncIdUseProgram(),
758 pEnv
->setActiveShader(uiProgId
);
759 osgGlUseProgram (uiProgId
);
762 if(_mfAttributes
.size() == 0 &&
763 (pWin
->getGLObjectInfo(getGLId()) & UsesAttribs
) == 0x0000 )
765 pEnv
->addRequiredOGLFeature(HardwareContext::HasAttribAliasing
);
768 pEnv
->incNumShaderChanges();
770 updateProceduralVariables(pEnv
, ShaderProcVariable::SHDAll
);
772 if(_sfPointSize
.getValue() == true)
774 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB
);
778 void ShaderExecutableChunk::changeFrom(DrawEnv
*pEnv
,
782 ShaderExecutableChunk
*pOld
= dynamic_cast<ShaderExecutableChunk
*>(pOther
);
784 // pOther can be a SimpleSHLChunk, since we share our StateClass id with it
787 Window
*pWin
= pEnv
->getWindow();
788 GLuint uiProgId
= GLuint(pWin
->getGLObjectId(getGLId()));
790 UInt32 uiDep
= ShaderProcVariable::SHDObject
;
792 if(uiProgId
!= pEnv
->getActiveShader())
794 UInt32 uiValRes
= pWin
->validateGLObject(getGLId(),
799 uiProgId
= GLuint(pWin
->getGLObjectId(getGLId()));
804 if(0x0000 == (uiValRes
& ProgActive
))
806 OSGGETGLFUNCBYID_GL3_ES(glUseProgram
,
808 ShaderProgram::getFuncIdUseProgram(),
811 pEnv
->setActiveShader(uiProgId
);
812 osgGlUseProgram (uiProgId
);
815 if(_mfAttributes
.size() == 0 &&
816 (pWin
->getGLObjectInfo(getGLId()) & UsesAttribs
) == 0x0000 )
818 pEnv
->addRequiredOGLFeature(
819 HardwareContext::HasAttribAliasing
);
822 if(_sfPointSize
.getValue() == true)
824 if(pOld
->getPointSize() == false)
826 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB
);
831 if(pOld
->getPointSize() == true)
833 glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB
);
837 uiDep
= ShaderProcVariable::SHDAll
;
839 pEnv
->incNumShaderChanges();
842 updateProceduralVariables(pEnv
, uiDep
);
846 pOther
->deactivate(pEnv
, uiIdx
);
847 activate (pEnv
, uiIdx
);
849 pEnv
->incNumShaderChanges();
853 void ShaderExecutableChunk::deactivate(DrawEnv
*pEnv
,
856 if(pEnv
->getWindow()->getGLObjectId(getGLId()) == 0)
859 OSGGETGLFUNC_GL3_ES(glUseProgram
,
861 ShaderProgram::getFuncIdUseProgram());
863 if(_sfPointSize
.getValue() == true)
865 glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB
);
868 pEnv
->setActiveShader(0);
870 pEnv
->subRequiredOGLFeature(HardwareContext::HasAttribAliasing
);
872 if(pEnv
->_openGLState
.isTransformFeedbackActive() == true)
874 pEnv
->_openGLState
.setTransformFeedbackInactive();
876 OSGGETGLFUNCBYID_GL3(glEndTransformFeedback
,
877 osgGlEndTransformFeedback
,
878 ShaderProgram::getFuncIdEndTransformFeedback(),
881 osgGlEndTransformFeedback();
887 void ShaderExecutableChunk::updateObjectDependencies(DrawEnv
*pEnv
,
890 updateProceduralVariables(pEnv
, ShaderProcVariable::SHDObject
);
893 void ShaderExecutableChunk::merge(const ShaderProgramChunk
*pChunk
)
895 editMField(VertexShaderFieldMask
, _mfVertexShader
);
896 editMField(TessControlShaderFieldMask
, _mfTessControlShader
);
897 editMField(TessEvaluationShaderFieldMask
, _mfTessEvaluationShader
);
898 editMField(GeometryShaderFieldMask
, _mfGeometryShader
);
899 editMField(FragmentShaderFieldMask
, _mfFragmentShader
);
900 editMField(AttributesFieldMask
, _mfAttributes
);
902 if(_sfVariables
.getValue() == NULL
)
904 ShaderProgramVariablesUnrecPtr pVar
=
905 ShaderProgramVariables::createDependent(
906 this->getFieldFlags()->_bNamespaceMask
);
911 _mfVertexShader
.reserve(_mfVertexShader
.size() +
912 pChunk
->getMFVertexShader()->size());
914 ShaderProgramChunk::MFVertexShaderType::const_iterator sIt
=
915 pChunk
->getMFVertexShader()->begin();
917 ShaderProgramChunk::MFVertexShaderType::const_iterator sEnd
=
918 pChunk
->getMFVertexShader()->end();
920 _mfAttributes
.clear();
922 bool bPointSize
= false;
924 for(; sIt
!= sEnd
; ++sIt
)
926 (*sIt
)->addParent(this, VertexShaderFieldId
);
928 _mfVertexShader
.push_back(*sIt
);
930 _sfVariables
.getValue()->merge(
931 (*sIt
)->getVariables(),
932 this->editMFVariableLocations(),
933 this->editMFProceduralVariableLocations());
935 bPointSize
|= (*sIt
)->getPointSize();
937 if((*sIt
)->hasAttributes() == true)
939 _mfAttributes
.reserve(_mfAttributes
.size() +
940 (*sIt
)->getMFAttributes()->size());
942 _mfAttributes
.insert(_mfAttributes
.end(),
943 (*sIt
)->getMFAttributes()->begin(),
944 (*sIt
)->getMFAttributes()->end ());
948 if(bPointSize
!= _sfPointSize
.getValue())
950 this->setPointSize(bPointSize
);
953 _mfTessControlShader
.reserve(_mfTessControlShader
.size() +
954 pChunk
->getMFTessControlShader()->size());
956 sIt
= pChunk
->getMFTessControlShader()->begin();
957 sEnd
= pChunk
->getMFTessControlShader()->end ();
959 for(; sIt
!= sEnd
; ++sIt
)
961 (*sIt
)->addParent(this, TessControlShaderFieldId
);
963 _mfTessControlShader
.push_back(*sIt
);
965 _sfVariables
.getValue()->merge(
966 (*sIt
)->getVariables(),
967 this->editMFVariableLocations(),
968 this->editMFProceduralVariableLocations());
971 _mfTessEvaluationShader
.reserve(
972 _mfTessEvaluationShader
.size() +
973 pChunk
->getMFTessEvaluationShader()->size());
975 sIt
= pChunk
->getMFTessEvaluationShader()->begin();
976 sEnd
= pChunk
->getMFTessEvaluationShader()->end ();
978 for(; sIt
!= sEnd
; ++sIt
)
980 (*sIt
)->addParent(this, TessEvaluationShaderFieldId
);
982 _mfTessEvaluationShader
.push_back(*sIt
);
984 _sfVariables
.getValue()->merge(
985 (*sIt
)->getVariables(),
986 this->editMFVariableLocations(),
987 this->editMFProceduralVariableLocations());
992 _mfGeometryShader
.reserve(_mfGeometryShader
.size() +
993 pChunk
->getMFGeometryShader()->size());
995 sIt
= pChunk
->getMFGeometryShader()->begin();
996 sEnd
= pChunk
->getMFGeometryShader()->end ();
998 for(; sIt
!= sEnd
; ++sIt
)
1000 (*sIt
)->addParent(this, GeometryShaderFieldId
);
1002 _mfGeometryShader
.push_back(*sIt
);
1004 _sfVariables
.getValue()->merge(
1005 (*sIt
)->getVariables(),
1006 this->editMFVariableLocations(),
1007 this->editMFProceduralVariableLocations());
1009 if((*sIt
)->hasParameter() == true)
1011 ShaderProgram::MFParameterType::const_iterator pIt
=
1012 (*sIt
)->getMFParameter()->begin();
1014 ShaderProgram::MFParameterType::const_iterator pEnd
=
1015 (*sIt
)->getMFParameter()->end ();
1021 case GL_GEOMETRY_INPUT_TYPE_EXT
:
1022 this->setGeometryInputType(pIt
->second
);
1025 case GL_GEOMETRY_OUTPUT_TYPE_EXT
:
1026 this->setGeometryOutputType(pIt
->second
);
1029 case GL_GEOMETRY_VERTICES_OUT_EXT
:
1030 this->setGeometryVerticesOut(pIt
->second
);
1040 _mfFragmentShader
.reserve(_mfFragmentShader
.size() +
1041 pChunk
->getMFFragmentShader()->size());
1043 sIt
= pChunk
->getMFFragmentShader()->begin();
1044 sEnd
= pChunk
->getMFFragmentShader()->end ();
1046 for(; sIt
!= sEnd
; ++sIt
)
1048 (*sIt
)->addParent(this, FragmentShaderFieldId
);
1050 _mfFragmentShader
.push_back(*sIt
);
1052 _sfVariables
.getValue()->merge(
1053 (*sIt
)->getVariables(),
1054 this->editMFVariableLocations(),
1055 this->editMFProceduralVariableLocations());
1059 void ShaderExecutableChunk::remergeVariables(void)
1061 OSG_ASSERT(_sfVariables
.getValue() != NULL
);
1063 _sfVariables
.getValue()->clearVariables();
1064 _sfVariables
.getValue()->clearProceduralVariables();
1066 this->editMFVariableLocations ()->clear();
1067 this->editMFProceduralVariableLocations()->clear();
1070 ShaderExecutableChunk::MFVertexShaderType::const_iterator sIt
=
1071 _mfVertexShader
.begin();
1073 ShaderExecutableChunk::MFVertexShaderType::const_iterator sEnd
=
1074 _mfVertexShader
.end();
1077 for(; sIt
!= sEnd
; ++sIt
)
1081 _sfVariables
.getValue()->merge(
1082 (*sIt
)->getVariables(),
1083 this->editMFVariableLocations(),
1084 this->editMFProceduralVariableLocations());
1090 sIt
= _mfTessControlShader
.begin();
1091 sEnd
= _mfTessControlShader
.end ();
1093 for(; sIt
!= sEnd
; ++sIt
)
1097 _sfVariables
.getValue()->merge(
1098 (*sIt
)->getVariables(),
1099 this->editMFVariableLocations (),
1100 this->editMFProceduralVariableLocations());
1106 sIt
= _mfTessEvaluationShader
.begin();
1107 sEnd
= _mfTessEvaluationShader
.end ();
1109 for(; sIt
!= sEnd
; ++sIt
)
1113 _sfVariables
.getValue()->merge(
1114 (*sIt
)->getVariables(),
1115 this->editMFVariableLocations (),
1116 this->editMFProceduralVariableLocations());
1122 sIt
= _mfGeometryShader
.begin();
1123 sEnd
= _mfGeometryShader
.end ();
1125 for(; sIt
!= sEnd
; ++sIt
)
1129 _sfVariables
.getValue()->merge(
1130 (*sIt
)->getVariables(),
1131 this->editMFVariableLocations (),
1132 this->editMFProceduralVariableLocations());
1138 sIt
= _mfFragmentShader
.begin();
1139 sEnd
= _mfFragmentShader
.end ();
1141 for(; sIt
!= sEnd
; ++sIt
)
1145 _sfVariables
.getValue()->merge(
1146 (*sIt
)->getVariables(),
1147 this->editMFVariableLocations (),
1148 this->editMFProceduralVariableLocations());
1153 void ShaderExecutableChunk::updateVariableLocations(DrawEnv
*pEnv
,
1159 const ShaderProgramVariables::MFVariablesType
*pMFVars
= NULL
;
1160 const ShaderProgramVariables::MFProceduralVariablesType
*pMFProcVars
= NULL
;
1162 if(_sfVariables
.getValue() != NULL
)
1164 pMFVars
= _sfVariables
.getValue()->getMFVariables ();
1165 pMFProcVars
= _sfVariables
.getValue()->getMFProceduralVariables();
1168 if(pMFVars
!= NULL
&& pMFVars
->size() != 0)
1170 MFInt32
&vVarLocations
= *this->editMFVariableLocations();
1172 OSG_ASSERT(pMFVars
->size() == vVarLocations
.size());
1174 MFInt32::iterator mLocIt
= vVarLocations
.begin();
1176 ShaderProgramVariables::MFVariablesType::const_iterator mVarIt
=
1178 ShaderProgramVariables::MFVariablesType::const_iterator mVarEnd
=
1181 OSGGETGLFUNC_GL3_ES(glGetUniformLocation
,
1182 osgGlGetUniformLocation
,
1183 ShaderProgram::getFuncIdGetUniformLocation());
1185 for(; mVarIt
!= mVarEnd
; ++mVarIt
, ++mLocIt
)
1187 *mLocIt
= osgGlGetUniformLocation(uiProgram
,
1188 (*mVarIt
)->getName().c_str());
1192 if(pMFProcVars
!= NULL
&& pMFProcVars
->size() != 0)
1194 MFInt32
&vVarLocations
= *this->editMFProceduralVariableLocations();
1196 OSG_ASSERT(pMFProcVars
->size() == vVarLocations
.size());
1198 MFInt32::iterator mLocIt
= vVarLocations
.begin();
1200 ShaderProgramVariables::MFProceduralVariablesType::const_iterator
1201 mVarIt
= pMFProcVars
->begin();
1202 ShaderProgramVariables::MFProceduralVariablesType::const_iterator
1203 mVarEnd
= pMFProcVars
->end ();
1205 OSGGETGLFUNC_GL3_ES(glGetUniformLocation
,
1206 osgGlGetUniformLocation
,
1207 ShaderProgram::getFuncIdGetUniformLocation());
1209 for(; mVarIt
!= mVarEnd
; ++mVarIt
, ++mLocIt
)
1211 *mLocIt
= osgGlGetUniformLocation(uiProgram
,
1212 (*mVarIt
)->getName().c_str());
1217 void ShaderExecutableChunk::updateVariables(DrawEnv
*pEnv
,
1223 const ShaderProgramVariables::MFVariablesType
*pMFVars
= NULL
;
1224 ShaderProgramVariables::MFVariableChangedType
*pMFVarChg
= NULL
;
1226 if(_sfVariables
.getValue() != NULL
)
1228 pMFVars
= _sfVariables
.getValue()->getMFVariables ();
1229 pMFVarChg
= _sfVariables
.getValue()->editMFVariableChanged();
1232 if(pMFVars
== NULL
|| pMFVars
->size() == 0 || pMFVarChg
== NULL
)
1237 OSG_ASSERT(pMFVars
->size() == pMFVarChg
->size());
1239 MFInt32
&vVarLocations
= *this->editMFVariableLocations();
1241 OSG_ASSERT(pMFVars
->size() == vVarLocations
.size());
1243 MFInt32::iterator mLocIt
= vVarLocations
.begin();
1245 ShaderProgramVariables::MFVariablesType::const_iterator mVarIt
=
1247 ShaderProgramVariables::MFVariablesType::const_iterator mVarEnd
=
1250 ShaderProgramVariables::MFVariableChangedType::iterator mVarChgIt
=
1253 bool warnUnknown
= ShaderVariable::WarnUnknown
;
1255 for(; mVarIt
!= mVarEnd
; ++mVarIt
, ++mLocIt
, ++mVarChgIt
)
1257 ShaderVariable
*pVar
= *mVarIt
;
1262 if(*mVarChgIt
== false)
1267 osgUniformShaderVariableSwitch(pEnv
, pVar
,
1268 *mLocIt
, uiProgram
, warnUnknown
);
1272 void ShaderExecutableChunk::updateAttribBindings(DrawEnv
*pEnv
,
1275 MFAttributesType::const_iterator aIt
= _mfAttributes
.begin();
1276 MFAttributesType::const_iterator aEnd
= _mfAttributes
.end ();
1281 OSGGETGLFUNC_GL3_ES(glBindAttribLocation
,
1282 osgGlBindAttribLocation
,
1283 ShaderProgram::getFuncIdBindAttribLocation());
1285 for(; aIt
!= aEnd
; ++aIt
)
1287 osgGlBindAttribLocation(uiProgram
, (*aIt
).first
, (*aIt
).second
.c_str());
1291 void ShaderExecutableChunk::updateParameters(DrawEnv
*pEnv
,
1294 if(uiProgram
== 0 || this->getGeometryVerticesOut() == 0)
1297 OSGGETGLFUNC_EXT(glProgramParameteriEXT
,
1298 osgGlProgramParameteriEXT
,
1299 ShaderProgram::getFuncIdProgramParameteri());
1301 osgGlProgramParameteriEXT(uiProgram
,
1302 GL_GEOMETRY_VERTICES_OUT_EXT
,
1303 this->getGeometryVerticesOut());
1304 osgGlProgramParameteriEXT(uiProgram
,
1305 GL_GEOMETRY_INPUT_TYPE_EXT
,
1306 this->getGeometryInputType());
1307 osgGlProgramParameteriEXT(uiProgram
,
1308 GL_GEOMETRY_OUTPUT_TYPE_EXT
,
1309 this->getGeometryOutputType());
1312 void ShaderExecutableChunk::updateProceduralVariables(
1314 UInt32 uiUpdateDependents
)
1316 UInt32 uiProgram
= pEnv
->getActiveShader();
1321 const ShaderProgramVariables::MFProceduralVariablesType
*pMFVars
= NULL
;
1323 if(_sfVariables
.getValue() != NULL
)
1325 pMFVars
= _sfVariables
.getValue()->getMFProceduralVariables();
1328 if(pMFVars
== NULL
|| pMFVars
->size() == 0)
1333 MFInt32
&vVarLocations
= *this->editMFProceduralVariableLocations();
1335 OSG_ASSERT(pMFVars
->size() == vVarLocations
.size());
1337 MFInt32::iterator mLocIt
= vVarLocations
.begin();
1339 ShaderProgramVariables::MFProceduralVariablesType::const_iterator mVarIt
=
1341 ShaderProgramVariables::MFProceduralVariablesType::const_iterator mVarEnd
=
1344 Window
*pWin
= pEnv
->getWindow();
1346 osgSinkUnusedWarning(pWin
);
1348 #ifdef OSG_1_COMPATX
1349 if(_fParameterCallback
)
1351 OSGGETGLFUNCBYID_GL3_ES(glGetUniformLocation
,
1352 osgGlGetUniformLocation
,
1353 ShaderProgram::getFuncIdGetUniformLocation(),
1356 _fParameterCallback(osgGlGetUniformLocation
, pEnv
, uiProgram
);
1360 for(; mVarIt
!= mVarEnd
; ++mVarIt
, ++mLocIt
)
1362 ShaderVariable
*pVar
= *mVarIt
;
1364 switch(pVar
->getTypeId())
1366 case ShaderVariable::SHVTypeOSG
:
1368 ShaderVariableOSG
*p
=
1369 dynamic_cast<ShaderVariableOSG
*>(pVar
);
1371 if(0x0000 == (p
->getDependency() & uiUpdateDependents
))
1376 OSGGETGLFUNCBYID_GL3_ES(
1377 glGetUniformLocation
,
1378 osgGlGetUniformLocation
,
1379 ShaderProgram::getFuncIdGetUniformLocation(),
1382 *mLocIt
= osgGlGetUniformLocation(uiProgram
,
1383 p
->getName().c_str());
1385 #ifdef OSG_MULTISHADER_VARCHUNK
1391 p
->evaluate(pEnv
, *mLocIt
);
1395 case ShaderVariable::SHVTypeFunctor
:
1397 ShaderVariableFunctor
*p
=
1398 dynamic_cast<ShaderVariableFunctor
*>(pVar
);
1400 if(0x0000 == (p
->getDependency() & uiUpdateDependents
))
1405 OSGGETGLFUNCBYID_GL3_ES(
1406 glGetUniformLocation
,
1407 osgGlGetUniformLocation
,
1408 ShaderProgram::getFuncIdGetUniformLocation(),
1411 *mLocIt
= osgGlGetUniformLocation(uiProgram
,
1412 p
->getName().c_str());
1413 #ifdef OSG_MULTISHADER_VARCHUNK
1420 switch(p
->getFuncMode())
1424 p
->evaluate(pEnv
, *mLocIt
);
1430 OSGGETGLFUNCBYID_GL3_ES(
1431 glGetUniformLocation
,
1432 osgGlGetUniformLocation
,
1433 ShaderProgram::getFuncIdGetUniformLocation(),
1436 p
->evaluate(osgGlGetUniformLocation
,
1451 p
->evaluate(pEnv
, *mLocIt
);