changed: gcc8 base update
[opensg.git] / Source / System / State / Shader / Base / OSGShaderProgram.cpp
blob9e8c845f553e4797068f751b82722130b004d61b
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 "OSGShaderProgram.h"
49 #include "OSGGLFuncProtos.h"
51 #include <boost/bind.hpp>
53 OSG_BEGIN_NAMESPACE
55 // Documentation for this class is emitted in the
56 // OSGShaderProgramBase.cpp file.
57 // To modify it, please change the .fcd file (OSGShaderProgram.fcd) and
58 // regenerate the base file.
60 /***************************************************************************\
61 * Class variables *
62 \***************************************************************************/
64 UInt32 ShaderProgram::_extSHL = Window::invalidExtensionID;
65 UInt32 ShaderProgram::_extCG = Window::invalidExtensionID;
66 UInt32 ShaderProgram::_extGeoShader4 = Window::invalidExtensionID;
67 UInt32 ShaderProgram::_extGPUShader4 = Window::invalidExtensionID;
68 UInt32 ShaderProgram::_extTransformFeedback2 = Window::invalidExtensionID;
69 UInt32 ShaderProgram::_extUniformBufferObject = Window::invalidExtensionID;
70 UInt32 ShaderProgram::_extProgramInterfaceQuery = Window::invalidExtensionID;
71 UInt32 ShaderProgram::_extShaderStorageBufferObject = Window::invalidExtensionID;
73 UInt32 ShaderProgram::FuncIdCreateShader = Window::invalidFunctionID;
74 UInt32 ShaderProgram::FuncIdDeleteShader = Window::invalidFunctionID;
75 UInt32 ShaderProgram::FuncIdShaderSource = Window::invalidFunctionID;
76 UInt32 ShaderProgram::FuncIdCompileShader = Window::invalidFunctionID;
77 UInt32 ShaderProgram::FuncIdAttachShader = Window::invalidFunctionID;
78 UInt32 ShaderProgram::FuncIdGetShaderiv = Window::invalidFunctionID;
79 UInt32 ShaderProgram::FuncIdGetShaderInfoLog = Window::invalidFunctionID;
80 UInt32 ShaderProgram::FuncIdGetActiveAttrib = Window::invalidFunctionID;
82 UInt32 ShaderProgram::FuncIdCreateProgram = Window::invalidFunctionID;
83 UInt32 ShaderProgram::FuncIdDeleteProgram = Window::invalidFunctionID;
84 UInt32 ShaderProgram::FuncIdLinkProgram = Window::invalidFunctionID;
85 UInt32 ShaderProgram::FuncIdGetProgramiv = Window::invalidFunctionID;
86 UInt32 ShaderProgram::FuncIdGetProgramInfoLog = Window::invalidFunctionID;
87 UInt32 ShaderProgram::FuncIdUseProgram = Window::invalidFunctionID;
89 UInt32 ShaderProgram::FuncIdGetUniformLocation = Window::invalidFunctionID;
91 UInt32 ShaderProgram::FuncIdUniform1i = Window::invalidFunctionID;
92 UInt32 ShaderProgram::FuncIdUniform2i = Window::invalidFunctionID;
93 UInt32 ShaderProgram::FuncIdUniform3i = Window::invalidFunctionID;
94 UInt32 ShaderProgram::FuncIdUniform4i = Window::invalidFunctionID;
96 UInt32 ShaderProgram::FuncIdUniform1ui = Window::invalidFunctionID;
97 UInt32 ShaderProgram::FuncIdUniform2ui = Window::invalidFunctionID;
98 UInt32 ShaderProgram::FuncIdUniform3ui = Window::invalidFunctionID;
99 UInt32 ShaderProgram::FuncIdUniform4ui = Window::invalidFunctionID;
101 UInt32 ShaderProgram::FuncIdUniform1f = Window::invalidFunctionID;
102 UInt32 ShaderProgram::FuncIdUniform2f = Window::invalidFunctionID;
103 UInt32 ShaderProgram::FuncIdUniform3f = Window::invalidFunctionID;
104 UInt32 ShaderProgram::FuncIdUniform4f = Window::invalidFunctionID;
107 UInt32 ShaderProgram::FuncIdUniform1iv = Window::invalidFunctionID;
108 UInt32 ShaderProgram::FuncIdUniform2iv = Window::invalidFunctionID;
109 UInt32 ShaderProgram::FuncIdUniform3iv = Window::invalidFunctionID;
110 UInt32 ShaderProgram::FuncIdUniform4iv = Window::invalidFunctionID;
112 UInt32 ShaderProgram::FuncIdUniform1uiv = Window::invalidFunctionID;
113 UInt32 ShaderProgram::FuncIdUniform2uiv = Window::invalidFunctionID;
114 UInt32 ShaderProgram::FuncIdUniform3uiv = Window::invalidFunctionID;
115 UInt32 ShaderProgram::FuncIdUniform4uiv = Window::invalidFunctionID;
117 UInt32 ShaderProgram::FuncIdUniform1fv = Window::invalidFunctionID;
118 UInt32 ShaderProgram::FuncIdUniform2fv = Window::invalidFunctionID;
119 UInt32 ShaderProgram::FuncIdUniform3fv = Window::invalidFunctionID;
120 UInt32 ShaderProgram::FuncIdUniform4fv = Window::invalidFunctionID;
122 UInt32 ShaderProgram::FuncIdUniformMatrix2fv = Window::invalidFunctionID;
123 UInt32 ShaderProgram::FuncIdUniformMatrix3fv = Window::invalidFunctionID;
124 UInt32 ShaderProgram::FuncIdUniformMatrix4fv = Window::invalidFunctionID;
126 UInt32 ShaderProgram::FuncIdGetUniformiv = Window::invalidFunctionID;
127 UInt32 ShaderProgram::FuncIdGetUniformfv = Window::invalidFunctionID;
129 UInt32 ShaderProgram::FuncIdProgramParameteri = Window::invalidFunctionID;
130 UInt32 ShaderProgram::FuncIdBindAttribLocation = Window::invalidFunctionID;
132 UInt32 ShaderProgram::FuncIdBindBufferBase = Window::invalidFunctionID;
134 UInt32 ShaderProgram::FuncIdTransformFeedbackVaryings = Window::invalidFunctionID;
136 UInt32 ShaderProgram::FuncIdBeginTransformFeedback = Window::invalidFunctionID;
137 UInt32 ShaderProgram::FuncIdEndTransformFeedback = Window::invalidFunctionID;
139 UInt32 ShaderProgram::FuncIdPauseTransformFeedback = Window::invalidFunctionID;
140 UInt32 ShaderProgram::FuncIdResumeTransformFeedback = Window::invalidFunctionID;
142 UInt32 ShaderProgram::FuncIdGetUniformBlockIndex = Window::invalidFunctionID;
143 UInt32 ShaderProgram::FuncIdUniformBlockBinding = Window::invalidFunctionID;
145 UInt32 ShaderProgram::FuncIdGetProgramResourceIndex = Window::invalidFunctionID;
146 UInt32 ShaderProgram::FuncIdGetProgramResourceiv = Window::invalidFunctionID;
147 UInt32 ShaderProgram::FuncIdShaderStorageBlockBinding = Window::invalidFunctionID;
149 const Char8 *ShaderProgram::NextBufferToken = "gl_NextBuffer";
151 ShaderProgram::ProgramIdPool *ShaderProgram::_pProgIdPool = NULL;
153 template<> inline
154 void SimpleReusePool<Int32,
155 ShaderProgram::ProgramIdPoolTag,
156 SingleLockPolicy >::initializeValue(void)
158 _currentValue = 1;
161 /***************************************************************************\
162 * Class methods *
163 \***************************************************************************/
165 void ShaderProgram::initMethod(InitPhase ePhase)
167 Inherited::initMethod(ePhase);
169 if(ePhase == TypeObject::SystemPost)
171 _extSHL =
172 Window::registerExtension("GL_ARB_shading_language_100");
174 _extCG =
175 Window::registerExtension("GL_EXT_Cg_shader");
177 _extGeoShader4 =
178 Window::registerExtension("GL_EXT_geometry_shader4");
180 _extGPUShader4 =
181 Window::registerExtension("GL_EXT_gpu_shader4");
183 _extTransformFeedback2 =
184 Window::registerExtension("GL_EXT_transform_feedback2");
186 _extUniformBufferObject =
187 Window::registerExtension("GL_ARB_uniform_buffer_object");
189 _extProgramInterfaceQuery =
190 Window::registerExtension("GL_ARB_program_interface_query");
192 _extShaderStorageBufferObject =
193 Window::registerExtension("GL_ARB_shader_storage_buffer_object");
196 FuncIdCreateShader =
197 Window::registerFunction
198 (OSG_DLSYM_UNDERSCORE"glCreateShader",
199 _extSHL);
201 FuncIdDeleteShader =
202 Window::registerFunction (
203 OSG_DLSYM_UNDERSCORE"glDeleteShader",
204 _extSHL);
206 FuncIdShaderSource =
207 Window::registerFunction (
208 OSG_DLSYM_UNDERSCORE"glShaderSource",
209 _extSHL);
211 FuncIdCompileShader =
212 Window::registerFunction (
213 OSG_DLSYM_UNDERSCORE"glCompileShader",
214 _extSHL);
216 FuncIdAttachShader =
217 Window::registerFunction (
218 OSG_DLSYM_UNDERSCORE"glAttachShader",
219 _extSHL);
221 FuncIdGetShaderiv =
222 Window::registerFunction (
223 OSG_DLSYM_UNDERSCORE"glGetShaderiv",
224 _extSHL);
226 FuncIdGetShaderInfoLog =
227 Window::registerFunction (
228 OSG_DLSYM_UNDERSCORE"glGetShaderInfoLog",
229 _extSHL);
231 FuncIdGetActiveAttrib =
232 Window::registerFunction (
233 OSG_DLSYM_UNDERSCORE"glGetActiveAttrib",
234 _extSHL);
237 FuncIdCreateProgram =
238 Window::registerFunction (
239 OSG_DLSYM_UNDERSCORE"glCreateProgram",
240 _extSHL);
242 FuncIdDeleteProgram =
243 Window::registerFunction (
244 OSG_DLSYM_UNDERSCORE"glDeleteProgram",
245 _extSHL);
247 FuncIdLinkProgram =
248 Window::registerFunction (
249 OSG_DLSYM_UNDERSCORE"glLinkProgram",
250 _extSHL);
252 FuncIdGetProgramiv =
253 Window::registerFunction (
254 OSG_DLSYM_UNDERSCORE"glGetProgramiv",
255 _extSHL);
257 FuncIdGetProgramInfoLog =
258 Window::registerFunction (
259 OSG_DLSYM_UNDERSCORE"glGetProgramInfoLog",
260 _extSHL);
262 FuncIdUseProgram =
263 Window::registerFunction (
264 OSG_DLSYM_UNDERSCORE"glUseProgram",
265 _extSHL);
268 FuncIdGetUniformLocation =
269 Window::registerFunction (
270 OSG_DLSYM_UNDERSCORE"glGetUniformLocationARB",
271 _extSHL);
273 // int{,2,3,4} uniforms
274 FuncIdUniform1i =
275 Window::registerFunction (
276 OSG_DLSYM_UNDERSCORE"glUniform1iARB",
277 _extSHL);
279 FuncIdUniform2i =
280 Window::registerFunction (
281 OSG_DLSYM_UNDERSCORE"glUniform2iARB",
282 _extSHL);
284 FuncIdUniform3i =
285 Window::registerFunction (
286 OSG_DLSYM_UNDERSCORE"glUniform3iARB",
287 _extSHL);
289 FuncIdUniform4i =
290 Window::registerFunction (
291 OSG_DLSYM_UNDERSCORE"glUniform4iARB",
292 _extSHL);
294 // uint{,2,3,4} uniforms
295 FuncIdUniform1ui =
296 Window::registerFunction (
297 OSG_DLSYM_UNDERSCORE"glUniform1uiEXT",
298 _extSHL);
300 FuncIdUniform2ui =
301 Window::registerFunction (
302 OSG_DLSYM_UNDERSCORE"glUniform2uiEXT",
303 _extSHL);
305 FuncIdUniform3ui =
306 Window::registerFunction (
307 OSG_DLSYM_UNDERSCORE"glUniform3uiEXT",
308 _extSHL);
310 FuncIdUniform4ui =
311 Window::registerFunction (
312 OSG_DLSYM_UNDERSCORE"glUniform4uiEXT",
313 _extSHL);
315 // float, vec{2,3,4} uniforms
316 FuncIdUniform1f =
317 Window::registerFunction (
318 OSG_DLSYM_UNDERSCORE"glUniform1fARB",
319 _extSHL);
321 FuncIdUniform2f =
322 Window::registerFunction (
323 OSG_DLSYM_UNDERSCORE"glUniform2fARB",
324 _extSHL);
326 FuncIdUniform3f =
327 Window::registerFunction (
328 OSG_DLSYM_UNDERSCORE"glUniform3fARB",
329 _extSHL);
331 FuncIdUniform4f =
332 Window::registerFunction (
333 OSG_DLSYM_UNDERSCORE"glUniform4fARB",
334 _extSHL);
336 // int{,2,3,4} uniform arrays
337 FuncIdUniform1iv =
338 Window::registerFunction (
339 OSG_DLSYM_UNDERSCORE"glUniform1ivARB",
340 _extSHL);
342 FuncIdUniform2iv =
343 Window::registerFunction (
344 OSG_DLSYM_UNDERSCORE"glUniform2ivARB",
345 _extSHL);
346 FuncIdUniform3iv =
347 Window::registerFunction (
348 OSG_DLSYM_UNDERSCORE"glUniform3ivARB",
349 _extSHL);
350 FuncIdUniform4iv =
351 Window::registerFunction (
352 OSG_DLSYM_UNDERSCORE"glUniform4ivARB",
353 _extSHL);
355 // uint{,2,3,4} uniform arrays
356 FuncIdUniform1uiv =
357 Window::registerFunction (
358 OSG_DLSYM_UNDERSCORE"glUniform1uivEXT",
359 _extSHL);
361 FuncIdUniform2uiv =
362 Window::registerFunction (
363 OSG_DLSYM_UNDERSCORE"glUniform2uivEXT",
364 _extSHL);
365 FuncIdUniform3uiv =
366 Window::registerFunction (
367 OSG_DLSYM_UNDERSCORE"glUniform3uivEXT",
368 _extSHL);
369 FuncIdUniform4uiv =
370 Window::registerFunction (
371 OSG_DLSYM_UNDERSCORE"glUniform4uivEXT",
372 _extSHL);
374 // float, vec{2,3,4} uniform arrays
375 FuncIdUniform1fv =
376 Window::registerFunction (
377 OSG_DLSYM_UNDERSCORE"glUniform1fvARB",
378 _extSHL);
380 FuncIdUniform2fv =
381 Window::registerFunction (
382 OSG_DLSYM_UNDERSCORE"glUniform2fvARB",
383 _extSHL);
385 FuncIdUniform3fv =
386 Window::registerFunction (
387 OSG_DLSYM_UNDERSCORE"glUniform3fvARB",
388 _extSHL);
390 FuncIdUniform4fv =
391 Window::registerFunction (
392 OSG_DLSYM_UNDERSCORE"glUniform4fvARB",
393 _extSHL);
396 FuncIdUniformMatrix2fv =
397 Window::registerFunction (
398 OSG_DLSYM_UNDERSCORE"glUniformMatrix2fvARB",
399 _extSHL);
401 FuncIdUniformMatrix3fv =
402 Window::registerFunction (
403 OSG_DLSYM_UNDERSCORE"glUniformMatrix3fvARB",
404 _extSHL);
406 FuncIdUniformMatrix4fv =
407 Window::registerFunction (
408 OSG_DLSYM_UNDERSCORE"glUniformMatrix4fvARB",
409 _extSHL);
411 FuncIdGetUniformiv =
412 Window::registerFunction (
413 OSG_DLSYM_UNDERSCORE"glGetUniformivARB",
414 _extSHL);
416 FuncIdGetUniformfv =
417 Window::registerFunction (
418 OSG_DLSYM_UNDERSCORE"glGetUniformfvARB",
419 _extSHL);
421 FuncIdProgramParameteri =
422 Window::registerFunction (
423 OSG_DLSYM_UNDERSCORE"glProgramParameteriEXT",
424 _extGeoShader4);
426 FuncIdBindAttribLocation =
427 Window::registerFunction (
428 OSG_DLSYM_UNDERSCORE"glBindAttribLocationARB",
429 _extSHL);
431 FuncIdBindBufferBase =
432 Window::registerFunction (
433 OSG_DLSYM_UNDERSCORE"glBindBufferBase",
434 _extTransformFeedback2);
436 FuncIdTransformFeedbackVaryings =
437 Window::registerFunction (
438 OSG_DLSYM_UNDERSCORE"glTransformFeedbackVaryings",
439 _extTransformFeedback2);
441 FuncIdBeginTransformFeedback =
442 Window::registerFunction (
443 OSG_DLSYM_UNDERSCORE"glBeginTransformFeedback",
444 _extTransformFeedback2);
446 FuncIdEndTransformFeedback =
447 Window::registerFunction (
448 OSG_DLSYM_UNDERSCORE"glEndTransformFeedback",
449 _extTransformFeedback2);
451 FuncIdPauseTransformFeedback =
452 Window::registerFunction (
453 OSG_DLSYM_UNDERSCORE"glPauseTransformFeedback",
454 _extTransformFeedback2);
456 FuncIdResumeTransformFeedback =
457 Window::registerFunction (
458 OSG_DLSYM_UNDERSCORE"glResumeTransformFeedback",
459 _extTransformFeedback2);
461 FuncIdGetUniformBlockIndex =
462 Window::registerFunction (
463 OSG_DLSYM_UNDERSCORE"glGetUniformBlockIndex",
464 _extUniformBufferObject);
466 FuncIdUniformBlockBinding =
467 Window::registerFunction (
468 OSG_DLSYM_UNDERSCORE"glUniformBlockBinding",
469 _extUniformBufferObject);
471 FuncIdGetProgramResourceIndex =
472 Window::registerFunction (
473 OSG_DLSYM_UNDERSCORE"glGetProgramResourceIndex",
474 _extProgramInterfaceQuery);
476 FuncIdGetProgramResourceiv =
477 Window::registerFunction (
478 OSG_DLSYM_UNDERSCORE"glGetProgramResourceiv",
479 _extProgramInterfaceQuery);
481 FuncIdShaderStorageBlockBinding =
482 Window::registerFunction (
483 OSG_DLSYM_UNDERSCORE"glShaderStorageBlockBinding",
484 _extShaderStorageBufferObject);
489 /***************************************************************************\
490 * Instance methods *
491 \***************************************************************************/
493 /*-------------------------------------------------------------------------*\
494 - private -
495 \*-------------------------------------------------------------------------*/
497 /*----------------------- constructors & destructors ----------------------*/
499 ShaderProgram::ShaderProgram(void) :
500 Inherited( ),
501 _uiProgId (0)
505 ShaderProgram::ShaderProgram(const ShaderProgram &source) :
506 Inherited(source),
507 _uiProgId (0 )
511 ShaderProgram::~ShaderProgram(void)
515 void ShaderProgram::onCreate(const ShaderProgram *source)
517 Inherited::onCreate(source);
519 // ignore prototypes.
520 if(GlobalSystemState == Startup)
522 if(_pProgIdPool == NULL)
524 _pProgIdPool = new ProgramIdPool;
527 return;
530 setGLId(
531 Window::registerGLObject(
532 boost::bind(&ShaderProgram::handleGL,
533 ShaderProgramMTUncountedPtr(this),
534 _1, _2, _3, _4),
535 &ShaderProgram::handleDestroyGL));
537 _uiProgId = _pProgIdPool->create();
540 void ShaderProgram::onCreateAspect(const ShaderProgram *createAspect,
541 const ShaderProgram *source)
543 Inherited::onCreateAspect(createAspect, source);
545 _uiProgId = createAspect->_uiProgId;
548 void ShaderProgram::onDestroy(UInt32 uiId)
550 if(GlobalSystemState == OSG::Running)
552 _pProgIdPool->release(_uiProgId);
554 if(getGLId() > 0)
555 Window::destroyGLObject(getGLId(), 1);
557 else if(GlobalSystemState == OSG::Shutdown)
559 delete _pProgIdPool;
561 _pProgIdPool = NULL;
564 Inherited::onDestroy(uiId);
567 void ShaderProgram::onDestroyAspect(UInt32 uiContainerId,
568 UInt32 uiAspect )
570 Inherited::onDestroyAspect(uiContainerId, uiAspect);
573 void ShaderProgram::resolveLinks(void)
575 MFDestroyedFunctorsType::const_iterator dfIt =
576 _mfDestroyedFunctors.begin();
577 MFDestroyedFunctorsType::const_iterator dfEnd =
578 _mfDestroyedFunctors.end();
580 for(; dfIt != dfEnd; ++dfIt)
582 if(dfIt->_func.empty() == false)
583 (dfIt->_func)(this, 0x0000, ChangedOrigin::External);
586 Inherited::resolveLinks();
589 UInt32 ShaderProgram::handleGL(DrawEnv *pEnv,
590 UInt32 id,
591 Window::GLObjectStatusE mode,
592 UInt64 uiOptions)
594 Window *pWin = pEnv->getWindow();
596 if(pWin->hasExtOrVersion(_extSHL, 0x0200, 0x0200) == false)
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 0;
606 if(mode == Window::initialize ||
607 mode == Window::reinitialize ||
608 mode == Window::needrefresh )
610 if( mode != Window::needrefresh &&
611 _sfProgram.getValue().empty() == false )
613 GLuint uiShader = GLuint(pWin->getGLObjectId(getGLId()));
615 #ifdef OSG_DEBUG
616 if(mode == Window::initialize && uiShader != 0)
618 FWARNING(("ShaderProgram::handleGL: "
619 "Initialize with non-zero GL object Id.\n"));
621 uiShader = 0;
623 #endif
625 if(uiShader == 0)
626 // if(mode == Window::initialize)
628 OSGGETGLFUNCBYID_GL3_ES(glCreateShader,
629 osgGlCreateShader,
630 FuncIdCreateShader,
631 pWin);
633 GLenum shaderType = _sfShaderType.getValue();
635 if(_sfCgFrontEnd.getValue() == true)
637 if(pWin->hasExtension(_extCG))
639 switch(shaderType)
641 case GL_VERTEX_SHADER:
642 shaderType = GL_CG_VERTEX_SHADER_EXT;
643 break;
644 case GL_FRAGMENT_SHADER:
645 shaderType = GL_CG_FRAGMENT_SHADER_EXT;
646 break;
649 else
651 FWARNING(("EXT_Cg_shader extension not supported, "
652 "using GLSL front end!\n"));
656 uiShader = osgGlCreateShader(shaderType);
659 if(uiShader == 0)
660 return 0;
662 const Char8 *source = _sfProgram.getValue().c_str();
664 OSGGETGLFUNCBYID_GL3_ES(glShaderSource,
665 osgGlShaderSource,
666 FuncIdShaderSource,
667 pWin);
669 OSGGETGLFUNCBYID_GL3_ES(glCompileShader,
670 osgGlCompileShader,
671 FuncIdCompileShader,
672 pWin);
674 OSGGETGLFUNCBYID_GL3_ES(glGetShaderiv,
675 osgGlGetShaderiv,
676 FuncIdGetShaderiv,
677 pWin);
679 if(_sfDefines.getValue().empty() == true)
681 osgGlShaderSource(uiShader,
683 static_cast<const char **>(&source),
686 else
688 const Char8 *defines = _sfDefines.getValue().c_str();
690 const char *shaderSources[2] =
692 defines,
693 source
696 osgGlShaderSource(uiShader,
698 shaderSources,
702 osgGlCompileShader(uiShader);
704 GLint iStatus = 0;
706 osgGlGetShaderiv( uiShader,
707 GL_COMPILE_STATUS,
708 &iStatus);
710 if(iStatus == 0)
712 GLint iDebugLength;
714 osgGlGetShaderiv( uiShader,
715 GL_INFO_LOG_LENGTH,
716 &iDebugLength);
718 if(iDebugLength > 0)
720 Char8 *szDebug = new Char8[iDebugLength];
722 OSGGETGLFUNCBYID_GL3_ES(glGetShaderInfoLog,
723 osgGlGetShaderInfoLog,
724 FuncIdGetShaderInfoLog,
725 pWin);
727 osgGlGetShaderInfoLog( uiShader,
728 iDebugLength,
729 &iDebugLength,
730 szDebug );
732 FFATAL(( "Couldn't compile shader program (0x%x)!\n%s\n",
733 _sfShaderType.getValue(),
734 szDebug));
736 delete [] szDebug;
739 // log source that failed to compile
740 FINFO(("Shader source was:\n"));
742 if(_sfDefines.getValue().empty() == false)
744 FPINFO(("%s\n", _sfDefines.getValue().c_str()));
747 FPINFO(("%s\n", source));
749 OSGGETGLFUNCBYID_GL3_ES(glDeleteShader,
750 osgGlDeleteShader,
751 FuncIdDeleteShader,
752 pWin);
754 osgGlDeleteShader(uiShader);
756 uiShader = 0;
759 pWin->setGLObjectId(getGLId(), uiShader);
762 //updateProgramParameters(win);
763 //updateParameters(win,
764 //*getMFParameters(),
765 //true,
766 //true /*mode != Window::needrefresh*/);
769 return 0;
772 void ShaderProgram::handleDestroyGL(DrawEnv *pEnv,
773 UInt32 id,
774 Window::GLObjectStatusE mode)
776 Window *pWin = pEnv->getWindow();
778 if(!pWin->hasExtOrVersion(_extSHL, 0x0200, 0x0200))
780 FWARNING(("OpenGL Shading Language is not supported, couldn't find "
781 "extension 'GL_ARB_shading_language_100'!\n"));
783 pWin->setGLObjectId(id, 0);
785 return;
788 if(mode == Window::destroy)
790 GLuint uiShader = GLuint(pWin->getGLObjectId(id));
792 if(uiShader != 0)
794 OSGGETGLFUNCBYID_GL3_ES(glDeleteShader,
795 osgGlDeleteShader,
796 FuncIdDeleteShader,
797 pWin);
799 osgGlDeleteShader(uiShader);
801 pWin->setGLObjectId(id, 0);
804 else if(mode == Window::finaldestroy)
806 ;//SWARNING << "Last program user destroyed" << std::endl;
811 /*----------------------------- class specific ----------------------------*/
813 void ShaderProgram::changed(ConstFieldMaskArg whichField,
814 UInt32 origin,
815 BitVector details)
817 Inherited::changed(whichField, origin, details);
819 if(0x0000 != (whichField & VariablesFieldMask))
821 if(details == 0x0001)
823 MFParentFieldContainerPtr::const_iterator parentsIt =
824 this->_mfParents.begin();
826 MFParentFieldContainerPtr::const_iterator parentsEnd =
827 this->_mfParents.end();
829 while(parentsIt != parentsEnd)
831 (*parentsIt)->changed(
832 TypeTraits<BitVector>::One << parentsIt.getParentFieldPos(),
833 ChangedOrigin::Child,
834 VariablesFieldMask);
836 ++parentsIt;
841 if(0x0000 != (whichField & ProgramFieldMask))
843 MFParentFieldContainerPtr::const_iterator parentsIt =
844 this->_mfParents.begin();
846 MFParentFieldContainerPtr::const_iterator parentsEnd =
847 this->_mfParents.end();
849 while(parentsIt != parentsEnd)
851 (*parentsIt)->changed(
852 TypeTraits<BitVector>::One << parentsIt.getParentFieldPos(),
853 ChangedOrigin::Child,
854 ProgramFieldMask);
856 ++parentsIt;
860 Window::reinitializeGLObject(this->getGLId());
864 ShaderProgramTransitPtr ShaderProgram::createVertexShader(
865 bool bCreateDefAttribMap)
867 ShaderProgramTransitPtr returnValue = ShaderProgram::create();
869 returnValue->setShaderType(GL_VERTEX_SHADER);
871 if(bCreateDefAttribMap == true)
872 returnValue->createDefaulAttribMapping();
874 return returnValue;
877 ShaderProgramTransitPtr ShaderProgram::createGeometryShader(void)
879 ShaderProgramTransitPtr returnValue = ShaderProgram::create();
881 returnValue->setShaderType(GL_GEOMETRY_SHADER_EXT);
883 return returnValue;
886 ShaderProgramTransitPtr ShaderProgram::createFragmentShader(void)
888 ShaderProgramTransitPtr returnValue = ShaderProgram::create();
890 returnValue->setShaderType(GL_FRAGMENT_SHADER);
892 return returnValue;
895 void ShaderProgram::accumulateFeedback(
896 DrawEnv *pEnv,
897 UInt32 uiProgram,
898 std::vector<const Char8 *> &vTFVaryings,
899 UInt32 &uiVaryingBufferIndex)
901 if(((_sfShaderType.getValue() == GL_VERTEX_SHADER) ||
902 (_sfShaderType.getValue() == GL_GEOMETRY_SHADER_EXT) ) == false)
904 return;
907 if(vTFVaryings.size() != 0)
909 vTFVaryings.push_back(NextBufferToken);
912 MFFeedbackVaryingsType::const_iterator vIt =
913 this->getMFFeedbackVaryings()->begin();
914 MFFeedbackVaryingsType::const_iterator vEnd =
915 this->getMFFeedbackVaryings()->end ();
917 for(; vIt != vEnd; ++vIt)
919 vTFVaryings.push_back((*vIt).c_str());
923 void ShaderProgram::addParent(FieldContainer * const pParent,
924 UInt16 uiParentFieldId)
926 editMField(ParentsFieldMask, _mfParents);
928 OSG_ASSERT(pParent != NULL);
930 _mfParents.push_back(pParent, uiParentFieldId);
933 void ShaderProgram::subParent(FieldContainer * const pParent)
935 Int32 iParentIdx = _mfParents.findIndex(pParent);
937 if(iParentIdx != -1)
939 editMField(ParentsFieldMask, _mfParents);
941 _mfParents.erase(iParentIdx);
945 void ShaderProgram::dump( UInt32 ,
946 const BitVector ) const
948 SLOG << "Dump ShaderProgram NI" << std::endl;
951 bool ShaderProgram::readProgram(const Char8 *file)
953 return readProgram(editSFProgram()->getValue(), file);
956 bool ShaderProgram::subUniformVariable(const Char8 *name)
958 if(_sfVariables.getValue() != NULL)
960 #if 0
961 return _sfVariables.getValue()->subUniformVariable(
962 name,
963 editMFVariableLocations(),
964 editMFProceduralVariableLocations());
965 #else
966 return _sfVariables.getValue()->subUniformVariable(
967 name,
968 NULL,
969 NULL);
970 #endif
973 return false;
976 void ShaderProgram::clearUniformVariables(void)
978 if(_sfVariables.getValue() != NULL)
980 _sfVariables.getValue()->clearUniformVariables();
985 bool ShaderProgram::subUniformBlock(const Char8 *name)
987 if(_sfVariables.getValue() != NULL)
989 #if 0
990 return _sfVariables.getValue()->subUniformBlock(
991 name,
992 editMFBlockLocations(),
993 editMFProceduralVariableLocations());
994 #else
995 return _sfVariables.getValue()->subUniformBlock(
996 name,
997 NULL,
998 NULL);
999 #endif
1002 return false;
1005 bool ShaderProgram::subShaderStorageBlock(const Char8 *name)
1007 if(_sfVariables.getValue() != NULL)
1009 #if 0
1010 return _sfVariables.getValue()->subShaderStorageBlock(
1011 name,
1012 editMFBlockLocations(),
1013 editMFProceduralVariableLocations());
1014 #else
1015 return _sfVariables.getValue()->subShaderStorageBlock(
1016 name,
1017 NULL,
1018 NULL);
1019 #endif
1022 return false;
1025 bool ShaderProgram::addProceduralVariable(const Char8 *name,
1026 ProcVarFunctor pFunc,
1027 UInt32 uiDependency)
1029 if(_sfVariables.getValue() == NULL)
1031 ShaderProgramVariablesUnrecPtr pParam =
1032 ShaderProgramVariables::create();
1034 setVariables(pParam);
1037 #if 0
1038 return _sfVariables.getValue()->addProceduralVariable(
1039 name,
1040 pFunc,
1041 uiDependency,
1042 editMFProceduralVariableLocations());
1043 #else
1044 return _sfVariables.getValue()->addProceduralVariable(
1045 name,
1046 pFunc,
1047 uiDependency,
1048 NULL);
1049 #endif
1052 bool ShaderProgram::addNodeProceduralVariable(
1053 const Char8 *name,
1054 ProcVarNodeFunctor pFunc,
1055 UInt32 uiDependency)
1057 if(_sfVariables.getValue() == NULL)
1059 ShaderProgramVariablesUnrecPtr pParam =
1060 ShaderProgramVariables::create();
1062 setVariables(pParam);
1065 #if 0
1066 return _sfVariables.getValue()->addNodeProceduralVariable(
1067 name,
1068 pFunc,
1069 uiDependency,
1070 editMFProceduralVariableLocations());
1071 #else
1072 return _sfVariables.getValue()->addNodeProceduralVariable(
1073 name,
1074 pFunc,
1075 uiDependency,
1076 NULL);
1077 #endif
1080 /*! \nohierarchy
1083 struct ParamEqual
1085 GLenum _ref;
1087 ParamEqual(GLenum ref) :
1088 _ref(ref)
1092 bool operator() (const ShaderParameter &lhs)
1094 return lhs.first == _ref;
1098 void ShaderProgram::setProgramParameter(GLenum name, UInt32 value)
1100 editMField(ParameterFieldMask, _mfParameter);
1102 MFShaderParameter::iterator pIt =
1103 std::find_if(_mfParameter.begin(),
1104 _mfParameter.end (),
1105 ParamEqual (name));
1107 if(pIt != _mfParameter.end())
1109 pIt->second = value;
1111 else
1113 ShaderParameter tmpParam;
1115 tmpParam.first = name;
1116 tmpParam.second = value;
1118 _mfParameter.push_back(tmpParam);
1122 void ShaderProgram::subProgramParameter(GLenum name)
1124 MFShaderParameter::iterator pIt =
1125 std::find_if(_mfParameter.begin(),
1126 _mfParameter.end (),
1127 ParamEqual (name));
1129 if(pIt != _mfParameter.end())
1131 editMField(ParameterFieldMask, _mfParameter);
1133 _mfParameter.erase(pIt);
1137 struct AttribEqual
1139 UInt16 _ref;
1141 AttribEqual(UInt16 ref) :
1142 _ref(ref)
1146 bool operator() (const ShaderAttribute &lhs)
1148 return lhs.first == _ref;
1152 void ShaderProgram::setProgramAttribute(UInt16 uiIndex, std::string szName)
1154 editMField(AttributesFieldMask, _mfAttributes);
1156 MFShaderAttribute::iterator aIt =
1157 std::find_if(_mfAttributes.begin(),
1158 _mfAttributes.end (),
1159 AttribEqual (uiIndex));
1162 if(aIt != _mfAttributes.end())
1164 aIt->second = szName;
1166 else
1168 ShaderAttribute tmpAttr;
1170 tmpAttr.first = uiIndex;
1171 tmpAttr.second = szName;
1173 _mfAttributes.push_back(tmpAttr);
1177 void ShaderProgram::subProgramAttribute(UInt16 uiIndex)
1179 MFAttributesType::iterator aIt =
1180 std::find_if(_mfAttributes.begin(),
1181 _mfAttributes.end (),
1182 AttribEqual (uiIndex));
1184 if(aIt != _mfAttributes.end())
1186 editMField(AttributesFieldMask, _mfAttributes);
1188 _mfAttributes.erase(aIt);
1192 void ShaderProgram::createDefaulAttribMapping(void)
1194 if(_sfShaderType.getValue() == GL_VERTEX_SHADER)
1196 this->setProgramAttribute(ShaderConstants::Attribute0Index,
1197 "osg_Vertex" );
1198 this->setProgramAttribute(ShaderConstants::Attribute2Index,
1199 "osg_Normal" );
1201 this->setProgramAttribute(ShaderConstants::Attribute3Index,
1202 "osg_Color" );
1203 this->setProgramAttribute(ShaderConstants::Attribute4Index,
1204 "osg_SecondaryColor" );
1206 this->setProgramAttribute(ShaderConstants::Attribute8Index,
1207 "osg_MultiTexCoord0" );
1208 this->setProgramAttribute(ShaderConstants::Attribute9Index,
1209 "osg_MultiTexCoord1" );
1210 this->setProgramAttribute(ShaderConstants::Attribute10Index,
1211 "osg_MultiTexCoord2" );
1212 this->setProgramAttribute(ShaderConstants::Attribute11Index,
1213 "osg_MultiTexCoord3" );
1214 this->setProgramAttribute(ShaderConstants::Attribute12Index,
1215 "osg_MultiTexCoord4" );
1216 this->setProgramAttribute(ShaderConstants::Attribute13Index,
1217 "osg_MultiTexCoord5" );
1218 this->setProgramAttribute(ShaderConstants::Attribute14Index,
1219 "osg_MultiTexCoord6" );
1220 this->setProgramAttribute(ShaderConstants::Attribute15Index,
1221 "osg_MultiTexCoord7" );
1223 else
1225 FWARNING(("attrib map can only be created for a vertex shader"));
1230 bool ShaderProgram::addOSGVariable(const Char8 *name)
1232 if(_sfVariables.getValue() == NULL)
1234 ShaderProgramVariablesUnrecPtr pVar =
1235 ShaderProgramVariables::create();
1237 setVariables(pVar);
1240 #if 0
1241 return _sfVariables.getValue()->addOSGVariable(
1242 name,
1243 editMFProceduralVariableLocations());
1244 #else
1245 return _sfVariables.getValue()->addOSGVariable(name,
1246 NULL);
1247 #endif
1250 bool ShaderProgram::updateProceduralVariable(const Char8 *name,
1251 ProcVarFunctor pFunc,
1252 UInt32 uiDependency)
1254 if(_sfVariables.getValue() == NULL)
1256 ShaderProgramVariablesUnrecPtr pParam =
1257 ShaderProgramVariables::create();
1259 setVariables(pParam);
1262 return _sfVariables.getValue()->updateProceduralVariable(name,
1263 pFunc,
1264 uiDependency);
1267 bool ShaderProgram::updateNodeProceduralVariable(
1268 const Char8 *name,
1269 ProcVarNodeFunctor pFunc,
1270 UInt32 uiDependency)
1272 if(_sfVariables.getValue() == NULL)
1274 ShaderProgramVariablesUnrecPtr pParam =
1275 ShaderProgramVariables::create();
1277 setVariables(pParam);
1280 return _sfVariables.getValue()->updateNodeProceduralVariable(name,
1281 pFunc,
1282 uiDependency);
1285 bool ShaderProgram::readProgram( std::string &szTarget,
1286 const Char8 *szFilename)
1288 std::ifstream s(szFilename);
1290 if(s.good())
1292 return readProgram(szTarget, s);
1294 else
1296 FWARNING(("ShaderChunk::readProgram: couldn't open '%s' "
1297 "for reading!\n", szFilename));
1299 return false;
1304 bool ShaderProgram::readProgram(std::string &szTarget,
1305 std::istream &iStream)
1307 #define BUFSIZE 200
1309 szTarget.erase();
1311 Char8 buf[BUFSIZE];
1313 if(!iStream.good())
1315 FWARNING(("SHLChunk::readProgram: stream is not good!\n"));
1317 return false;
1322 iStream.read(buf, BUFSIZE);
1324 szTarget.append(buf, iStream.gcount());
1326 while(!iStream.eof());
1328 return true;
1331 OSG_END_NAMESPACE