1 // Created on: 2013-09-19
2 // Created by: Denis BOGOLEPOV
3 // Copyright (c) 2013-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <OSD_File.hxx>
17 #include <OSD_Protection.hxx>
19 #include <Graphic3d_Buffer.hxx>
20 #include <Standard_Assert.hxx>
21 #include <Standard_Atomic.hxx>
22 #include <TCollection_ExtendedString.hxx>
24 #include <OpenGl_Context.hxx>
25 #include <OpenGl_ShaderProgram.hxx>
26 #include <OpenGl_ShaderManager.hxx>
27 #include <OpenGl_ArbTexBindless.hxx>
29 IMPLEMENT_STANDARD_HANDLE (OpenGl_ShaderProgram, OpenGl_Resource)
30 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderProgram, OpenGl_Resource)
32 OpenGl_VariableSetterSelector OpenGl_ShaderProgram::mySetterSelector = OpenGl_VariableSetterSelector();
34 // Declare OCCT-specific OpenGL/GLSL shader variables
35 Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] =
37 "occModelWorldMatrix", // OpenGl_OCC_MODEL_WORLD_MATRIX
38 "occWorldViewMatrix", // OpenGl_OCC_WORLD_VIEW_MATRIX
39 "occProjectionMatrix", // OpenGl_OCC_PROJECTION_MATRIX
40 "occModelWorldMatrixInverse", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE
41 "occWorldViewMatrixInverse", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE
42 "occProjectionMatrixInverse", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE
43 "occModelWorldMatrixTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE
44 "occWorldViewMatrixTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE
45 "occProjectionMatrixTranspose", // OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE
46 "occModelWorldMatrixInverseTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE
47 "occWorldViewMatrixInverseTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE
48 "occProjectionMatrixInverseTranspose", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE
50 "occClipPlaneEquations", // OpenGl_OCC_CLIP_PLANE_EQUATIONS
51 "occClipPlaneSpaces", // OpenGl_OCC_CLIP_PLANE_SPACES
52 "occClipPlaneCount", // OpenGl_OCC_CLIP_PLANE_COUNT
54 "occLightSourcesCount", // OpenGl_OCC_LIGHT_SOURCE_COUNT
55 "occLightSourcesTypes", // OpenGl_OCC_LIGHT_SOURCE_TYPES
56 "occLightSources", // OpenGl_OCC_LIGHT_SOURCE_PARAMS
57 "occLightAmbient", // OpenGl_OCC_LIGHT_AMBIENT
59 "occActiveSampler", // OpenGl_OCCT_ACTIVE_SAMPLER
60 "occTextureEnable", // OpenGl_OCCT_TEXTURE_ENABLE
61 "occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE
62 "occFrontMaterial", // OpenGl_OCCT_FRONT_MATERIAL
63 "occBackMaterial", // OpenGl_OCCT_BACK_MATERIAL
64 "occColor", // OpenGl_OCCT_COLOR
66 "occPointSize" // OpenGl_OCCT_POINT_SIZE
70 // =======================================================================
71 // function : OpenGl_VariableSetterSelector
72 // purpose : Creates new variable setter selector
73 // =======================================================================
74 OpenGl_VariableSetterSelector::OpenGl_VariableSetterSelector()
76 // Note: Add new variable setters here
77 mySetterList = OpenGl_HashMapInitializer::CreateListOf<size_t, OpenGl_SetterInterface*>
78 (Graphic3d_UniformValueTypeID<int>::ID, new OpenGl_VariableSetter<int>())
79 (Graphic3d_UniformValueTypeID<float>::ID, new OpenGl_VariableSetter<float>())
80 (Graphic3d_UniformValueTypeID<OpenGl_Vec2>::ID, new OpenGl_VariableSetter<OpenGl_Vec2>())
81 (Graphic3d_UniformValueTypeID<OpenGl_Vec3>::ID, new OpenGl_VariableSetter<OpenGl_Vec3>())
82 (Graphic3d_UniformValueTypeID<OpenGl_Vec4>::ID, new OpenGl_VariableSetter<OpenGl_Vec4>())
83 (Graphic3d_UniformValueTypeID<OpenGl_Vec2i>::ID, new OpenGl_VariableSetter<OpenGl_Vec2i>())
84 (Graphic3d_UniformValueTypeID<OpenGl_Vec3i>::ID, new OpenGl_VariableSetter<OpenGl_Vec3i>())
85 (Graphic3d_UniformValueTypeID<OpenGl_Vec4i>::ID, new OpenGl_VariableSetter<OpenGl_Vec4i>());
88 // =======================================================================
89 // function : ~OpenGl_VariableSetterSelector
90 // purpose : Releases memory resources of variable setter selector
91 // =======================================================================
92 OpenGl_VariableSetterSelector::~OpenGl_VariableSetterSelector()
94 for (OpenGl_SetterList::Iterator anIt (mySetterList); anIt.More(); anIt.Next())
102 // =======================================================================
104 // purpose : Sets generic variable to specified shader program
105 // =======================================================================
106 void OpenGl_VariableSetterSelector::Set (const Handle(OpenGl_Context)& theCtx,
107 const Handle(Graphic3d_ShaderVariable)& theVariable,
108 OpenGl_ShaderProgram* theProgram) const
110 Standard_ASSERT_RETURN (mySetterList.IsBound (theVariable->Value()->TypeID()),
111 "The type of user-defined uniform variable is not supported...", );
113 mySetterList.Find (theVariable->Value()->TypeID())->Set (theCtx, theVariable, theProgram);
116 // =======================================================================
117 // function : OpenGl_ShaderProgram
118 // purpose : Creates uninitialized shader program
119 // =======================================================================
120 OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy)
121 : myProgramID (NO_PROGRAM),
125 memset (myCurrentState, 0, sizeof (myCurrentState));
126 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
128 myStateLocations[aVar] = INVALID_LOCATION;
132 // =======================================================================
133 // function : Initialize
134 // purpose : Initializes program object with the list of shader objects
135 // =======================================================================
136 Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& theCtx,
137 const Graphic3d_ShaderObjectList& theShaders)
139 if (theCtx.IsNull() || !Create (theCtx))
141 return Standard_False;
144 OSD_File aDeclFile (Graphic3d_ShaderProgram::ShadersFolder() + "/Declarations.glsl");
145 OSD_File aDeclImplFile (Graphic3d_ShaderProgram::ShadersFolder() + "/DeclarationsImpl.glsl");
146 if (!aDeclFile.Exists()
147 || !aDeclImplFile.Exists())
149 const TCollection_ExtendedString aMsg = "Error! Failed to load OCCT shader declarations file";
150 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
151 GL_DEBUG_TYPE_ERROR_ARB,
153 GL_DEBUG_SEVERITY_HIGH_ARB,
155 return Standard_False;
158 TCollection_AsciiString aHeader = !myProxy.IsNull() && !myProxy->Header().IsEmpty()
159 ? (myProxy->Header() + "\n")
160 : TCollection_AsciiString();
162 TCollection_AsciiString aDeclarations;
163 aDeclFile.Open (OSD_ReadOnly, OSD_Protection());
164 aDeclFile.Read (aDeclarations, (int)aDeclFile.Size());
167 TCollection_AsciiString aDeclImpl;
168 aDeclImplFile.Open (OSD_ReadOnly, OSD_Protection());
169 aDeclImplFile.Read (aDeclImpl, (int)aDeclImplFile.Size());
170 aDeclImplFile.Close();
171 aDeclarations += aDeclImpl;
173 for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders);
174 anIter.More(); anIter.Next())
176 if (!anIter.Value()->IsDone())
178 const TCollection_ExtendedString aMsg = "Error! Failed to get shader source";
179 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
180 GL_DEBUG_TYPE_ERROR_ARB,
182 GL_DEBUG_SEVERITY_HIGH_ARB,
184 return Standard_False;
187 Handle(OpenGl_ShaderObject) aShader;
189 // Note: Add support of other shader types here
190 switch (anIter.Value()->Type())
192 case Graphic3d_TOS_VERTEX:
193 aShader = new OpenGl_ShaderObject (GL_VERTEX_SHADER);
195 case Graphic3d_TOS_FRAGMENT:
196 aShader = new OpenGl_ShaderObject (GL_FRAGMENT_SHADER);
200 // Is unsupported shader type?
201 if (aShader.IsNull())
203 TCollection_ExtendedString aMsg = "Error! Unsupported shader type";
204 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
205 GL_DEBUG_TYPE_ERROR_ARB,
207 GL_DEBUG_SEVERITY_HIGH_ARB,
209 return Standard_False;
212 if (!aShader->Create (theCtx))
214 aShader->Release (theCtx.operator->());
215 return Standard_False;
218 TCollection_AsciiString aSource = aDeclarations + anIter.Value()->Source();
219 switch (anIter.Value()->Type())
221 case Graphic3d_TOS_VERTEX:
223 aSource = aHeader + TCollection_AsciiString ("#define VERTEX_SHADER\n") + aSource;
226 case Graphic3d_TOS_FRAGMENT:
228 #if defined(GL_ES_VERSION_2_0)
229 TCollection_AsciiString aPrefix (theCtx->hasHighp
230 ? "precision highp float;\n"
231 : "precision mediump float;\n");
232 aSource = aHeader + aPrefix + aSource;
234 aSource = aHeader + aSource;
240 if (!aShader->LoadSource (theCtx, aSource))
242 const TCollection_ExtendedString aMsg = "Error! Failed to set shader source";
243 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
244 GL_DEBUG_TYPE_ERROR_ARB,
246 GL_DEBUG_SEVERITY_HIGH_ARB,
248 aShader->Release (theCtx.operator->());
249 return Standard_False;
252 if (!aShader->Compile (theCtx))
254 TCollection_AsciiString aLog;
255 aShader->FetchInfoLog (theCtx, aLog);
258 aLog = "Compilation log is empty.";
260 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
261 GL_DEBUG_TYPE_ERROR_ARB,
263 GL_DEBUG_SEVERITY_HIGH_ARB,
264 TCollection_ExtendedString ("Failed to compile shader object. Compilation log:\n") + aLog);
265 aShader->Release (theCtx.operator->());
266 return Standard_False;
268 else if (theCtx->caps->glslWarnings)
270 TCollection_AsciiString aLog;
271 aShader->FetchInfoLog (theCtx, aLog);
273 && !aLog.IsEqual ("No errors.\n"))
275 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
276 GL_DEBUG_TYPE_PORTABILITY_ARB,
278 GL_DEBUG_SEVERITY_LOW_ARB,
279 TCollection_ExtendedString ("Shader compilation log:\n") + aLog);
283 if (!AttachShader (theCtx, aShader))
285 aShader->Release (theCtx.operator->());
286 return Standard_False;
290 // bind locations for pre-defined Vertex Attributes
291 SetAttributeName (theCtx, Graphic3d_TOA_POS, "occVertex");
292 SetAttributeName (theCtx, Graphic3d_TOA_NORM, "occNormal");
293 SetAttributeName (theCtx, Graphic3d_TOA_UV, "occTexCoord");
294 SetAttributeName (theCtx, Graphic3d_TOA_COLOR, "occVertColor");
298 TCollection_AsciiString aLog;
299 FetchInfoLog (theCtx, aLog);
302 aLog = "Linker log is empty.";
304 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
305 GL_DEBUG_TYPE_ERROR_ARB,
307 GL_DEBUG_SEVERITY_HIGH_ARB,
308 TCollection_ExtendedString ("Failed to link program object! Linker log:\n") + aLog);
309 return Standard_False;
311 else if (theCtx->caps->glslWarnings)
313 TCollection_AsciiString aLog;
314 FetchInfoLog (theCtx, aLog);
316 && !aLog.IsEqual ("No errors.\n"))
318 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
319 GL_DEBUG_TYPE_PORTABILITY_ARB,
321 GL_DEBUG_SEVERITY_LOW_ARB,
322 TCollection_ExtendedString ("GLSL linker log:\n") + aLog);
326 return Standard_True;
329 // =======================================================================
330 // function : ~OpenGl_ShaderProgram
331 // purpose : Releases resources of shader program
332 // =======================================================================
333 OpenGl_ShaderProgram::~OpenGl_ShaderProgram()
338 // =======================================================================
339 // function : AttachShader
340 // purpose : Attaches shader object to the program object
341 // =======================================================================
342 Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context)& theCtx,
343 const Handle(OpenGl_ShaderObject)& theShader)
345 if (myProgramID == NO_PROGRAM || theShader.IsNull())
347 return Standard_False;
350 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
352 if (theShader == anIter.Value())
354 return Standard_False;
358 myShaderObjects.Append (theShader);
359 theCtx->core20fwd->glAttachShader (myProgramID, theShader->myShaderID);
360 return Standard_True;
363 // =======================================================================
364 // function : DetachShader
365 // purpose : Detaches shader object to the program object
366 // =======================================================================
367 Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context)& theCtx,
368 const Handle(OpenGl_ShaderObject)& theShader)
370 if (myProgramID == NO_PROGRAM
371 || theShader.IsNull())
373 return Standard_False;
376 OpenGl_ShaderList::Iterator anIter (myShaderObjects);
377 while (anIter.More())
379 if (theShader == anIter.Value())
381 myShaderObjects.Remove (anIter);
390 return Standard_False;
393 theCtx->core20fwd->glDetachShader (myProgramID, theShader->myShaderID);
394 return Standard_True;
397 // =======================================================================
399 // purpose : Links the program object
400 // =======================================================================
401 Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx)
403 if (myProgramID == NO_PROGRAM)
405 return Standard_False;
408 GLint aStatus = GL_FALSE;
409 theCtx->core20fwd->glLinkProgram (myProgramID);
410 theCtx->core20fwd->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
411 if (aStatus == GL_FALSE)
413 return Standard_False;
416 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
418 myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]);
420 return Standard_True;
423 // =======================================================================
424 // function : FetchInfoLog
425 // purpose : Fetches information log of the last link operation
426 // =======================================================================
427 Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
428 TCollection_AsciiString& theOutput)
430 if (myProgramID == NO_PROGRAM)
432 return Standard_False;
436 theCtx->core20fwd->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
439 GLchar* aLog = (GLchar*) alloca (aLength);
440 memset (aLog, 0, aLength);
441 theCtx->core20fwd->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
444 return Standard_True;
447 // =======================================================================
448 // function : ApplyVariables
449 // purpose : Fetches uniform variables from proxy shader program
450 // =======================================================================
451 Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Context)& theCtx)
453 if (myProxy.IsNull() || myProxy->Variables().IsEmpty())
455 return Standard_False;
458 for (Graphic3d_ShaderVariableList::Iterator anIter (myProxy->Variables()); anIter.More(); anIter.Next())
460 mySetterSelector.Set (theCtx, anIter.Value(), this);
463 myProxy->ClearVariables();
464 return Standard_True;
467 // =======================================================================
468 // function : ActiveState
469 // purpose : Returns index of last modification for specified state type
470 // =======================================================================
471 Standard_Size OpenGl_ShaderProgram::ActiveState (const OpenGl_UniformStateType theType) const
473 if (theType < MaxStateTypes)
475 return myCurrentState[theType];
480 // =======================================================================
481 // function : UpdateState
482 // purpose : Updates index of last modification for specified state type
483 // =======================================================================
484 void OpenGl_ShaderProgram::UpdateState (const OpenGl_UniformStateType theType,
485 const Standard_Size theIndex)
487 if (theType < MaxStateTypes)
489 myCurrentState[theType] = theIndex;
493 // =======================================================================
494 // function : GetUniformLocation
495 // purpose : Returns location (index) of the specific uniform variable
496 // =======================================================================
497 GLint OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& theCtx,
498 const GLchar* theName) const
500 return myProgramID != NO_PROGRAM
501 ? theCtx->core20fwd->glGetUniformLocation (myProgramID, theName)
505 // =======================================================================
506 // function : GetAttributeLocation
507 // purpose : Returns location (index) of the generic vertex attribute
508 // =======================================================================
509 GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)& theCtx,
510 const GLchar* theName) const
512 return myProgramID != NO_PROGRAM
513 ? theCtx->core20fwd->glGetAttribLocation (myProgramID, theName)
517 // =======================================================================
518 // function : GetStateLocation
519 // purpose : Returns location of the OCCT state uniform variable
520 // =======================================================================
521 GLint OpenGl_ShaderProgram::GetStateLocation (const GLuint theVariable) const
523 if (theVariable < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES)
525 return myStateLocations[theVariable];
527 return INVALID_LOCATION;
530 // =======================================================================
531 // function : GetUniform
532 // purpose : Returns the value of the integer uniform variable
533 // =======================================================================
534 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
535 const GLchar* theName,
536 OpenGl_Vec4i& theValue) const
538 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
541 // =======================================================================
542 // function : GetUniform
543 // purpose : Returns the value of the integer uniform variable
544 // =======================================================================
545 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
547 OpenGl_Vec4i& theValue) const
549 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
551 return Standard_False;
554 theCtx->core20fwd->glGetUniformiv (myProgramID, theLocation, theValue);
555 return Standard_True;
558 // =======================================================================
559 // function : GetUniform
560 // purpose : Returns the value of the floating-point uniform variable
561 // =======================================================================
562 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
563 const GLchar* theName,
564 OpenGl_Vec4& theValue) const
566 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
569 // =======================================================================
570 // function : GetUniform
571 // purpose : Returns the value of the floating-point uniform variable
572 // =======================================================================
573 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
575 OpenGl_Vec4& theValue) const
577 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
579 return Standard_False;
582 theCtx->core20fwd->glGetUniformfv (myProgramID, theLocation, theValue);
583 return Standard_True;
586 // =======================================================================
587 // function : GetAttribute
588 // purpose : Returns the integer vertex attribute
589 // =======================================================================
590 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
591 const GLchar* theName,
592 OpenGl_Vec4i& theValue) const
594 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
597 // =======================================================================
598 // function : GetAttribute
599 // purpose : Returns the integer vertex attribute
600 // =======================================================================
601 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
603 OpenGl_Vec4i& theValue) const
605 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
607 return Standard_False;
610 theCtx->core20fwd->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
611 return Standard_True;
614 // =======================================================================
615 // function : GetAttribute
616 // purpose : Returns the floating-point vertex attribute
617 // =======================================================================
618 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
619 const GLchar* theName,
620 OpenGl_Vec4& theValue) const
622 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
625 // =======================================================================
626 // function : GetAttribute
627 // purpose : Returns the floating-point vertex attribute
628 // =======================================================================
629 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
631 OpenGl_Vec4& theValue) const
633 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
635 return Standard_False;
638 theCtx->core20fwd->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
639 return Standard_True;
642 // =======================================================================
643 // function : SetAttributeName
645 // =======================================================================
646 Standard_Boolean OpenGl_ShaderProgram::SetAttributeName (const Handle(OpenGl_Context)& theCtx,
648 const GLchar* theName)
650 theCtx->core20fwd->glBindAttribLocation (myProgramID, theIndex, theName);
651 return Standard_True;
654 // =======================================================================
655 // function : SetAttribute
657 // =======================================================================
658 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
659 const GLchar* theName,
662 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
665 // =======================================================================
666 // function : SetAttribute
668 // =======================================================================
669 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
673 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
675 return Standard_False;
678 theCtx->core20fwd->glVertexAttrib1f (theIndex, theValue);
679 return Standard_True;
682 // =======================================================================
683 // function : SetAttribute
685 // =======================================================================
686 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
687 const GLchar* theName,
688 const OpenGl_Vec2& theValue)
690 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
693 // =======================================================================
694 // function : SetAttribute
696 // =======================================================================
697 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
699 const OpenGl_Vec2& theValue)
701 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
703 return Standard_False;
706 theCtx->core20fwd->glVertexAttrib2fv (theIndex, theValue);
707 return Standard_True;
710 // =======================================================================
711 // function : SetAttribute
713 // =======================================================================
714 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
715 const GLchar* theName,
716 const OpenGl_Vec3& theValue)
718 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
721 // =======================================================================
722 // function : SetAttribute
724 // =======================================================================
725 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
727 const OpenGl_Vec3& theValue)
729 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
731 return Standard_False;
734 theCtx->core20fwd->glVertexAttrib3fv (theIndex, theValue);
735 return Standard_True;
738 // =======================================================================
739 // function : SetAttribute
741 // =======================================================================
742 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
743 const GLchar* theName,
744 const OpenGl_Vec4& theValue)
746 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
749 // =======================================================================
750 // function : SetAttribute
752 // =======================================================================
753 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
755 const OpenGl_Vec4& theValue)
757 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
759 return Standard_False;
762 theCtx->core20fwd->glVertexAttrib4fv (theIndex, theValue);
763 return Standard_True;
766 // =======================================================================
767 // function : SetUniform
768 // purpose : Specifies the value of the integer uniform variable
769 // =======================================================================
770 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
771 const GLchar* theName,
774 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
777 // =======================================================================
778 // function : SetUniform
779 // purpose : Specifies the value of the integer uniform variable
780 // =======================================================================
781 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
785 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
787 return Standard_False;
790 theCtx->core20fwd->glUniform1i (theLocation, theValue);
791 return Standard_True;
794 // =======================================================================
795 // function : SetUniform
796 // purpose : Specifies the value of the 64-bit unsigned uniform variable
797 // =======================================================================
798 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
799 const GLchar* theName,
802 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
805 // =======================================================================
806 // function : SetUniform
807 // purpose : Specifies the value of the 64-bit unsigned uniform variable
808 // =======================================================================
809 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
813 if (theCtx->arbTexBindless == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
815 return Standard_False;
818 #if !defined(GL_ES_VERSION_2_0)
819 theCtx->arbTexBindless->glUniformHandleui64ARB (theLocation, theValue);
822 return Standard_True;
825 // =======================================================================
826 // function : SetUniform
827 // purpose : Specifies the value of the 64-bit unsigned uniform array
828 // =======================================================================
829 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
830 const GLchar* theName,
831 const GLsizei theCount,
832 const GLuint64* theValue)
834 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theCount, theValue);
837 // =======================================================================
838 // function : SetUniform
839 // purpose : Specifies the value of the 64-bit unsigned uniform array
840 // =======================================================================
841 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
843 const GLsizei theCount,
844 const GLuint64* theValue)
846 if (theCtx->arbTexBindless == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
848 return Standard_False;
851 #if !defined(GL_ES_VERSION_2_0)
852 theCtx->arbTexBindless->glUniformHandleui64vARB (theLocation, theCount, theValue);
855 return Standard_True;
858 // =======================================================================
859 // function : SetUniform
860 // purpose : Specifies the value of the floating-point uniform variable
861 // =======================================================================
862 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
863 const GLchar* theName,
866 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
869 // =======================================================================
870 // function : SetUniform
871 // purpose : Specifies the value of the floating-point uniform variable
872 // =======================================================================
873 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
877 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
879 return Standard_False;
882 theCtx->core20fwd->glUniform1f (theLocation, theValue);
883 return Standard_True;
886 // =======================================================================
887 // function : SetUniform
888 // purpose : Specifies the value of the integer uniform 2D vector
889 // =======================================================================
890 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
891 const GLchar* theName,
892 const OpenGl_Vec2i& theValue)
894 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
897 // =======================================================================
898 // function : SetUniform
899 // purpose : Specifies the value of the integer uniform 2D vector
900 // =======================================================================
901 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
903 const OpenGl_Vec2i& theValue)
905 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
907 return Standard_False;
910 theCtx->core20fwd->glUniform2iv (theLocation, 1, theValue);
911 return Standard_True;
914 // =======================================================================
915 // function : SetUniform
916 // purpose : Specifies the value of the integer uniform 3D vector
917 // =======================================================================
918 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
919 const GLchar* theName,
920 const OpenGl_Vec3i& theValue)
922 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
925 // =======================================================================
926 // function : SetUniform
927 // purpose : Specifies the value of the integer uniform 3D vector
928 // =======================================================================
929 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
931 const OpenGl_Vec3i& theValue)
933 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
935 return Standard_False;
938 theCtx->core20fwd->glUniform3iv (theLocation, 1, theValue);
939 return Standard_True;
942 // =======================================================================
943 // function : SetUniform
944 // purpose : Specifies the value of the integer uniform 4D vector
945 // =======================================================================
946 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
947 const GLchar* theName,
948 const OpenGl_Vec4i& theValue)
950 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
953 // =======================================================================
954 // function : SetUniform
955 // purpose : Specifies the value of the integer uniform 4D vector
956 // =======================================================================
957 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
959 const OpenGl_Vec4i& theValue)
961 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
963 return Standard_False;
966 theCtx->core20fwd->glUniform4iv (theLocation, 1, theValue);
967 return Standard_True;
970 // =======================================================================
971 // function : SetUniform
972 // purpose : Specifies the value of the floating-point uniform 2D vector
973 // =======================================================================
974 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
975 const GLchar* theName,
976 const OpenGl_Vec2& theValue)
978 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
981 // =======================================================================
982 // function : SetUniform
983 // purpose : Specifies the value of the floating-point uniform 2D vector
984 // =======================================================================
985 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
987 const OpenGl_Vec2& theValue)
989 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
991 return Standard_False;
994 theCtx->core20fwd->glUniform2fv (theLocation, 1, theValue);
995 return Standard_True;
998 // =======================================================================
999 // function : SetUniform
1000 // purpose : Specifies the value of the floating-point uniform 3D vector
1001 // =======================================================================
1002 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1003 const GLchar* theName,
1004 const OpenGl_Vec3& theValue)
1006 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1009 // =======================================================================
1010 // function : SetUniform
1011 // purpose : Specifies the value of the floating-point uniform 3D vector
1012 // =======================================================================
1013 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1015 const OpenGl_Vec3& theValue)
1017 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1019 return Standard_False;
1022 theCtx->core20fwd->glUniform3fv (theLocation, 1, theValue);
1023 return Standard_True;
1026 // =======================================================================
1027 // function : SetUniform
1028 // purpose : Specifies the value of the floating-point uniform 4D vector
1029 // =======================================================================
1030 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1031 const GLchar* theName,
1032 const OpenGl_Vec4& theValue)
1034 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1037 // =======================================================================
1038 // function : SetUniform
1039 // purpose : Specifies the value of the floating-point uniform 4D vector
1040 // =======================================================================
1041 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1043 const OpenGl_Vec4& theValue)
1045 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1047 return Standard_False;
1050 theCtx->core20fwd->glUniform4fv (theLocation, 1, theValue);
1051 return Standard_True;
1054 // =======================================================================
1055 // function : SetUniform
1056 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1057 // =======================================================================
1058 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1059 const GLchar* theName,
1060 const OpenGl_Mat4& theValue,
1061 GLboolean theTranspose)
1063 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1066 // =======================================================================
1067 // function : SetUniform
1068 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1069 // =======================================================================
1070 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1072 const OpenGl_Mat4& theValue,
1073 GLboolean theTranspose)
1075 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1077 return Standard_False;
1080 theCtx->core20fwd->glUniformMatrix4fv (theLocation, 1, GL_FALSE, theTranspose ? theValue.Transposed() : theValue);
1081 return Standard_True;
1084 // =======================================================================
1085 // function : SetUniform
1086 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1087 // =======================================================================
1088 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1089 const GLchar* theName,
1090 const OpenGl_Matrix& theValue,
1091 GLboolean theTranspose)
1093 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1096 // =======================================================================
1097 // function : SetUniform
1098 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1099 // =======================================================================
1100 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1102 const OpenGl_Matrix& theValue,
1103 GLboolean theTranspose)
1105 return SetUniform (theCtx, theLocation, OpenGl_Mat4::Map (*theValue.mat), theTranspose);
1108 // =======================================================================
1109 // function : SetUniform
1110 // purpose : Specifies the value of the float uniform array
1111 // =======================================================================
1112 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1115 const Standard_ShortReal* theData)
1117 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1119 return Standard_False;
1122 theCtx->core20fwd->glUniform1fv (theLocation, theCount, theData);
1123 return Standard_True;
1126 // =======================================================================
1127 // function : SetUniform
1128 // purpose : Specifies the value of the float2 uniform array
1129 // =======================================================================
1130 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1133 const OpenGl_Vec2* theData)
1135 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1137 return Standard_False;
1140 theCtx->core20fwd->glUniform2fv (theLocation, theCount, theData[0].GetData());
1141 return Standard_True;
1144 // =======================================================================
1145 // function : SetUniform
1146 // purpose : Specifies the value of the float3 uniform array
1147 // =======================================================================
1148 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1151 const OpenGl_Vec3* theData)
1153 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1155 return Standard_False;
1158 theCtx->core20fwd->glUniform3fv (theLocation, theCount, theData[0].GetData());
1159 return Standard_True;
1162 // =======================================================================
1163 // function : SetUniform
1164 // purpose : Specifies the value of the float4 uniform array
1165 // =======================================================================
1166 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1169 const OpenGl_Vec4* theData)
1171 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1173 return Standard_False;
1176 theCtx->core20fwd->glUniform4fv (theLocation, theCount, theData[0].GetData());
1177 return Standard_True;
1180 // =======================================================================
1181 // function : SetUniform
1182 // purpose : Specifies the value of the integer uniform array
1183 // =======================================================================
1184 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1187 const Standard_Integer* theData)
1189 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1191 return Standard_False;
1194 theCtx->core20fwd->glUniform1iv (theLocation, theCount, theData);
1195 return Standard_True;
1198 // =======================================================================
1199 // function : SetUniform
1200 // purpose : Specifies the value of the int2 uniform array
1201 // =======================================================================
1202 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1205 const OpenGl_Vec2i* theData)
1207 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1209 return Standard_False;
1212 theCtx->core20fwd->glUniform2iv (theLocation, theCount, theData[0].GetData());
1213 return Standard_True;
1216 // =======================================================================
1217 // function : SetUniform
1218 // purpose : Specifies the value of the int3 uniform array
1219 // =======================================================================
1220 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1223 const OpenGl_Vec3i* theData)
1225 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1227 return Standard_False;
1230 theCtx->core20fwd->glUniform3iv (theLocation, theCount, theData[0].GetData());
1231 return Standard_True;
1234 // =======================================================================
1235 // function : SetUniform
1236 // purpose : Specifies the value of the int4 uniform array
1237 // =======================================================================
1238 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1241 const OpenGl_Vec4i* theData)
1243 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1245 return Standard_False;
1248 theCtx->core20fwd->glUniform4iv (theLocation, theCount, theData[0].GetData());
1249 return Standard_True;
1252 // =======================================================================
1253 // function : SetSampler
1254 // purpose : Specifies the value of the sampler uniform variable
1255 // =======================================================================
1256 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1257 const GLchar* theName,
1258 const GLenum theTextureUnit)
1260 return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit);
1263 // =======================================================================
1264 // function : SetSampler
1265 // purpose : Specifies the value of the sampler uniform variable
1266 // =======================================================================
1267 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1269 const GLenum theTextureUnit)
1271 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1273 return Standard_False;
1276 theCtx->core20fwd->glUniform1i (theLocation, theTextureUnit);
1277 return Standard_True;
1280 // =======================================================================
1281 // function : Create
1282 // purpose : Creates new empty shader program of specified type
1283 // =======================================================================
1284 Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx)
1286 if (myProgramID == NO_PROGRAM
1287 && theCtx->core20fwd != NULL)
1289 myProgramID = theCtx->core20fwd->glCreateProgram();
1292 return myProgramID != NO_PROGRAM;
1295 // =======================================================================
1296 // function : Release
1297 // purpose : Destroys shader program
1298 // =======================================================================
1299 void OpenGl_ShaderProgram::Release (OpenGl_Context* theCtx)
1301 if (myProgramID == NO_PROGRAM)
1306 Standard_ASSERT_RETURN (theCtx != NULL,
1307 "OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...",);
1309 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
1311 if (!anIter.Value().IsNull())
1313 anIter.ChangeValue()->Release (theCtx);
1314 anIter.ChangeValue().Nullify();
1318 if (theCtx->core20fwd != NULL
1319 && theCtx->IsValid())
1321 theCtx->core20fwd->glDeleteProgram (myProgramID);
1324 myProgramID = NO_PROGRAM;