changed: gcc8 base update
[opensg.git] / Source / System / State / Shader / Chunks / OSGShaderExecutableChunk.cpp
blobeb13b5ca9f0c05490670ca279ab9f7c0b3a8f80c
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 <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"
57 OSG_BEGIN_NAMESPACE
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 /***************************************************************************\
65 * Class variables *
66 \***************************************************************************/
68 StateChunkClass ShaderExecutableChunk::_class("ShaderExecutable", 1, 7);
69 volatile UInt16 ShaderExecutableChunk::_uiChunkCounter = 1;
71 UInt32 ShaderExecutableChunk::_extSHL = Window::invalidExtensionID;
73 /***************************************************************************\
74 * Class methods *
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)
94 if(*fIt != NULL)
95 (*fIt)->subParent(this);
98 GeometryShaderIt gIt = _mfGeometryShader.begin();
99 GeometryShaderIt gEnd = _mfGeometryShader.end ();
101 for(; gIt != gEnd; ++gIt)
103 if(*gIt != NULL)
104 (*gIt)->subParent(this);
107 TessEvalShaderIt teIt = _mfTessEvaluationShader.begin();
108 TessEvalShaderIt teEnd = _mfTessEvaluationShader.end ();
110 for(; teIt != teEnd; ++teIt)
112 if(*teIt != NULL)
113 (*teIt)->subParent(this);
116 TessControlShaderIt tcIt = _mfTessControlShader.begin();
117 TessControlShaderIt tcEnd = _mfTessControlShader.end ();
119 for(; tcIt != tcEnd; ++tcIt)
121 if(*tcIt != NULL)
122 (*tcIt)->subParent(this);
125 VertexShaderIt vIt = _mfVertexShader.begin();
126 VertexShaderIt vEnd = _mfVertexShader.end ();
128 for(; vIt != vEnd; ++vIt)
130 if(*vIt != NULL)
131 (*vIt)->subParent(this);
134 Inherited::resolveLinks();
137 /***************************************************************************\
138 * Instance methods *
139 \***************************************************************************/
141 /*-------------------------------------------------------------------------*\
142 - private -
143 \*-------------------------------------------------------------------------*/
145 /*----------------------- constructors & destructors ----------------------*/
147 ShaderExecutableChunk::ShaderExecutableChunk(void) :
148 Inherited( ),
149 _uiChunkId(0)
153 ShaderExecutableChunk::ShaderExecutableChunk(
154 const ShaderExecutableChunk &source) :
156 Inherited(source),
157 _uiChunkId(0 )
161 ShaderExecutableChunk::~ShaderExecutableChunk(void)
165 void ShaderExecutableChunk::onCreate(const ShaderExecutableChunk *source)
167 Inherited::onCreate(source);
169 // ignore prototypes.
170 if(GlobalSystemState == Startup)
171 return;
173 setGLId(
174 Window::registerGLObject(
175 boost::bind(&ShaderExecutableChunk::handleGL,
176 ShaderExecutableChunkMTUncountedPtr(this),
177 _1, _2, _3, _4),
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)
194 if(getGLId() > 0)
195 Window::destroyGLObject(getGLId(), 1);
197 Inherited::onDestroy(uiId);
200 const StateChunkClass *ShaderExecutableChunk::getClass(void) const
202 return &_class;
205 UInt16 ShaderExecutableChunk::getChunkId(void)
207 return _uiChunkId;
210 UInt32 ShaderExecutableChunk::handleGL(DrawEnv *pEnv,
211 UInt32 id,
212 Window::GLObjectStatusE mode,
213 UInt64 uiOptions)
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);
225 return returnValue;
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)
236 if(uiProgram != 0)
238 OSGGETGLFUNCBYID_GL3_ES(
239 glDeleteProgram,
240 osgGlDeleteProgram,
241 ShaderProgram::getFuncIdDeleteProgram(),
242 pWin);
244 osgGlDeleteProgram(uiProgram);
247 OSGGETGLFUNCBYID_GL3_ES(glCreateProgram,
248 osgGlCreateProgram,
249 ShaderProgram::getFuncIdCreateProgram(),
250 pWin);
252 OSGGETGLFUNCBYID_GL3_ES(glAttachShader,
253 osgGlAttachShader,
254 ShaderProgram::getFuncIdAttachShader(),
255 pWin);
257 OSGGETGLFUNCBYID_GL3_ES(glLinkProgram,
258 osgGlLinkProgram,
259 ShaderProgram::getFuncIdLinkProgram(),
260 pWin);
262 uiProgram = osgGlCreateProgram();
264 FragmentShaderIt fIt = _mfFragmentShader.begin();
265 FragmentShaderIt fEnd = _mfFragmentShader.end ();
267 for(; fIt != fEnd; ++fIt)
269 (*fIt)->validate(pEnv);
271 GLuint uiShader =
272 GLuint(pWin->getGLObjectId((*fIt)->getGLId()));
274 if(uiShader != 0)
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);
288 GLuint uiShader =
289 GLuint(pWin->getGLObjectId((*gIt)->getGLId()));
291 if(uiShader != 0)
293 osgGlAttachShader(uiProgram, uiShader);
295 (*gIt)->accumulateFeedback(pEnv,
296 uiProgram,
297 vTFVaryings,
298 uiVaryingBufferIndex);
302 TessEvalShaderIt teIt = _mfTessEvaluationShader.begin();
303 TessEvalShaderIt teEnd = _mfTessEvaluationShader.end ();
305 for(; teIt != teEnd; ++teIt)
307 (*teIt)->validate(pEnv);
309 GLuint uiShader =
310 GLuint(pWin->getGLObjectId((*teIt)->getGLId()));
312 if(uiShader != 0)
313 osgGlAttachShader(uiProgram, uiShader);
317 TessControlShaderIt tcIt = _mfTessControlShader.begin();
318 TessControlShaderIt tcEnd = _mfTessControlShader.end ();
320 for(; tcIt != tcEnd; ++tcIt)
322 (*tcIt)->validate(pEnv);
324 GLuint uiShader =
325 GLuint(pWin->getGLObjectId((*tcIt)->getGLId()));
327 if(uiShader != 0)
328 osgGlAttachShader(uiProgram, uiShader);
332 VertexShaderIt vIt = _mfVertexShader.begin();
333 VertexShaderIt vEnd = _mfVertexShader.end ();
335 for(; vIt != vEnd; ++vIt)
337 (*vIt)->validate(pEnv);
339 GLuint uiShader =
340 GLuint(pWin->getGLObjectId((*vIt)->getGLId()));
342 if(uiShader != 0)
343 osgGlAttachShader(uiProgram, uiShader);
346 if(vTFVaryings.size() != 0)
348 OSGGETGLFUNCBYID_GL3(
349 glTransformFeedbackVaryings,
350 osgGlTransformFeedbackVaryings,
351 ShaderProgram::getFuncIdTransformFeedbackVaryings(),
352 pEnv->getWindow() );
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);
368 GLint iInfoLength;
369 Char8 *szInfoBuffer = NULL;
371 OSGGETGLFUNCBYID_GL3_ES(glGetProgramiv,
372 osgGlGetProgramiv,
373 ShaderProgram::getFuncIdGetProgramiv(),
374 pWin);
376 osgGlGetProgramiv(uiProgram,
377 GL_OBJECT_INFO_LOG_LENGTH_ARB,
378 &iInfoLength);
380 if(iInfoLength > 0)
382 szInfoBuffer = new Char8[iInfoLength];
383 szInfoBuffer[0] = '\0';
385 OSGGETGLFUNCBYID_GL3_ES(
386 glGetProgramInfoLog,
387 osgGlGetProgramInfoLog,
388 ShaderProgram::getFuncIdGetProgramInfoLog(),
389 pWin);
391 osgGlGetProgramInfoLog( uiProgram,
392 iInfoLength,
393 &iInfoLength,
394 szInfoBuffer);
397 GLint iStatus = 0;
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,
408 &iMaxAttribLength);
410 if(iMaxAttribLength > 0)
412 Char8 *szAttribBuffer = NULL;
413 GLsizei iNameLength;
414 GLint iSizeTmp;
415 GLenum eTypeTmp;
417 szAttribBuffer = new Char8[iMaxAttribLength];
418 szAttribBuffer[0] = '\0';
420 OSGGETGLFUNCBYID_GL3_ES(
421 glGetActiveAttrib,
422 osgGlGetActiveAttrib,
423 ShaderProgram::getFuncIdGetActiveAttrib(),
424 pWin);
426 for(GLint i = 0; i < iNumAttribs; ++i)
428 osgGlGetActiveAttrib( uiProgram,
430 iMaxAttribLength,
431 &iNameLength,
432 &iSizeTmp,
433 &eTypeTmp,
434 szAttribBuffer);
436 if(iNameLength != 0)
438 if(iNameLength < 3 ||
439 szAttribBuffer[0] != 'g' ||
440 szAttribBuffer[1] != 'l' ||
441 szAttribBuffer[2] != '_' )
443 pWin->setGLObjectInfo(getGLId(), UsesAttribs);
445 break;
451 delete [] szAttribBuffer;
454 if(iStatus == 0)
456 if(szInfoBuffer != NULL && szInfoBuffer[0] != '\0')
458 FFATAL(("Couldn't link vertex and fragment program!\n%s\n",
459 szInfoBuffer));
461 #ifdef OSG_DEBUG
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()
472 << "\n";
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()
486 << "\n";
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()
500 << "\n";
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()
514 << "\n";
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()
528 << "\n";
531 #endif // OSG_DEBUG
533 else
535 FFATAL(("Couldn't link vertex and fragment program!\n"
536 "No further info available\n"));
539 OSGGETGLFUNCBYID_GL3_ES(glDeleteProgram,
540 osgGlDeleteProgram,
541 ShaderProgram::getFuncIdDeleteProgram(),
542 pWin);
544 osgGlDeleteProgram(uiProgram);
546 uiProgram = 0;
548 else
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;
563 if(uiProgram != 0)
565 OSGGETGLFUNCBYID_GL3_ES(glUseProgram,
566 osgGlUseProgram,
567 ShaderProgram::getFuncIdUseProgram(),
568 pWin);
570 pEnv->setActiveShader(uiProgram);
571 osgGlUseProgram (uiProgram);
573 updateVariables(pEnv, uiProgram);
575 if(0x0000 == (uiOptions & KeepProgActive))
577 pEnv->setActiveShader(0);
578 osgGlUseProgram (0);
580 else
582 returnValue |= ProgActive;
587 return returnValue;
590 void ShaderExecutableChunk::handleDestroyGL(DrawEnv *pEnv,
591 UInt32 id,
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);
603 return;
606 // BUG this is not called for every window!
607 if(mode == Window::destroy)
609 GLuint uiProgram = GLuint(pWin->getGLObjectId(id));
611 if(uiProgram != 0)
613 OSGGETGLFUNCBYID_GL3_ES(glDeleteProgram,
614 osgGlDeleteProgram,
615 ShaderProgram::getFuncIdDeleteProgram(),
616 pWin);
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,
632 UInt32 origin,
633 BitVector details)
635 bool bMarkChanged = false;
637 if(0x0000 != (whichField & VariablesFieldMask))
639 ShaderProgramVariables *pVars = _sfVariables.getValue();
641 if(pVars != NULL)
643 if(details == 0x0001)
645 // be save reset all locations
647 if(pVars->getMFVariables()->size() == 0)
649 editMFVariableLocations()->clear();
651 else
653 editMFVariableLocations()->resize(
654 pVars->getMFVariables()->size(),
655 -1);
657 std::fill(editMFVariableLocations()->begin(),
658 editMFVariableLocations()->end (),
659 -1);
662 // be save reset all locations
664 if(pVars->getMFProceduralVariables()->size() == 0 )
666 editMFProceduralVariableLocations()->clear();
668 else
670 editMFProceduralVariableLocations()->resize(
671 pVars->getMFProceduralVariables()->size(),
672 -1);
674 std::fill(editMFProceduralVariableLocations()->begin(),
675 editMFProceduralVariableLocations()->end (),
676 -1);
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());
700 bMarkChanged = true;
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 (),
717 -1);
719 std::fill(editMFProceduralVariableLocations()->begin(),
720 editMFProceduralVariableLocations()->end (),
721 -1);
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,
739 UInt32 uiIdx)
741 Window *pWin = pEnv->getWindow();
742 UInt32 uiValRes = pWin->validateGLObject(getGLId(),
743 pEnv,
744 KeepProgActive);
746 GLuint uiProgId = GLuint(pWin->getGLObjectId(getGLId()));
748 if(uiProgId == 0)
749 return;
751 if(0x0000 == (uiValRes & ProgActive))
753 OSGGETGLFUNCBYID_GL3_ES(glUseProgram,
754 osgGlUseProgram,
755 ShaderProgram::getFuncIdUseProgram(),
756 pWin);
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,
779 StateChunk *pOther,
780 UInt32 uiIdx)
782 ShaderExecutableChunk *pOld = dynamic_cast<ShaderExecutableChunk *>(pOther);
784 // pOther can be a SimpleSHLChunk, since we share our StateClass id with it
785 if(pOld != NULL)
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(),
795 pEnv,
796 KeepProgActive);
799 uiProgId = GLuint(pWin->getGLObjectId(getGLId()));
801 if(uiProgId == 0)
802 return;
804 if(0x0000 == (uiValRes & ProgActive))
806 OSGGETGLFUNCBYID_GL3_ES(glUseProgram,
807 osgGlUseProgram,
808 ShaderProgram::getFuncIdUseProgram(),
809 pWin);
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);
829 else
831 if(pOld->getPointSize() == true)
833 glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
837 uiDep = ShaderProcVariable::SHDAll;
839 pEnv->incNumShaderChanges();
842 updateProceduralVariables(pEnv, uiDep);
844 else
846 pOther->deactivate(pEnv, uiIdx);
847 activate (pEnv, uiIdx);
849 pEnv->incNumShaderChanges();
853 void ShaderExecutableChunk::deactivate(DrawEnv *pEnv,
854 UInt32 uiIdx)
856 if(pEnv->getWindow()->getGLObjectId(getGLId()) == 0)
857 return;
859 OSGGETGLFUNC_GL3_ES(glUseProgram,
860 osgGlUseProgram,
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(),
879 pEnv->getWindow());
881 osgGlEndTransformFeedback();
884 osgGlUseProgram(0);
887 void ShaderExecutableChunk::updateObjectDependencies(DrawEnv *pEnv,
888 UInt32 index)
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);
908 setVariables(pVar);
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 ();
1017 while(pIt != pEnd)
1019 switch(pIt->first)
1021 case GL_GEOMETRY_INPUT_TYPE_EXT:
1022 this->setGeometryInputType(pIt->second);
1023 break;
1025 case GL_GEOMETRY_OUTPUT_TYPE_EXT:
1026 this->setGeometryOutputType(pIt->second);
1027 break;
1029 case GL_GEOMETRY_VERTICES_OUT_EXT:
1030 this->setGeometryVerticesOut(pIt->second);
1031 break;
1034 ++pIt;
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)
1079 if(*sIt != NULL)
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)
1095 if(*sIt != NULL)
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)
1111 if(*sIt != NULL)
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)
1127 if(*sIt != NULL)
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)
1143 if(*sIt != NULL)
1145 _sfVariables.getValue()->merge(
1146 (*sIt)->getVariables(),
1147 this->editMFVariableLocations (),
1148 this->editMFProceduralVariableLocations());
1153 void ShaderExecutableChunk::updateVariableLocations(DrawEnv *pEnv,
1154 UInt32 uiProgram)
1156 if(uiProgram == 0)
1157 return;
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 =
1177 pMFVars->begin();
1178 ShaderProgramVariables::MFVariablesType::const_iterator mVarEnd =
1179 pMFVars->end ();
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,
1218 UInt32 uiProgram)
1220 if(uiProgram == 0)
1221 return;
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)
1234 return;
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 =
1246 pMFVars->begin();
1247 ShaderProgramVariables::MFVariablesType::const_iterator mVarEnd =
1248 pMFVars->end ();
1250 ShaderProgramVariables::MFVariableChangedType::iterator mVarChgIt =
1251 pMFVarChg->begin();
1253 bool warnUnknown = ShaderVariable::WarnUnknown;
1255 for(; mVarIt != mVarEnd; ++mVarIt, ++mLocIt, ++mVarChgIt)
1257 ShaderVariable *pVar = *mVarIt;
1259 if(pVar == NULL)
1260 continue;
1262 if(*mVarChgIt == false)
1263 continue;
1265 *mVarChgIt = false;
1267 osgUniformShaderVariableSwitch(pEnv, pVar,
1268 *mLocIt, uiProgram, warnUnknown);
1272 void ShaderExecutableChunk::updateAttribBindings(DrawEnv *pEnv,
1273 UInt32 uiProgram)
1275 MFAttributesType::const_iterator aIt = _mfAttributes.begin();
1276 MFAttributesType::const_iterator aEnd = _mfAttributes.end ();
1278 if(aIt == aEnd)
1279 return;
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,
1292 UInt32 uiProgram)
1294 if(uiProgram == 0 || this->getGeometryVerticesOut() == 0)
1295 return;
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(
1313 DrawEnv *pEnv,
1314 UInt32 uiUpdateDependents)
1316 UInt32 uiProgram = pEnv->getActiveShader();
1318 if(uiProgram == 0)
1319 return;
1321 const ShaderProgramVariables::MFProceduralVariablesType *pMFVars = NULL;
1323 if(_sfVariables.getValue() != NULL)
1325 pMFVars = _sfVariables.getValue()->getMFProceduralVariables();
1328 if(pMFVars == NULL || pMFVars->size() == 0)
1330 return;
1333 MFInt32 &vVarLocations = *this->editMFProceduralVariableLocations();
1335 OSG_ASSERT(pMFVars->size() == vVarLocations.size());
1337 MFInt32::iterator mLocIt = vVarLocations.begin();
1339 ShaderProgramVariables::MFProceduralVariablesType::const_iterator mVarIt =
1340 pMFVars->begin();
1341 ShaderProgramVariables::MFProceduralVariablesType::const_iterator mVarEnd =
1342 pMFVars->end ();
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(),
1354 pWin);
1356 _fParameterCallback(osgGlGetUniformLocation, pEnv, uiProgram);
1358 #endif
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))
1372 continue;
1374 if(*mLocIt == -1)
1376 OSGGETGLFUNCBYID_GL3_ES(
1377 glGetUniformLocation,
1378 osgGlGetUniformLocation,
1379 ShaderProgram::getFuncIdGetUniformLocation(),
1380 pWin);
1382 *mLocIt = osgGlGetUniformLocation(uiProgram,
1383 p->getName().c_str());
1385 #ifdef OSG_MULTISHADER_VARCHUNK
1386 if(*mLocIt == -1)
1387 *mLocIt = -2;
1388 #endif
1391 p->evaluate(pEnv, *mLocIt);
1393 break;
1395 case ShaderVariable::SHVTypeFunctor:
1397 ShaderVariableFunctor *p =
1398 dynamic_cast<ShaderVariableFunctor *>(pVar);
1400 if(0x0000 == (p->getDependency() & uiUpdateDependents))
1401 continue;
1403 if(*mLocIt == -1)
1405 OSGGETGLFUNCBYID_GL3_ES(
1406 glGetUniformLocation,
1407 osgGlGetUniformLocation,
1408 ShaderProgram::getFuncIdGetUniformLocation(),
1409 pWin);
1411 *mLocIt = osgGlGetUniformLocation(uiProgram,
1412 p->getName().c_str());
1413 #ifdef OSG_MULTISHADER_VARCHUNK
1414 if(*mLocIt == -1)
1415 *mLocIt = -2;
1416 #endif
1419 #ifdef OSG_1_COMPAT
1420 switch(p->getFuncMode())
1422 case 0:
1424 p->evaluate(pEnv, *mLocIt);
1426 break;
1428 case 1:
1430 OSGGETGLFUNCBYID_GL3_ES(
1431 glGetUniformLocation,
1432 osgGlGetUniformLocation,
1433 ShaderProgram::getFuncIdGetUniformLocation(),
1434 pWin);
1436 p->evaluate(osgGlGetUniformLocation,
1437 pEnv,
1438 uiProgram);
1440 break;
1442 case 2:
1444 p->evaluate(p,
1445 pEnv,
1446 uiProgram);
1448 break;
1450 #else
1451 p->evaluate(pEnv, *mLocIt);
1452 #endif
1454 break;
1456 default:
1457 break;
1462 OSG_END_NAMESPACE