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 "OSGConfig.h"
48 #include "OSGSimpleSHLChunk.h"
49 #include "OSGDrawEnv.h"
51 #include "OSGShaderVariables.h"
52 #include "OSGConceptPropertyChecks.h"
54 #include <boost/bind.hpp>
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 /***************************************************************************\
65 \***************************************************************************/
68 volatile UInt16
SimpleSHLChunk::_uiChunkCounter
= 1;
72 SimpleSHLChunk::ParamFunctor
SimpleSHLChunk::_fParameterCallback
;
75 /***************************************************************************\
77 \***************************************************************************/
79 void SimpleSHLChunk::initMethod(InitPhase ePhase
)
81 Inherited::initMethod(ePhase
);
84 UInt32
SimpleSHLChunk::handleGL(DrawEnv
*pEnv
,
86 Window::GLObjectStatusE mode
,
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);
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
)
112 OSGGETGLFUNCBYID_GL3_ES(glDeleteProgram
,
114 ShaderProgram::getFuncIdDeleteProgram(),
117 osgGlDeleteProgram(uiProgram
);
120 OSGGETGLFUNCBYID_GL3_ES(glCreateProgram
,
122 ShaderProgram::getFuncIdCreateProgram(),
125 OSGGETGLFUNCBYID_GL3_ES(glAttachShader
,
127 ShaderProgram::getFuncIdAttachShader(),
130 OSGGETGLFUNCBYID_GL3_ES(glLinkProgram
,
132 ShaderProgram::getFuncIdLinkProgram(),
135 uiProgram
= osgGlCreateProgram();
137 FragmentShaderIt fIt
= _mfFragmentShader
.begin();
138 FragmentShaderIt fEnd
= _mfFragmentShader
.end ();
140 for(; fIt
!= fEnd
; ++fIt
)
142 (*fIt
)->validate(pEnv
);
145 GLuint(pWin
->getGLObjectId((*fIt
)->getGLId()));
148 osgGlAttachShader(uiProgram
, uiShader
);
151 GeometryShaderIt gIt
= _mfGeometryShader
.begin();
152 GeometryShaderIt gEnd
= _mfGeometryShader
.end ();
154 for(; gIt
!= gEnd
; ++gIt
)
156 (*gIt
)->validate(pEnv
);
159 GLuint(pWin
->getGLObjectId((*gIt
)->getGLId()));
162 osgGlAttachShader(uiProgram
, uiShader
);
165 TessEvalShaderIt teIt
= _mfTessEvaluationShader
.begin();
166 TessEvalShaderIt teEnd
= _mfTessEvaluationShader
.end ();
168 for(; teIt
!= teEnd
; ++teIt
)
170 (*teIt
)->validate(pEnv
);
173 GLuint(pWin
->getGLObjectId((*teIt
)->getGLId()));
176 osgGlAttachShader(uiProgram
, uiShader
);
179 TessControlShaderIt tcIt
= _mfTessControlShader
.begin();
180 TessControlShaderIt tcEnd
= _mfTessControlShader
.end ();
182 for(; tcIt
!= tcEnd
; ++tcIt
)
184 (*tcIt
)->validate(pEnv
);
187 GLuint(pWin
->getGLObjectId((*tcIt
)->getGLId()));
190 osgGlAttachShader(uiProgram
, uiShader
);
193 VertexShaderIt vIt
= _mfVertexShader
.begin();
194 VertexShaderIt vEnd
= _mfVertexShader
.end ();
196 for(; vIt
!= vEnd
; ++vIt
)
198 (*vIt
)->validate(pEnv
);
201 GLuint(pWin
->getGLObjectId((*vIt
)->getGLId()));
204 osgGlAttachShader(uiProgram
, uiShader
);
207 // parameters must be set before linking
208 updateParameters(pEnv
, uiProgram
);
210 osgGlLinkProgram(uiProgram
);
213 Char8
*szInfoBuffer
= NULL
;
215 OSGGETGLFUNCBYID_GL3_ES(glGetProgramiv
,
217 ShaderProgram::getFuncIdGetProgramiv(),
220 osgGlGetProgramiv(uiProgram
,
221 GL_OBJECT_INFO_LOG_LENGTH_ARB
,
226 szInfoBuffer
= new Char8
[iInfoLength
];
227 szInfoBuffer
[0] = '\0';
229 OSGGETGLFUNCBYID_GL3_ES(
231 osgGlGetProgramInfoLog
,
232 ShaderProgram::getFuncIdGetProgramInfoLog(),
235 osgGlGetProgramInfoLog( uiProgram
,
243 osgGlGetProgramiv(uiProgram
, GL_LINK_STATUS
, &iStatus
);
247 if(szInfoBuffer
!= NULL
&& szInfoBuffer
[0] != '\0')
249 FFATAL(("Couldn't link vertex and fragment program!\n%s\n",
254 FFATAL(("Couldn't link vertex and fragment program!\n"
255 "No further info available\n"));
258 OSGGETGLFUNCBYID_GL3_ES(glDeleteProgram
,
260 ShaderProgram::getFuncIdDeleteProgram(),
263 osgGlDeleteProgram(uiProgram
);
269 if(szInfoBuffer
!= NULL
&& szInfoBuffer
[0] != '\0')
271 FWARNING(("SimpleSHLChunk: link status: %s\n",
276 pWin
->setGLObjectId(getGLId(), uiProgram
);
278 updateVariableLocations(pEnv
, uiProgram
);
283 OSGGETGLFUNCBYID_GL3_ES(glUseProgram
,
285 ShaderProgram::getFuncIdUseProgram(),
288 osgGlUseProgram(uiProgram
);
290 updateVariables(pEnv
, uiProgram
);
292 if(0x0000 == (uiOptions
& KeepProgActive
))
298 returnValue
|= ProgActive
;
306 void SimpleSHLChunk::handleDestroyGL(DrawEnv
*pEnv
,
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);
322 // BUG this is not called for every window!
323 if(mode
== Window::destroy
)
325 GLuint uiProgram
= GLuint(pWin
->getGLObjectId(id
));
329 OSGGETGLFUNCBYID_GL3_ES(glDeleteProgram
,
331 ShaderProgram::getFuncIdDeleteProgram(),
334 osgGlDeleteProgram(uiProgram
);
336 pWin
->setGLObjectId(id
, 0);
339 else if(mode
== Window::finaldestroy
)
341 ;//SWARNING << "Last program user destroyed" << std::endl;
345 /***************************************************************************\
347 \***************************************************************************/
349 /*-------------------------------------------------------------------------*\
351 \*-------------------------------------------------------------------------*/
353 /*----------------------- constructors & destructors ----------------------*/
355 SimpleSHLChunk::SimpleSHLChunk(void) :
361 SimpleSHLChunk::SimpleSHLChunk(const SimpleSHLChunk
&source
) :
367 SimpleSHLChunk::~SimpleSHLChunk(void)
371 void SimpleSHLChunk::onCreate(const SimpleSHLChunk
*source
)
373 Inherited::onCreate(source
);
375 // ignore prototypes.
376 if(GlobalSystemState
== Startup
)
380 Window::registerGLObject(
381 boost::bind(&SimpleSHLChunk::handleGL
,
382 SimpleSHLChunkMTUncountedPtr(this),
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
)
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)
415 /*----------------------------- class specific ----------------------------*/
417 void SimpleSHLChunk::changed(ConstFieldMaskArg whichField
,
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());
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());
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());
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());
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());
551 Window::reinitializeGLObject(this->getGLId());
555 if(0x0000 != (whichField
& VariablesFieldMask
))
557 ShaderProgramVariables
*pVars
= _sfVariables
.getValue();
561 if(details
== 0x0001)
563 // be save reset all locations
565 if(pVars
->getMFVariables()->size() == 0)
567 editMFVariableLocations()->clear();
571 editMFVariableLocations()->resize(
572 pVars
->getMFVariables()->size(),
575 std::fill(editMFVariableLocations()->begin(),
576 editMFVariableLocations()->end (),
580 // be save reset all locations
582 if(pVars
->getMFProceduralVariables()->size() == 0 )
584 editMFProceduralVariableLocations()->clear();
588 editMFProceduralVariableLocations()->resize(
589 pVars
->getMFProceduralVariables()->size(),
592 std::fill(editMFProceduralVariableLocations()->begin(),
593 editMFProceduralVariableLocations()->end (),
599 Window::refreshGLObject(this->getGLId());
602 if(0x0000 != (whichField
& (VertexShaderFieldMask
|
603 GeometryShaderFieldMask
|
604 FragmentShaderFieldMask
)))
608 Window::reinitializeGLObject(this->getGLId());
611 if(0x0000 != (whichField
& (GeometryVerticesOutFieldMask
|
612 GeometryInputTypeFieldMask
|
613 GeometryOutputTypeFieldMask
)))
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 (),
629 std::fill(editMFProceduralVariableLocations()->begin(),
630 editMFProceduralVariableLocations()->end (),
633 if(_sfVariables
.getValue() != NULL
)
635 _sfVariables
.getValue()->markAllChanged();
639 Inherited::changed(whichField
, origin
, details
);
642 void SimpleSHLChunk::activate(DrawEnv
*pEnv
,
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
);
671 Window
*pWin
= pEnv
->getWindow();
673 UInt32 uiValRes
= pWin
->validateGLObject(getGLId(),
677 GLuint uiProgId
= GLuint(pWin
->getGLObjectId(getGLId()));
682 pEnv
->setActiveShader(uiProgId
);
684 if(0x0000 == (uiValRes
& ProgActive
))
686 OSGGETGLFUNCBYID_GL3_ES(glUseProgram
,
688 ShaderProgram::getFuncIdUseProgram(),
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
,
709 SimpleSHLChunk
*pOld
= dynamic_cast<SimpleSHLChunk
*>(pOther
);
711 // pOther can be a ShaderExecutableChunk, since we share the StateClass id
715 Window
*pWin
= pEnv
->getWindow();
716 GLuint uiProgId
= GLuint(pWin
->getGLObjectId(getGLId()));
718 UInt32 uiDep
= ShaderProcVariable::SHDObject
;
720 if(uiProgId
!= pEnv
->getActiveShader())
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
);
748 UInt32 uiValRes
= pWin
->validateGLObject(getGLId(),
752 uiProgId
= GLuint(pWin
->getGLObjectId(getGLId()));
757 pEnv
->setActiveShader(uiProgId
);
759 if(0x0000 == (uiValRes
& ProgActive
))
761 OSGGETGLFUNCBYID_GL3_ES(glUseProgram
,
763 ShaderProgram::getFuncIdUseProgram(),
766 osgGlUseProgram(uiProgId
);
769 if(_sfPointSize
.getValue() == true)
771 if(pOld
->getPointSize() == false)
773 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB
);
778 if(pOld
->getPointSize() == true)
780 glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB
);
784 uiDep
= ShaderProcVariable::SHDAll
;
786 pEnv
->incNumShaderChanges();
789 updateProceduralVariables(pEnv
, uiDep
);
793 pOther
->deactivate(pEnv
, uiIdx
);
794 activate (pEnv
, uiIdx
);
796 pEnv
->incNumShaderChanges();
800 void SimpleSHLChunk::deactivate(DrawEnv
*pEnv
,
803 if(pEnv
->getWindow()->getGLObjectId(getGLId()) == 0)
806 pEnv
->setActiveShader(0);
808 OSGGETGLFUNC_GL3_ES(glUseProgram
,
810 ShaderProgram::getFuncIdUseProgram());
812 if(_sfPointSize
.getValue() == true)
814 glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB
);
820 void SimpleSHLChunk::updateObjectDependencies(DrawEnv
*pEnv
,
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
);
864 return readProgram(szTarget
, s
);
868 FWARNING(("ShaderChunk::readProgram: couldn't open '%s' "
869 "for reading!\n", szFilename
));
876 bool SimpleSHLChunk::readProgram(std::string
&szTarget
,
877 std::istream
&iStream
)
887 FWARNING(("SHLChunk::readProgram: stream is not good!\n"));
894 iStream
.read(buf
, BUFSIZE
);
896 szTarget
.append(buf
, iStream
.gcount());
898 while(!iStream
.eof());
904 void SimpleSHLChunk::addProgramParameter(GLenum name
, UInt32 value
)
908 case GL_GEOMETRY_VERTICES_OUT_EXT
:
909 this->setGeometryVerticesOut(value
);
912 case GL_GEOMETRY_INPUT_TYPE_EXT
:
913 this->setGeometryInputType(value
);
916 case GL_GEOMETRY_OUTPUT_TYPE_EXT
:
917 this->setGeometryOutputType(value
);
921 FWARNING(("Invalid program paramter '%d'.\n", name
));
926 void SimpleSHLChunk::subProgramParameter(GLenum name
)
930 case GL_GEOMETRY_VERTICES_OUT_EXT
:
931 this->setGeometryVerticesOut(0);
934 case GL_GEOMETRY_INPUT_TYPE_EXT
:
935 this->setGeometryInputType(GL_TRIANGLES
);
938 case GL_GEOMETRY_OUTPUT_TYPE_EXT
:
939 this->setGeometryOutputType(GL_TRIANGLE_STRIP
);
943 FWARNING(("Invalid program paramter '%d'.\n", name
));
949 void SimpleSHLChunk::setProgramParameter(GLenum name
, UInt32 value
)
953 case GL_GEOMETRY_VERTICES_OUT_EXT
:
954 this->setGeometryVerticesOut(value
);
957 case GL_GEOMETRY_INPUT_TYPE_EXT
:
958 this->setGeometryInputType(value
);
961 case GL_GEOMETRY_OUTPUT_TYPE_EXT
:
962 this->setGeometryOutputType(value
);
966 FWARNING(("Invalid program paramter '%d'.\n", name
));
971 UInt32
SimpleSHLChunk::getProgramParameter(GLenum name
)
975 case GL_GEOMETRY_VERTICES_OUT_EXT
:
976 return this->getGeometryVerticesOut();
979 case GL_GEOMETRY_INPUT_TYPE_EXT
:
980 return this->getGeometryInputType();
983 case GL_GEOMETRY_OUTPUT_TYPE_EXT
:
984 return this->getGeometryOutputType();
988 FWARNING(("Invalid program paramter '%d'.\n", name
));
994 void SimpleSHLChunk::clearProgramParameters(void)
996 setGeometryVerticesOut(0 );
997 setGeometryInputType (GL_TRIANGLES
);
998 setGeometryOutputType (GL_TRIANGLE_STRIP
);
1002 bool SimpleSHLChunk::subUniformParameter(const Char8
*name
)
1004 if(_sfVariables
.getValue() != NULL
)
1006 return _sfVariables
.getValue()->subUniformVariable(
1008 editMFVariableLocations(),
1009 editMFProceduralVariableLocations());
1016 void SimpleSHLChunk::clearUniformParameters(void)
1018 if(_sfVariables
.getValue() != NULL
)
1020 _sfVariables
.getValue()->clearUniformVariables();
1023 editMFVariableLocations ()->clear();
1024 editMFProceduralVariableLocations()->clear();
1028 bool SimpleSHLChunk::hasUniformVariable(const Char8
*name
)
1030 if(_sfVariables
.getValue() != NULL
)
1032 return _sfVariables
.getValue()->hasUniformVariable(name
);
1038 bool SimpleSHLChunk::subUniformVariable(const Char8
*name
)
1040 if(_sfVariables
.getValue() != NULL
)
1042 return _sfVariables
.getValue()->subUniformVariable(
1044 editMFVariableLocations(),
1045 editMFProceduralVariableLocations());
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(
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
);
1094 bool SimpleSHLChunk::subUniformBlock(const Char8
*name
)
1096 if(_sfVariables
.getValue() != NULL
)
1098 return _sfVariables
.getValue()->subUniformBlock(
1100 editMFVariableLocations(),
1101 editMFProceduralVariableLocations());
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(
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
);
1150 bool SimpleSHLChunk::subShaderStorageBlock(const Char8
*name
)
1152 if(_sfVariables
.getValue() != NULL
)
1154 return _sfVariables
.getValue()->subShaderStorageBlock(
1156 editMFVariableLocations(),
1157 editMFProceduralVariableLocations());
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
);
1185 if(_mfVertexShader
.size() > 0)
1187 _mfVertexShader
[0]->setVariables(this->getVariables());
1191 return _sfVariables
.getValue()->addOSGVariable(
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(
1218 editMFProceduralVariableLocations());
1221 bool SimpleSHLChunk::updateNodeProceduralVariable(
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
,
1245 bool SimpleSHLChunk::addNodeProceduralVariable(
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(
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
,
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(
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(
1336 editMFProceduralVariableLocations());
1339 void SimpleSHLChunk::setParameterCallback(ParamFunctor fp
)
1341 _fParameterCallback
= fp
;
1346 void SimpleSHLChunk::updateParameters(
1348 const UInt32
¶meters
,
1351 bool keepProgramActive
)
1355 const UInt32
*SimpleSHLChunk::getMFParameters(void) const
1363 void SimpleSHLChunk::updateVariableLocations(DrawEnv
*pEnv
,
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
=
1388 ShaderProgramVariables::MFVariablesType::const_iterator mVarEnd
=
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
)
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
,
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
)
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
=
1461 ShaderProgramVariables::MFVariablesType::const_iterator mVarEnd
=
1464 ShaderProgramVariables::MFVariableChangedType::iterator mVarChgIt
=
1467 bool warnUnknown
= ShaderVariable::WarnUnknown
;
1469 for(; mVarIt
!= mVarEnd
; ++mVarIt
, ++mLocIt
, ++mVarChgIt
)
1471 ShaderVariable
*pVar
= *mVarIt
;
1476 if(*mVarChgIt
== false)
1481 osgUniformShaderVariableSwitch(pEnv
, pVar
,
1482 *mLocIt
, uiProgram
, warnUnknown
);
1486 void SimpleSHLChunk::updateParameters(DrawEnv
*pEnv
,
1489 if(uiProgram
== 0 || this->getGeometryVerticesOut() == 0)
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(
1509 UInt32 uiUpdateDependents
)
1511 UInt32 uiProgram
= pEnv
->getActiveShader();
1516 const ShaderProgramVariables::MFProceduralVariablesType
*pMFVars
= NULL
;
1518 if(_sfVariables
.getValue() != NULL
)
1520 pMFVars
= _sfVariables
.getValue()->getMFProceduralVariables();
1523 if(pMFVars
== NULL
|| pMFVars
->size() == 0)
1528 MFInt32
&vVarLocations
= *this->editMFProceduralVariableLocations();
1530 OSG_ASSERT(pMFVars
->size() == vVarLocations
.size());
1532 MFInt32::iterator mLocIt
= vVarLocations
.begin();
1534 ShaderProgramVariables::MFProceduralVariablesType::const_iterator mVarIt
=
1536 ShaderProgramVariables::MFProceduralVariablesType::const_iterator mVarEnd
=
1539 Window
*pWin
= pEnv
->getWindow();
1541 osgSinkUnusedWarning(pWin
);
1544 if(_fParameterCallback
)
1546 OSGGETGLFUNCBYID_GL3_ES(glGetUniformLocation
,
1547 osgGlGetUniformLocation
,
1548 ShaderProgram::getFuncIdGetUniformLocation(),
1551 _fParameterCallback(osgGlGetUniformLocation
, pEnv
, uiProgram
);
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
))
1571 OSGGETGLFUNCBYID_GL3_ES(
1572 glGetUniformLocation
,
1573 osgGlGetUniformLocation
,
1574 ShaderProgram::getFuncIdGetUniformLocation(),
1577 *mLocIt
= osgGlGetUniformLocation(uiProgram
,
1578 p
->getName().c_str());
1581 p
->evaluate(pEnv
, *mLocIt
);
1585 case ShaderVariable::SHVTypeFunctor
:
1587 ShaderVariableFunctor
*p
=
1588 dynamic_cast<ShaderVariableFunctor
*>(pVar
);
1590 if(0x0000 == (p
->getDependency() & uiUpdateDependents
))
1595 OSGGETGLFUNCBYID_GL3_ES(
1596 glGetUniformLocation
,
1597 osgGlGetUniformLocation
,
1598 ShaderProgram::getFuncIdGetUniformLocation(),
1601 *mLocIt
= osgGlGetUniformLocation(uiProgram
,
1602 p
->getName().c_str());
1606 switch(p
->getFuncMode())
1610 p
->evaluate(pEnv
, *mLocIt
);
1616 OSGGETGLFUNCBYID_GL3_ES(
1617 glGetUniformLocation
,
1618 osgGlGetUniformLocation
,
1619 ShaderProgram::getFuncIdGetUniformLocation(),
1622 p
->evaluate(osgGlGetUniformLocation
,
1637 p
->evaluate(pEnv
, *mLocIt
);