changed: gcc8 base update
[opensg.git] / Source / System / State / Shader / SHL / OSGSimpleSHLChunk.cpp
blobac795152438b9a93cfa34f763d7eadbf718c5558
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 "OSGSimpleSHLChunk.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 // OSGSimpleSHLChunkBase.cpp file.
60 // To modify it, please change the .fcd file (OSGSimpleSHLChunk.fcd) and
61 // regenerate the base file.
63 /***************************************************************************\
64 * Class variables *
65 \***************************************************************************/
67 #if 0
68 volatile UInt16 SimpleSHLChunk::_uiChunkCounter = 1;
69 #endif
71 #ifdef OSG_1_COMPAT
72 SimpleSHLChunk::ParamFunctor SimpleSHLChunk::_fParameterCallback;
73 #endif
75 /***************************************************************************\
76 * Class methods *
77 \***************************************************************************/
79 void SimpleSHLChunk::initMethod(InitPhase ePhase)
81 Inherited::initMethod(ePhase);
84 UInt32 SimpleSHLChunk::handleGL(DrawEnv *pEnv,
85 UInt32 id,
86 Window::GLObjectStatusE mode,
87 UInt64 uiOptions)
89 UInt32 returnValue = 0;
90 Window *pWin = pEnv->getWindow();
92 if(!pWin->hasExtOrVersion(_extSHL, 0x0200, 0x0200))
94 FWARNING(("OpenGL Shading Language is not supported, couldn't find "
95 "extension 'GL_ARB_shading_language_100'!\n"));
97 pWin->setGLObjectId(getGLId(), 0);
99 return returnValue;
102 if(mode == Window::initialize ||
103 mode == Window::reinitialize ||
104 mode == Window::needrefresh )
106 GLuint uiProgram = GLuint(pWin->getGLObjectId(getGLId()));;
108 if(mode != Window::needrefresh)
110 if(uiProgram != 0)
112 OSGGETGLFUNCBYID_GL3_ES(glDeleteProgram,
113 osgGlDeleteProgram,
114 ShaderProgram::getFuncIdDeleteProgram(),
115 pWin);
117 osgGlDeleteProgram(uiProgram);
120 OSGGETGLFUNCBYID_GL3_ES(glCreateProgram,
121 osgGlCreateProgram,
122 ShaderProgram::getFuncIdCreateProgram(),
123 pWin);
125 OSGGETGLFUNCBYID_GL3_ES(glAttachShader,
126 osgGlAttachShader,
127 ShaderProgram::getFuncIdAttachShader(),
128 pWin);
130 OSGGETGLFUNCBYID_GL3_ES(glLinkProgram,
131 osgGlLinkProgram,
132 ShaderProgram::getFuncIdLinkProgram(),
133 pWin);
135 uiProgram = osgGlCreateProgram();
137 FragmentShaderIt fIt = _mfFragmentShader.begin();
138 FragmentShaderIt fEnd = _mfFragmentShader.end ();
140 for(; fIt != fEnd; ++fIt)
142 (*fIt)->validate(pEnv);
144 GLuint uiShader =
145 GLuint(pWin->getGLObjectId((*fIt)->getGLId()));
147 if(uiShader != 0)
148 osgGlAttachShader(uiProgram, uiShader);
151 GeometryShaderIt gIt = _mfGeometryShader.begin();
152 GeometryShaderIt gEnd = _mfGeometryShader.end ();
154 for(; gIt != gEnd; ++gIt)
156 (*gIt)->validate(pEnv);
158 GLuint uiShader =
159 GLuint(pWin->getGLObjectId((*gIt)->getGLId()));
161 if(uiShader != 0)
162 osgGlAttachShader(uiProgram, uiShader);
165 TessEvalShaderIt teIt = _mfTessEvaluationShader.begin();
166 TessEvalShaderIt teEnd = _mfTessEvaluationShader.end ();
168 for(; teIt != teEnd; ++teIt)
170 (*teIt)->validate(pEnv);
172 GLuint uiShader =
173 GLuint(pWin->getGLObjectId((*teIt)->getGLId()));
175 if(uiShader != 0)
176 osgGlAttachShader(uiProgram, uiShader);
179 TessControlShaderIt tcIt = _mfTessControlShader.begin();
180 TessControlShaderIt tcEnd = _mfTessControlShader.end ();
182 for(; tcIt != tcEnd; ++tcIt)
184 (*tcIt)->validate(pEnv);
186 GLuint uiShader =
187 GLuint(pWin->getGLObjectId((*tcIt)->getGLId()));
189 if(uiShader != 0)
190 osgGlAttachShader(uiProgram, uiShader);
193 VertexShaderIt vIt = _mfVertexShader.begin();
194 VertexShaderIt vEnd = _mfVertexShader.end ();
196 for(; vIt != vEnd; ++vIt)
198 (*vIt)->validate(pEnv);
200 GLuint uiShader =
201 GLuint(pWin->getGLObjectId((*vIt)->getGLId()));
203 if(uiShader != 0)
204 osgGlAttachShader(uiProgram, uiShader);
207 // parameters must be set before linking
208 updateParameters(pEnv, uiProgram);
210 osgGlLinkProgram(uiProgram);
212 GLint iInfoLength;
213 Char8 *szInfoBuffer = NULL;
215 OSGGETGLFUNCBYID_GL3_ES(glGetProgramiv,
216 osgGlGetProgramiv,
217 ShaderProgram::getFuncIdGetProgramiv(),
218 pWin);
220 osgGlGetProgramiv(uiProgram,
221 GL_OBJECT_INFO_LOG_LENGTH_ARB,
222 &iInfoLength);
224 if(iInfoLength > 0)
226 szInfoBuffer = new Char8[iInfoLength];
227 szInfoBuffer[0] = '\0';
229 OSGGETGLFUNCBYID_GL3_ES(
230 glGetProgramInfoLog,
231 osgGlGetProgramInfoLog,
232 ShaderProgram::getFuncIdGetProgramInfoLog(),
233 pWin);
235 osgGlGetProgramInfoLog( uiProgram,
236 iInfoLength,
237 &iInfoLength,
238 szInfoBuffer);
241 GLint iStatus = 0;
243 osgGlGetProgramiv(uiProgram, GL_LINK_STATUS, &iStatus);
245 if(iStatus == 0)
247 if(szInfoBuffer != NULL && szInfoBuffer[0] != '\0')
249 FFATAL(("Couldn't link vertex and fragment program!\n%s\n",
250 szInfoBuffer));
252 else
254 FFATAL(("Couldn't link vertex and fragment program!\n"
255 "No further info available\n"));
258 OSGGETGLFUNCBYID_GL3_ES(glDeleteProgram,
259 osgGlDeleteProgram,
260 ShaderProgram::getFuncIdDeleteProgram(),
261 pWin);
263 osgGlDeleteProgram(uiProgram);
265 uiProgram = 0;
267 else
269 if(szInfoBuffer != NULL && szInfoBuffer[0] != '\0')
271 FWARNING(("SimpleSHLChunk: link status: %s\n",
272 szInfoBuffer));
276 pWin->setGLObjectId(getGLId(), uiProgram);
278 updateVariableLocations(pEnv, uiProgram);
281 if(uiProgram != 0)
283 OSGGETGLFUNCBYID_GL3_ES(glUseProgram,
284 osgGlUseProgram,
285 ShaderProgram::getFuncIdUseProgram(),
286 pWin);
288 osgGlUseProgram(uiProgram);
290 updateVariables(pEnv, uiProgram);
292 if(0x0000 == (uiOptions & KeepProgActive))
294 osgGlUseProgram(0);
296 else
298 returnValue |= ProgActive;
303 return returnValue;
306 void SimpleSHLChunk::handleDestroyGL(DrawEnv *pEnv,
307 UInt32 id,
308 Window::GLObjectStatusE mode)
310 Window *pWin = pEnv->getWindow();
312 if(!pWin->hasExtOrVersion(_extSHL, 0x0200, 0x0200))
314 FWARNING(("OpenGL Shading Language is not supported, couldn't find "
315 "extension 'GL_ARB_shading_language_100'!\n"));
317 pWin->setGLObjectId(id, 0);
319 return;
322 // BUG this is not called for every window!
323 if(mode == Window::destroy)
325 GLuint uiProgram = GLuint(pWin->getGLObjectId(id));
327 if(uiProgram != 0)
329 OSGGETGLFUNCBYID_GL3_ES(glDeleteProgram,
330 osgGlDeleteProgram,
331 ShaderProgram::getFuncIdDeleteProgram(),
332 pWin);
334 osgGlDeleteProgram(uiProgram);
336 pWin->setGLObjectId(id, 0);
339 else if(mode == Window::finaldestroy)
341 ;//SWARNING << "Last program user destroyed" << std::endl;
345 /***************************************************************************\
346 * Instance methods *
347 \***************************************************************************/
349 /*-------------------------------------------------------------------------*\
350 - private -
351 \*-------------------------------------------------------------------------*/
353 /*----------------------- constructors & destructors ----------------------*/
355 SimpleSHLChunk::SimpleSHLChunk(void) :
356 Inherited( ),
357 _uiChunkId(0)
361 SimpleSHLChunk::SimpleSHLChunk(const SimpleSHLChunk &source) :
362 Inherited(source),
363 _uiChunkId(0 )
367 SimpleSHLChunk::~SimpleSHLChunk(void)
371 void SimpleSHLChunk::onCreate(const SimpleSHLChunk *source)
373 Inherited::onCreate(source);
375 // ignore prototypes.
376 if(GlobalSystemState == Startup)
377 return;
379 setGLId(
380 Window::registerGLObject(
381 boost::bind(&SimpleSHLChunk::handleGL,
382 SimpleSHLChunkMTUncountedPtr(this),
383 _1, _2, _3, _4),
384 &SimpleSHLChunk::handleDestroyGL));
386 _uiChunkId = ShaderExecutableChunk::_uiChunkCounter++;
389 void SimpleSHLChunk::onCreateAspect(const SimpleSHLChunk *createAspect,
390 const SimpleSHLChunk *source )
392 Inherited::onCreateAspect(createAspect, source);
394 _uiChunkId = createAspect->_uiChunkId;
397 void SimpleSHLChunk::onDestroy(UInt32 uiId)
399 if(getGLId() > 0)
400 Window::destroyGLObject(getGLId(), 1);
402 Inherited::onDestroy(uiId);
405 const StateChunkClass *SimpleSHLChunk::getClass(void) const
407 return ShaderExecutableChunk::getStaticClass();
410 UInt16 SimpleSHLChunk::getChunkId(void)
412 return _uiChunkId;
415 /*----------------------------- class specific ----------------------------*/
417 void SimpleSHLChunk::changed(ConstFieldMaskArg whichField,
418 UInt32 origin,
419 BitVector details)
421 bool bMarkChanged = false;
423 if(0x0000 != (whichField & FragmentProgramFieldMask) &&
424 0 != _sfFragmentProgram.getValue().size() )
426 if(_mfFragmentShader.size() == 0)
428 ShaderProgramUnrecPtr pProg = ShaderProgram::createDependent(
429 this->getFieldFlags()->_bNamespaceMask);
431 pProg->setShaderType(GL_FRAGMENT_SHADER);
433 addFragmentShader(pProg);
435 else if(_mfFragmentShader.size() > 1)
437 editMFFragmentShader()->resize(1);
440 _mfFragmentShader[0]->setProgram (_sfFragmentProgram.getValue());
441 _mfFragmentShader[0]->setCgFrontEnd(_sfCgFrontEnd .getValue());
443 bMarkChanged = true;
445 Window::reinitializeGLObject(this->getGLId());
448 if(0x0000 != (whichField & GeometryProgramFieldMask) &&
449 0 != _sfGeometryProgram.getValue().size() )
451 if(_mfGeometryShader.size() == 0)
453 ShaderProgramUnrecPtr pProg = ShaderProgram::createDependent(
454 this->getFieldFlags()->_bNamespaceMask);
456 pProg->setShaderType(GL_GEOMETRY_SHADER_EXT);
458 addGeometryShader(pProg);
460 else if(_mfGeometryShader.size() > 1)
462 editMFGeometryShader()->resize(1);
465 _mfGeometryShader[0]->setProgram (_sfGeometryProgram.getValue());
466 _mfGeometryShader[0]->setCgFrontEnd(_sfCgFrontEnd .getValue());
468 bMarkChanged = true;
470 Window::reinitializeGLObject(this->getGLId());
473 if(0x0000 != (whichField & TessControlProgramFieldMask) &&
474 0 != _sfTessControlProgram.getValue().size() )
476 if(_mfTessControlShader.size() == 0)
478 ShaderProgramUnrecPtr pProg = ShaderProgram::createDependent(
479 this->getFieldFlags()->_bNamespaceMask);
481 pProg->setShaderType(GL_TESS_CONTROL_SHADER);
483 addTessControlShader(pProg);
485 else if(_mfTessControlShader.size() > 1)
487 editMFTessControlShader()->resize(1);
490 _mfTessControlShader[0]->setProgram (
491 _sfTessControlProgram.getValue());
492 _mfTessControlShader[0]->setCgFrontEnd(
493 _sfCgFrontEnd .getValue());
495 bMarkChanged = true;
497 Window::reinitializeGLObject(this->getGLId());
500 if(0x0000 != (whichField & TessEvaluationProgramFieldMask) &&
501 0 != _sfTessEvaluationProgram.getValue().size() )
503 if(_mfTessEvaluationShader.size() == 0)
505 ShaderProgramUnrecPtr pProg = ShaderProgram::createDependent(
506 this->getFieldFlags()->_bNamespaceMask);
508 pProg->setShaderType(GL_TESS_EVALUATION_SHADER);
510 addTessEvaluationShader(pProg);
512 else if(_mfTessEvaluationShader.size() > 1)
514 editMFTessEvaluationShader()->resize(1);
517 _mfTessEvaluationShader[0]->setProgram (
518 _sfTessEvaluationProgram.getValue());
519 _mfTessEvaluationShader[0]->setCgFrontEnd(
520 _sfCgFrontEnd .getValue());
522 bMarkChanged = true;
524 Window::reinitializeGLObject(this->getGLId());
527 if(0x0000 != (whichField & VertexProgramFieldMask) &&
528 0 != _sfVertexProgram.getValue().size() )
530 if(_mfVertexShader.size() == 0)
532 ShaderProgramUnrecPtr pProg = ShaderProgram::createDependent(
533 this->getFieldFlags()->_bNamespaceMask);
535 pProg->setShaderType(GL_VERTEX_SHADER);
537 addVertexShader(pProg);
539 pProg->setVariables(this->getVariables());
541 else if(_mfVertexShader.size() > 1)
543 editMFVertexShader()->resize(1);
546 _mfVertexShader[0]->setProgram (_sfVertexProgram.getValue());
547 _mfVertexShader[0]->setCgFrontEnd(_sfCgFrontEnd .getValue());
549 bMarkChanged = true;
551 Window::reinitializeGLObject(this->getGLId());
555 if(0x0000 != (whichField & VariablesFieldMask))
557 ShaderProgramVariables *pVars = _sfVariables.getValue();
559 if(pVars != NULL)
561 if(details == 0x0001)
563 // be save reset all locations
565 if(pVars->getMFVariables()->size() == 0)
567 editMFVariableLocations()->clear();
569 else
571 editMFVariableLocations()->resize(
572 pVars->getMFVariables()->size(),
573 -1);
575 std::fill(editMFVariableLocations()->begin(),
576 editMFVariableLocations()->end (),
577 -1);
580 // be save reset all locations
582 if(pVars->getMFProceduralVariables()->size() == 0 )
584 editMFProceduralVariableLocations()->clear();
586 else
588 editMFProceduralVariableLocations()->resize(
589 pVars->getMFProceduralVariables()->size(),
590 -1);
592 std::fill(editMFProceduralVariableLocations()->begin(),
593 editMFProceduralVariableLocations()->end (),
594 -1);
599 Window::refreshGLObject(this->getGLId());
602 if(0x0000 != (whichField & (VertexShaderFieldMask |
603 GeometryShaderFieldMask |
604 FragmentShaderFieldMask )))
606 bMarkChanged = true;
608 Window::reinitializeGLObject(this->getGLId());
611 if(0x0000 != (whichField & (GeometryVerticesOutFieldMask |
612 GeometryInputTypeFieldMask |
613 GeometryOutputTypeFieldMask )))
615 bMarkChanged = true;
617 // changing parameters requires re-linking the shader
618 Window::reinitializeGLObject(this->getGLId());
621 if(bMarkChanged == true)
623 // be save reset all locations
625 std::fill(editMFVariableLocations()->begin(),
626 editMFVariableLocations()->end (),
627 -1);
629 std::fill(editMFProceduralVariableLocations()->begin(),
630 editMFProceduralVariableLocations()->end (),
631 -1);
633 if(_sfVariables.getValue() != NULL)
635 _sfVariables.getValue()->markAllChanged();
639 Inherited::changed(whichField, origin, details);
642 void SimpleSHLChunk::activate(DrawEnv *pEnv,
643 UInt32 uiIdx)
645 #if 0
646 FragmentShaderIt fIt = _mfFragmentShader.begin();
647 FragmentShaderIt fEnd = _mfFragmentShader.end ();
649 for(; fIt != fEnd; ++fIt)
651 (*fIt)->validate(pEnv);
654 GeometryShaderIt gIt = _mfGeometryShader.begin();
655 GeometryShaderIt gEnd = _mfGeometryShader.end ();
657 for(; gIt != gEnd; ++gIt)
659 (*gIt)->validate(pEnv);
662 VertexShaderIt vIt = _mfVertexShader.begin();
663 VertexShaderIt vEnd = _mfVertexShader.end ();
665 for(; vIt != vEnd; ++vIt)
667 (*vIt)->validate(pEnv);
669 #endif
671 Window *pWin = pEnv->getWindow();
673 UInt32 uiValRes = pWin->validateGLObject(getGLId(),
674 pEnv,
675 KeepProgActive);
677 GLuint uiProgId = GLuint(pWin->getGLObjectId(getGLId()));
679 if(uiProgId == 0)
680 return;
682 pEnv->setActiveShader(uiProgId);
684 if(0x0000 == (uiValRes & ProgActive))
686 OSGGETGLFUNCBYID_GL3_ES(glUseProgram,
687 osgGlUseProgram,
688 ShaderProgram::getFuncIdUseProgram(),
689 pWin);
691 osgGlUseProgram(uiProgId);
694 pEnv->incNumShaderChanges();
696 updateProceduralVariables(pEnv, ShaderProcVariable::SHDAll);
698 if(_sfPointSize.getValue() == true)
700 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
705 void SimpleSHLChunk::changeFrom(DrawEnv *pEnv,
706 StateChunk *pOther,
707 UInt32 uiIdx)
709 SimpleSHLChunk *pOld = dynamic_cast<SimpleSHLChunk *>(pOther);
711 // pOther can be a ShaderExecutableChunk, since we share the StateClass id
712 // with it
713 if(pOld != NULL)
715 Window *pWin = pEnv->getWindow();
716 GLuint uiProgId = GLuint(pWin->getGLObjectId(getGLId()));
718 UInt32 uiDep = ShaderProcVariable::SHDObject;
720 if(uiProgId != pEnv->getActiveShader())
722 #if 0
723 FragmentShaderIt fIt = _mfFragmentShader.begin();
724 FragmentShaderIt fEnd = _mfFragmentShader.end ();
726 for(; fIt != fEnd; ++fIt)
728 (*fIt)->validate(pEnv);
731 GeometryShaderIt gIt = _mfGeometryShader.begin();
732 GeometryShaderIt gEnd = _mfGeometryShader.end ();
734 for(; gIt != gEnd; ++gIt)
736 (*gIt)->validate(pEnv);
739 VertexShaderIt vIt = _mfVertexShader.begin();
740 VertexShaderIt vEnd = _mfVertexShader.end ();
742 for(; vIt != vEnd; ++vIt)
744 (*vIt)->validate(pEnv);
746 #endif
748 UInt32 uiValRes = pWin->validateGLObject(getGLId(),
749 pEnv,
750 KeepProgActive);
752 uiProgId = GLuint(pWin->getGLObjectId(getGLId()));
754 if(uiProgId == 0)
755 return;
757 pEnv->setActiveShader(uiProgId);
759 if(0x0000 == (uiValRes & ProgActive))
761 OSGGETGLFUNCBYID_GL3_ES(glUseProgram,
762 osgGlUseProgram,
763 ShaderProgram::getFuncIdUseProgram(),
764 pWin);
766 osgGlUseProgram(uiProgId);
769 if(_sfPointSize.getValue() == true)
771 if(pOld->getPointSize() == false)
773 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
776 else
778 if(pOld->getPointSize() == true)
780 glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
784 uiDep = ShaderProcVariable::SHDAll;
786 pEnv->incNumShaderChanges();
789 updateProceduralVariables(pEnv, uiDep);
791 else
793 pOther->deactivate(pEnv, uiIdx);
794 activate (pEnv, uiIdx);
796 pEnv->incNumShaderChanges();
800 void SimpleSHLChunk::deactivate(DrawEnv *pEnv,
801 UInt32 uiIdx)
803 if(pEnv->getWindow()->getGLObjectId(getGLId()) == 0)
804 return;
806 pEnv->setActiveShader(0);
808 OSGGETGLFUNC_GL3_ES(glUseProgram,
809 osgGlUseProgram,
810 ShaderProgram::getFuncIdUseProgram());
812 if(_sfPointSize.getValue() == true)
814 glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
817 osgGlUseProgram(0);
820 void SimpleSHLChunk::updateObjectDependencies(DrawEnv *pEnv,
821 UInt32 index)
823 updateProceduralVariables(pEnv, ShaderProcVariable::SHDObject);
826 void SimpleSHLChunk::dump( UInt32 ,
827 const BitVector ) const
829 SLOG << "Dump SimpleSHLChunk NI" << std::endl;
832 bool SimpleSHLChunk::readFragmentProgram(const Char8 *file)
834 return readProgram(editSFFragmentProgram()->getValue(), file);
837 bool SimpleSHLChunk::readGeometryProgram(const Char8 *file)
839 return readProgram(editSFGeometryProgram()->getValue(), file);
842 bool SimpleSHLChunk::readTessControlProgram(const Char8* file)
844 return readProgram(editSFTessControlProgram()->getValue(), file);
847 bool SimpleSHLChunk::readTessEvaluationProgram(const Char8* file)
849 return readProgram(editSFTessEvaluationProgram()->getValue(), file);
852 bool SimpleSHLChunk::readVertexProgram(const Char8 *file)
854 return readProgram(editSFVertexProgram()->getValue(), file);
857 bool SimpleSHLChunk::readProgram( std::string &szTarget,
858 const Char8 *szFilename)
860 std::ifstream s(szFilename);
862 if(s.good())
864 return readProgram(szTarget, s);
866 else
868 FWARNING(("ShaderChunk::readProgram: couldn't open '%s' "
869 "for reading!\n", szFilename));
871 return false;
876 bool SimpleSHLChunk::readProgram(std::string &szTarget,
877 std::istream &iStream)
879 #define BUFSIZE 200
881 szTarget.erase();
883 Char8 buf[BUFSIZE];
885 if(!iStream.good())
887 FWARNING(("SHLChunk::readProgram: stream is not good!\n"));
889 return false;
894 iStream.read(buf, BUFSIZE);
896 szTarget.append(buf, iStream.gcount());
898 while(!iStream.eof());
900 return true;
903 #ifdef OSG_1_COMPAT
904 void SimpleSHLChunk::addProgramParameter(GLenum name, UInt32 value)
906 switch(name)
908 case GL_GEOMETRY_VERTICES_OUT_EXT:
909 this->setGeometryVerticesOut(value);
910 break;
912 case GL_GEOMETRY_INPUT_TYPE_EXT:
913 this->setGeometryInputType(value);
914 break;
916 case GL_GEOMETRY_OUTPUT_TYPE_EXT:
917 this->setGeometryOutputType(value);
918 break;
920 default:
921 FWARNING(("Invalid program paramter '%d'.\n", name));
922 break;
926 void SimpleSHLChunk::subProgramParameter(GLenum name)
928 switch(name)
930 case GL_GEOMETRY_VERTICES_OUT_EXT:
931 this->setGeometryVerticesOut(0);
932 break;
934 case GL_GEOMETRY_INPUT_TYPE_EXT:
935 this->setGeometryInputType(GL_TRIANGLES);
936 break;
938 case GL_GEOMETRY_OUTPUT_TYPE_EXT:
939 this->setGeometryOutputType(GL_TRIANGLE_STRIP);
940 break;
942 default:
943 FWARNING(("Invalid program paramter '%d'.\n", name));
944 break;
947 #endif
949 void SimpleSHLChunk::setProgramParameter(GLenum name, UInt32 value)
951 switch(name)
953 case GL_GEOMETRY_VERTICES_OUT_EXT:
954 this->setGeometryVerticesOut(value);
955 break;
957 case GL_GEOMETRY_INPUT_TYPE_EXT:
958 this->setGeometryInputType(value);
959 break;
961 case GL_GEOMETRY_OUTPUT_TYPE_EXT:
962 this->setGeometryOutputType(value);
963 break;
965 default:
966 FWARNING(("Invalid program paramter '%d'.\n", name));
967 break;
971 UInt32 SimpleSHLChunk::getProgramParameter(GLenum name)
973 switch(name)
975 case GL_GEOMETRY_VERTICES_OUT_EXT:
976 return this->getGeometryVerticesOut();
977 break;
979 case GL_GEOMETRY_INPUT_TYPE_EXT:
980 return this->getGeometryInputType();
981 break;
983 case GL_GEOMETRY_OUTPUT_TYPE_EXT:
984 return this->getGeometryOutputType();
985 break;
987 default:
988 FWARNING(("Invalid program paramter '%d'.\n", name));
989 return 0;
990 break;
994 void SimpleSHLChunk::clearProgramParameters(void)
996 setGeometryVerticesOut(0 );
997 setGeometryInputType (GL_TRIANGLES );
998 setGeometryOutputType (GL_TRIANGLE_STRIP);
1001 #ifdef OSG_1_COMPAT
1002 bool SimpleSHLChunk::subUniformParameter(const Char8 *name)
1004 if(_sfVariables.getValue() != NULL)
1006 return _sfVariables.getValue()->subUniformVariable(
1007 name,
1008 editMFVariableLocations(),
1009 editMFProceduralVariableLocations());
1013 return false;
1016 void SimpleSHLChunk::clearUniformParameters(void)
1018 if(_sfVariables.getValue() != NULL)
1020 _sfVariables.getValue()->clearUniformVariables();
1023 editMFVariableLocations ()->clear();
1024 editMFProceduralVariableLocations()->clear();
1026 #endif
1028 bool SimpleSHLChunk::hasUniformVariable(const Char8 *name)
1030 if(_sfVariables.getValue() != NULL)
1032 return _sfVariables.getValue()->hasUniformVariable(name);
1035 return false;
1038 bool SimpleSHLChunk::subUniformVariable(const Char8 *name)
1040 if(_sfVariables.getValue() != NULL)
1042 return _sfVariables.getValue()->subUniformVariable(
1043 name,
1044 editMFVariableLocations(),
1045 editMFProceduralVariableLocations());
1049 return false;
1052 bool SimpleSHLChunk::addUniformBlock(const Char8 *name, UInt32 value)
1054 if(_sfVariables.getValue() == NULL)
1056 ShaderProgramVariablesUnrecPtr pParam =
1057 ShaderProgramVariables::createDependent(
1058 this->getFieldFlags()->_bNamespaceMask);
1060 setVariables(pParam);
1063 return _sfVariables.getValue()->addUniformBlock(
1064 name,
1065 value,
1066 editMFVariableLocations (),
1067 editMFProceduralVariableLocations());
1070 bool SimpleSHLChunk::updateUniformBlock(const Char8 *name, UInt32 value)
1072 if(_sfVariables.getValue() == NULL)
1074 ShaderProgramVariablesUnrecPtr pParam =
1075 ShaderProgramVariables::createDependent(
1076 this->getFieldFlags()->_bNamespaceMask);
1078 setVariables(pParam);
1081 return _sfVariables.getValue()->updateUniformBlock(name, value);
1084 bool SimpleSHLChunk::getUniformBlock(const Char8 *name, UInt32& value)
1086 if(_sfVariables.getValue() != NULL)
1088 return _sfVariables.getValue()->getUniformBlock(name, value);
1091 return false;
1094 bool SimpleSHLChunk::subUniformBlock(const Char8 *name)
1096 if(_sfVariables.getValue() != NULL)
1098 return _sfVariables.getValue()->subUniformBlock(
1099 name,
1100 editMFVariableLocations(),
1101 editMFProceduralVariableLocations());
1105 return false;
1108 bool SimpleSHLChunk::addShaderStorageBlock(const Char8 *name, UInt32 value)
1110 if(_sfVariables.getValue() == NULL)
1112 ShaderProgramVariablesUnrecPtr pParam =
1113 ShaderProgramVariables::createDependent(
1114 this->getFieldFlags()->_bNamespaceMask);
1116 setVariables(pParam);
1119 return _sfVariables.getValue()->addShaderStorageBlock(
1120 name,
1121 value,
1122 editMFVariableLocations (),
1123 editMFProceduralVariableLocations());
1126 bool SimpleSHLChunk::updateShaderStorageBlock(const Char8 *name, UInt32 value)
1128 if(_sfVariables.getValue() == NULL)
1130 ShaderProgramVariablesUnrecPtr pParam =
1131 ShaderProgramVariables::createDependent(
1132 this->getFieldFlags()->_bNamespaceMask);
1134 setVariables(pParam);
1137 return _sfVariables.getValue()->updateShaderStorageBlock(name, value);
1140 bool SimpleSHLChunk::getShaderStorageBlock(const Char8 *name, UInt32& value)
1142 if(_sfVariables.getValue() != NULL)
1144 return _sfVariables.getValue()->getShaderStorageBlock(name, value);
1147 return false;
1150 bool SimpleSHLChunk::subShaderStorageBlock(const Char8 *name)
1152 if(_sfVariables.getValue() != NULL)
1154 return _sfVariables.getValue()->subShaderStorageBlock(
1155 name,
1156 editMFVariableLocations(),
1157 editMFProceduralVariableLocations());
1161 return false;
1164 void SimpleSHLChunk::clearUniformVariables(void)
1166 if(_sfVariables.getValue() != NULL)
1168 _sfVariables.getValue()->clearUniformVariables();
1171 editMFVariableLocations ()->clear();
1172 editMFProceduralVariableLocations()->clear();
1175 bool SimpleSHLChunk::addOSGVariable(const Char8 *name)
1177 if(_sfVariables.getValue() == NULL)
1179 ShaderProgramVariablesUnrecPtr pVar =
1180 ShaderProgramVariables::createDependent(
1181 this->getFieldFlags()->_bNamespaceMask);
1183 setVariables(pVar);
1185 if(_mfVertexShader.size() > 0)
1187 _mfVertexShader[0]->setVariables(this->getVariables());
1191 return _sfVariables.getValue()->addOSGVariable(
1192 name,
1193 editMFProceduralVariableLocations());
1196 bool SimpleSHLChunk::addProceduralVariable(const Char8 *name,
1197 ProcVarFunctor pFunc,
1198 UInt32 uiDependency)
1200 if(_sfVariables.getValue() == NULL)
1202 ShaderProgramVariablesUnrecPtr pParam =
1203 ShaderProgramVariables::createDependent(
1204 this->getFieldFlags()->_bNamespaceMask);
1206 setVariables(pParam);
1208 if(_mfVertexShader.size() > 0)
1210 _mfVertexShader[0]->setVariables(this->getVariables());
1214 return _sfVariables.getValue()->addProceduralVariable(
1215 name,
1216 pFunc,
1217 uiDependency,
1218 editMFProceduralVariableLocations());
1221 bool SimpleSHLChunk::updateNodeProceduralVariable(
1222 const Char8 *name,
1223 ProcVarNodeFunctor pFunc,
1224 UInt32 uiDependency)
1226 if(_sfVariables.getValue() == NULL)
1228 ShaderProgramVariablesUnrecPtr pParam =
1229 ShaderProgramVariables::createDependent(
1230 this->getFieldFlags()->_bNamespaceMask);
1232 setVariables(pParam);
1234 if(_mfVertexShader.size() > 0)
1236 _mfVertexShader[0]->setVariables(this->getVariables());
1240 return _sfVariables.getValue()->updateNodeProceduralVariable(name,
1241 pFunc,
1242 uiDependency);
1245 bool SimpleSHLChunk::addNodeProceduralVariable(
1246 const Char8 *name,
1247 ProcVarNodeFunctor pFunc,
1248 UInt32 uiDependency)
1250 if(_sfVariables.getValue() == NULL)
1252 ShaderProgramVariablesUnrecPtr pParam =
1253 ShaderProgramVariables::createDependent(
1254 this->getFieldFlags()->_bNamespaceMask);
1256 setVariables(pParam);
1258 if(_mfVertexShader.size() > 0)
1260 _mfVertexShader[0]->setVariables(this->getVariables());
1264 return _sfVariables.getValue()->addNodeProceduralVariable(
1265 name,
1266 pFunc,
1267 uiDependency,
1268 editMFProceduralVariableLocations());
1271 bool SimpleSHLChunk::updateProceduralVariable(const Char8 *name,
1272 ProcVarFunctor pFunc,
1273 UInt32 uiDependency)
1275 if(_sfVariables.getValue() == NULL)
1277 ShaderProgramVariablesUnrecPtr pParam =
1278 ShaderProgramVariables::createDependent(
1279 this->getFieldFlags()->_bNamespaceMask);
1281 setVariables(pParam);
1283 if(_mfVertexShader.size() > 0)
1285 _mfVertexShader[0]->setVariables(this->getVariables());
1289 return _sfVariables.getValue()->updateProceduralVariable(name,
1290 pFunc,
1291 uiDependency);
1294 #ifdef OSG_1_COMPAT
1295 void SimpleSHLChunk::addParameterCallback(const Char8 *name, ParamFunctor fp)
1297 if(_sfVariables.getValue() == NULL)
1299 ShaderProgramVariablesUnrecPtr pParam =
1300 ShaderProgramVariables::createDependent(
1301 this->getFieldFlags()->_bNamespaceMask);
1303 setVariables(pParam);
1305 if(_mfVertexShader.size() > 0)
1307 _mfVertexShader[0]->setVariables(this->getVariables());
1311 _sfVariables.getValue()->addProceduralVariable(
1312 name,
1314 editMFProceduralVariableLocations());
1317 void SimpleSHLChunk::addParameterCallback(const Char8 *name, OSGParamFunctor fp)
1319 if(_sfVariables.getValue() == NULL)
1321 ShaderProgramVariablesUnrecPtr pParam =
1322 ShaderProgramVariables::createDependent(
1323 this->getFieldFlags()->_bNamespaceMask);
1325 setVariables(pParam);
1327 if(_mfVertexShader.size() > 0)
1329 _mfVertexShader[0]->setVariables(this->getVariables());
1333 _sfVariables.getValue()->addProceduralVariable(
1334 name,
1336 editMFProceduralVariableLocations());
1339 void SimpleSHLChunk::setParameterCallback(ParamFunctor fp)
1341 _fParameterCallback = fp;
1343 #endif
1345 #if 1
1346 void SimpleSHLChunk::updateParameters(
1347 Window *win,
1348 const UInt32 &parameters,
1349 bool useProgram,
1350 bool force,
1351 bool keepProgramActive)
1355 const UInt32 *SimpleSHLChunk::getMFParameters(void) const
1357 static UInt32 foo;
1359 return &foo;
1361 #endif
1363 void SimpleSHLChunk::updateVariableLocations(DrawEnv *pEnv,
1364 UInt32 uiProgram)
1366 if(uiProgram == 0)
1367 return;
1369 const ShaderProgramVariables::MFVariablesType *pMFVars = NULL;
1370 const ShaderProgramVariables::MFProceduralVariablesType *pMFProcVars = NULL;
1372 if(_sfVariables.getValue() != NULL)
1374 pMFVars = _sfVariables.getValue()->getMFVariables ();
1375 pMFProcVars = _sfVariables.getValue()->getMFProceduralVariables();
1378 if(pMFVars != NULL && pMFVars->size() != 0)
1380 MFInt32 &vVarLocations = *this->editMFVariableLocations();
1382 OSG_ASSERT(pMFVars->size() == vVarLocations.size());
1384 MFInt32::iterator mLocIt = vVarLocations.begin();
1386 ShaderProgramVariables::MFVariablesType::const_iterator mVarIt =
1387 pMFVars->begin();
1388 ShaderProgramVariables::MFVariablesType::const_iterator mVarEnd =
1389 pMFVars->end ();
1391 OSGGETGLFUNC_GL3_ES(glGetUniformLocation,
1392 osgGlGetUniformLocation,
1393 ShaderProgram::getFuncIdGetUniformLocation());
1395 for(; mVarIt != mVarEnd; ++mVarIt, ++mLocIt)
1397 // variable at this position was removed
1398 if((*mVarIt) == NULL)
1399 continue;
1401 *mLocIt = osgGlGetUniformLocation(uiProgram,
1402 (*mVarIt)->getName().c_str());
1406 if(pMFProcVars != NULL && pMFProcVars->size() != 0)
1408 MFInt32 &vVarLocations = *this->editMFProceduralVariableLocations();
1410 OSG_ASSERT(pMFProcVars->size() == vVarLocations.size());
1412 MFInt32::iterator mLocIt = vVarLocations.begin();
1414 ShaderProgramVariables::MFProceduralVariablesType::const_iterator
1415 mVarIt = pMFProcVars->begin();
1416 ShaderProgramVariables::MFProceduralVariablesType::const_iterator
1417 mVarEnd = pMFProcVars->end ();
1419 OSGGETGLFUNC_GL3_ES(glGetUniformLocation,
1420 osgGlGetUniformLocation,
1421 ShaderProgram::getFuncIdGetUniformLocation());
1423 for(; mVarIt != mVarEnd; ++mVarIt, ++mLocIt)
1425 *mLocIt = osgGlGetUniformLocation(uiProgram,
1426 (*mVarIt)->getName().c_str());
1431 void SimpleSHLChunk::updateVariables(DrawEnv *pEnv,
1432 UInt32 uiProgram)
1434 if(uiProgram == 0)
1435 return;
1437 const ShaderProgramVariables::MFVariablesType *pMFVars = NULL;
1438 ShaderProgramVariables::MFVariableChangedType *pMFVarChg = NULL;
1440 if(_sfVariables.getValue() != NULL)
1442 pMFVars = _sfVariables.getValue()->getMFVariables ();
1443 pMFVarChg = _sfVariables.getValue()->editMFVariableChanged();
1446 if(pMFVars == NULL || pMFVars->size() == 0 || pMFVarChg == NULL)
1448 return;
1451 OSG_ASSERT(pMFVars->size() == pMFVarChg->size());
1453 MFInt32 &vVarLocations = *this->editMFVariableLocations();
1455 OSG_ASSERT(pMFVars->size() == vVarLocations.size());
1457 MFInt32::iterator mLocIt = vVarLocations.begin();
1459 ShaderProgramVariables::MFVariablesType::const_iterator mVarIt =
1460 pMFVars->begin();
1461 ShaderProgramVariables::MFVariablesType::const_iterator mVarEnd =
1462 pMFVars->end ();
1464 ShaderProgramVariables::MFVariableChangedType::iterator mVarChgIt =
1465 pMFVarChg->begin();
1467 bool warnUnknown = ShaderVariable::WarnUnknown;
1469 for(; mVarIt != mVarEnd; ++mVarIt, ++mLocIt, ++mVarChgIt)
1471 ShaderVariable *pVar = *mVarIt;
1473 if(pVar == NULL)
1474 continue;
1476 if(*mVarChgIt == false)
1477 continue;
1479 *mVarChgIt = false;
1481 osgUniformShaderVariableSwitch(pEnv, pVar,
1482 *mLocIt, uiProgram, warnUnknown);
1486 void SimpleSHLChunk::updateParameters(DrawEnv *pEnv,
1487 UInt32 uiProgram)
1489 if(uiProgram == 0 || this->getGeometryVerticesOut() == 0)
1490 return;
1492 OSGGETGLFUNC_EXT(glProgramParameteriEXT,
1493 osgGlProgramParameteriEXT,
1494 ShaderProgram::getFuncIdProgramParameteri());
1496 osgGlProgramParameteriEXT(uiProgram,
1497 GL_GEOMETRY_VERTICES_OUT_EXT,
1498 this->getGeometryVerticesOut());
1499 osgGlProgramParameteriEXT(uiProgram,
1500 GL_GEOMETRY_INPUT_TYPE_EXT,
1501 this->getGeometryInputType());
1502 osgGlProgramParameteriEXT(uiProgram,
1503 GL_GEOMETRY_OUTPUT_TYPE_EXT,
1504 this->getGeometryOutputType());
1507 void SimpleSHLChunk::updateProceduralVariables(
1508 DrawEnv *pEnv,
1509 UInt32 uiUpdateDependents)
1511 UInt32 uiProgram = pEnv->getActiveShader();
1513 if(uiProgram == 0)
1514 return;
1516 const ShaderProgramVariables::MFProceduralVariablesType *pMFVars = NULL;
1518 if(_sfVariables.getValue() != NULL)
1520 pMFVars = _sfVariables.getValue()->getMFProceduralVariables();
1523 if(pMFVars == NULL || pMFVars->size() == 0)
1525 return;
1528 MFInt32 &vVarLocations = *this->editMFProceduralVariableLocations();
1530 OSG_ASSERT(pMFVars->size() == vVarLocations.size());
1532 MFInt32::iterator mLocIt = vVarLocations.begin();
1534 ShaderProgramVariables::MFProceduralVariablesType::const_iterator mVarIt =
1535 pMFVars->begin();
1536 ShaderProgramVariables::MFProceduralVariablesType::const_iterator mVarEnd =
1537 pMFVars->end ();
1539 Window *pWin = pEnv->getWindow();
1541 osgSinkUnusedWarning(pWin);
1543 #ifdef OSG_1_COMPAT
1544 if(_fParameterCallback)
1546 OSGGETGLFUNCBYID_GL3_ES(glGetUniformLocation,
1547 osgGlGetUniformLocation,
1548 ShaderProgram::getFuncIdGetUniformLocation(),
1549 pWin);
1551 _fParameterCallback(osgGlGetUniformLocation, pEnv, uiProgram);
1553 #endif
1555 for(; mVarIt != mVarEnd; ++mVarIt, ++mLocIt)
1557 ShaderVariable *pVar = *mVarIt;
1559 switch(pVar->getTypeId())
1561 case ShaderVariable::SHVTypeOSG:
1563 ShaderVariableOSG *p =
1564 dynamic_cast<ShaderVariableOSG *>(pVar);
1566 if(0x0000 == (p->getDependency() & uiUpdateDependents))
1567 continue;
1569 if(*mLocIt == -1)
1571 OSGGETGLFUNCBYID_GL3_ES(
1572 glGetUniformLocation,
1573 osgGlGetUniformLocation,
1574 ShaderProgram::getFuncIdGetUniformLocation(),
1575 pWin);
1577 *mLocIt = osgGlGetUniformLocation(uiProgram,
1578 p->getName().c_str());
1581 p->evaluate(pEnv, *mLocIt);
1583 break;
1585 case ShaderVariable::SHVTypeFunctor:
1587 ShaderVariableFunctor *p =
1588 dynamic_cast<ShaderVariableFunctor *>(pVar);
1590 if(0x0000 == (p->getDependency() & uiUpdateDependents))
1591 continue;
1593 if(*mLocIt == -1)
1595 OSGGETGLFUNCBYID_GL3_ES(
1596 glGetUniformLocation,
1597 osgGlGetUniformLocation,
1598 ShaderProgram::getFuncIdGetUniformLocation(),
1599 pWin);
1601 *mLocIt = osgGlGetUniformLocation(uiProgram,
1602 p->getName().c_str());
1605 #ifdef OSG_1_COMPAT
1606 switch(p->getFuncMode())
1608 case 0:
1610 p->evaluate(pEnv, *mLocIt);
1612 break;
1614 case 1:
1616 OSGGETGLFUNCBYID_GL3_ES(
1617 glGetUniformLocation,
1618 osgGlGetUniformLocation,
1619 ShaderProgram::getFuncIdGetUniformLocation(),
1620 pWin);
1622 p->evaluate(osgGlGetUniformLocation,
1623 pEnv,
1624 uiProgram);
1626 break;
1628 case 2:
1630 p->evaluate(p,
1631 pEnv,
1632 uiProgram);
1634 break;
1636 #else
1637 p->evaluate(pEnv, *mLocIt);
1638 #endif
1640 break;
1642 default:
1643 break;
1649 OSG_END_NAMESPACE