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 aDeclarations;
159 aDeclFile.Open (OSD_ReadOnly, OSD_Protection());
160 aDeclFile.Read (aDeclarations, (int)aDeclFile.Size());
163 TCollection_AsciiString aDeclImpl;
164 aDeclImplFile.Open (OSD_ReadOnly, OSD_Protection());
165 aDeclImplFile.Read (aDeclImpl, (int)aDeclImplFile.Size());
166 aDeclImplFile.Close();
167 aDeclarations += aDeclImpl;
169 for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders);
170 anIter.More(); anIter.Next())
172 if (!anIter.Value()->IsDone())
174 const TCollection_ExtendedString aMsg = "Error! Failed to get shader source";
175 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
176 GL_DEBUG_TYPE_ERROR_ARB,
178 GL_DEBUG_SEVERITY_HIGH_ARB,
180 return Standard_False;
183 Handle(OpenGl_ShaderObject) aShader;
185 // Note: Add support of other shader types here
186 switch (anIter.Value()->Type())
188 case Graphic3d_TOS_VERTEX:
189 aShader = new OpenGl_ShaderObject (GL_VERTEX_SHADER);
191 case Graphic3d_TOS_FRAGMENT:
192 aShader = new OpenGl_ShaderObject (GL_FRAGMENT_SHADER);
196 // Is unsupported shader type?
197 if (aShader.IsNull())
199 TCollection_ExtendedString aMsg = "Error! Unsupported shader type";
200 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
201 GL_DEBUG_TYPE_ERROR_ARB,
203 GL_DEBUG_SEVERITY_HIGH_ARB,
205 return Standard_False;
208 if (!aShader->Create (theCtx))
210 aShader->Release (theCtx.operator->());
211 return Standard_False;
214 TCollection_AsciiString aSource = aDeclarations + anIter.Value()->Source();
215 switch (anIter.Value()->Type())
217 case Graphic3d_TOS_VERTEX:
219 aSource = TCollection_AsciiString ("#define VERTEX_SHADER\n") + aSource;
222 case Graphic3d_TOS_FRAGMENT:
224 #if defined(GL_ES_VERSION_2_0)
225 TCollection_AsciiString aPrefix (theCtx->hasHighp
226 ? "precision highp float;\n"
227 : "precision mediump float;\n");
228 aSource = aPrefix + aSource;
234 if (!aShader->LoadSource (theCtx, aSource))
236 const TCollection_ExtendedString aMsg = "Error! Failed to set shader source";
237 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
238 GL_DEBUG_TYPE_ERROR_ARB,
240 GL_DEBUG_SEVERITY_HIGH_ARB,
242 aShader->Release (theCtx.operator->());
243 return Standard_False;
246 if (!aShader->Compile (theCtx))
248 TCollection_AsciiString aLog;
249 aShader->FetchInfoLog (theCtx, aLog);
252 aLog = "Compilation log is empty.";
254 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
255 GL_DEBUG_TYPE_ERROR_ARB,
257 GL_DEBUG_SEVERITY_HIGH_ARB,
258 TCollection_ExtendedString ("Failed to compile shader object. Compilation log:\n") + aLog);
259 aShader->Release (theCtx.operator->());
260 return Standard_False;
262 else if (theCtx->caps->glslWarnings)
264 TCollection_AsciiString aLog;
265 aShader->FetchInfoLog (theCtx, aLog);
267 && !aLog.IsEqual ("No errors.\n"))
269 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
270 GL_DEBUG_TYPE_PORTABILITY_ARB,
272 GL_DEBUG_SEVERITY_LOW_ARB,
273 TCollection_ExtendedString ("Shader compilation log:\n") + aLog);
277 if (!AttachShader (theCtx, aShader))
279 aShader->Release (theCtx.operator->());
280 return Standard_False;
284 // bind locations for pre-defined Vertex Attributes
285 SetAttributeName (theCtx, Graphic3d_TOA_POS, "occVertex");
286 SetAttributeName (theCtx, Graphic3d_TOA_NORM, "occNormal");
287 SetAttributeName (theCtx, Graphic3d_TOA_UV, "occTexCoord");
288 SetAttributeName (theCtx, Graphic3d_TOA_COLOR, "occVertColor");
292 TCollection_AsciiString aLog;
293 FetchInfoLog (theCtx, aLog);
296 aLog = "Linker log is empty.";
298 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
299 GL_DEBUG_TYPE_ERROR_ARB,
301 GL_DEBUG_SEVERITY_HIGH_ARB,
302 TCollection_ExtendedString ("Failed to link program object! Linker log:\n") + aLog);
303 return Standard_False;
305 else if (theCtx->caps->glslWarnings)
307 TCollection_AsciiString aLog;
308 FetchInfoLog (theCtx, aLog);
310 && !aLog.IsEqual ("No errors.\n"))
312 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
313 GL_DEBUG_TYPE_PORTABILITY_ARB,
315 GL_DEBUG_SEVERITY_LOW_ARB,
316 TCollection_ExtendedString ("GLSL linker log:\n") + aLog);
320 return Standard_True;
323 // =======================================================================
324 // function : ~OpenGl_ShaderProgram
325 // purpose : Releases resources of shader program
326 // =======================================================================
327 OpenGl_ShaderProgram::~OpenGl_ShaderProgram()
332 // =======================================================================
333 // function : AttachShader
334 // purpose : Attaches shader object to the program object
335 // =======================================================================
336 Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context)& theCtx,
337 const Handle(OpenGl_ShaderObject)& theShader)
339 if (myProgramID == NO_PROGRAM || theShader.IsNull())
341 return Standard_False;
344 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
346 if (theShader == anIter.Value())
348 return Standard_False;
352 myShaderObjects.Append (theShader);
353 theCtx->core20->glAttachShader (myProgramID, theShader->myShaderID);
354 return Standard_True;
357 // =======================================================================
358 // function : DetachShader
359 // purpose : Detaches shader object to the program object
360 // =======================================================================
361 Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context)& theCtx,
362 const Handle(OpenGl_ShaderObject)& theShader)
364 if (myProgramID == NO_PROGRAM
365 || theShader.IsNull())
367 return Standard_False;
370 OpenGl_ShaderList::Iterator anIter (myShaderObjects);
371 while (anIter.More())
373 if (theShader == anIter.Value())
375 myShaderObjects.Remove (anIter);
384 return Standard_False;
387 theCtx->core20->glDetachShader (myProgramID, theShader->myShaderID);
388 return Standard_True;
391 // =======================================================================
393 // purpose : Links the program object
394 // =======================================================================
395 Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx)
397 if (myProgramID == NO_PROGRAM)
399 return Standard_False;
402 GLint aStatus = GL_FALSE;
403 theCtx->core20->glLinkProgram (myProgramID);
404 theCtx->core20->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
405 if (aStatus == GL_FALSE)
407 return Standard_False;
410 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
412 myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]);
414 return Standard_True;
417 // =======================================================================
418 // function : FetchInfoLog
419 // purpose : Fetches information log of the last link operation
420 // =======================================================================
421 Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
422 TCollection_AsciiString& theOutput)
424 if (myProgramID == NO_PROGRAM)
426 return Standard_False;
430 theCtx->core20->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
433 GLchar* aLog = (GLchar*) alloca (aLength);
434 memset (aLog, 0, aLength);
435 theCtx->core20->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
438 return Standard_True;
441 // =======================================================================
442 // function : ApplyVariables
443 // purpose : Fetches uniform variables from proxy shader program
444 // =======================================================================
445 Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Context)& theCtx)
447 if (myProxy.IsNull() || myProxy->Variables().IsEmpty())
449 return Standard_False;
452 for (Graphic3d_ShaderVariableList::Iterator anIter (myProxy->Variables()); anIter.More(); anIter.Next())
454 mySetterSelector.Set (theCtx, anIter.Value(), this);
457 myProxy->ClearVariables();
458 return Standard_True;
461 // =======================================================================
462 // function : ActiveState
463 // purpose : Returns index of last modification for specified state type
464 // =======================================================================
465 Standard_Size OpenGl_ShaderProgram::ActiveState (const OpenGl_UniformStateType theType) const
467 if (theType < MaxStateTypes)
469 return myCurrentState[theType];
474 // =======================================================================
475 // function : UpdateState
476 // purpose : Updates index of last modification for specified state type
477 // =======================================================================
478 void OpenGl_ShaderProgram::UpdateState (const OpenGl_UniformStateType theType,
479 const Standard_Size theIndex)
481 if (theType < MaxStateTypes)
483 myCurrentState[theType] = theIndex;
487 // =======================================================================
488 // function : GetUniformLocation
489 // purpose : Returns location (index) of the specific uniform variable
490 // =======================================================================
491 GLint OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& theCtx,
492 const GLchar* theName) const
494 return myProgramID != NO_PROGRAM
495 ? theCtx->core20->glGetUniformLocation (myProgramID, theName)
499 // =======================================================================
500 // function : GetAttributeLocation
501 // purpose : Returns location (index) of the generic vertex attribute
502 // =======================================================================
503 GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)& theCtx,
504 const GLchar* theName) const
506 return myProgramID != NO_PROGRAM
507 ? theCtx->core20->glGetAttribLocation (myProgramID, theName)
511 // =======================================================================
512 // function : GetStateLocation
513 // purpose : Returns location of the OCCT state uniform variable
514 // =======================================================================
515 GLint OpenGl_ShaderProgram::GetStateLocation (const GLuint theVariable) const
517 if (theVariable < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES)
519 return myStateLocations[theVariable];
521 return INVALID_LOCATION;
524 // =======================================================================
525 // function : GetUniform
526 // purpose : Returns the value of the integer uniform variable
527 // =======================================================================
528 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
529 const GLchar* theName,
530 OpenGl_Vec4i& theValue) const
532 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
535 // =======================================================================
536 // function : GetUniform
537 // purpose : Returns the value of the integer uniform variable
538 // =======================================================================
539 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
541 OpenGl_Vec4i& theValue) const
543 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
545 return Standard_False;
548 theCtx->core20->glGetUniformiv (myProgramID, theLocation, theValue);
549 return Standard_True;
552 // =======================================================================
553 // function : GetUniform
554 // purpose : Returns the value of the floating-point uniform variable
555 // =======================================================================
556 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
557 const GLchar* theName,
558 OpenGl_Vec4& theValue) const
560 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
563 // =======================================================================
564 // function : GetUniform
565 // purpose : Returns the value of the floating-point uniform variable
566 // =======================================================================
567 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
569 OpenGl_Vec4& theValue) const
571 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
573 return Standard_False;
576 theCtx->core20->glGetUniformfv (myProgramID, theLocation, theValue);
577 return Standard_True;
580 // =======================================================================
581 // function : GetAttribute
582 // purpose : Returns the integer vertex attribute
583 // =======================================================================
584 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
585 const GLchar* theName,
586 OpenGl_Vec4i& theValue) const
588 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
591 // =======================================================================
592 // function : GetAttribute
593 // purpose : Returns the integer vertex attribute
594 // =======================================================================
595 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
597 OpenGl_Vec4i& theValue) const
599 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
601 return Standard_False;
604 theCtx->core20->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
605 return Standard_True;
608 // =======================================================================
609 // function : GetAttribute
610 // purpose : Returns the floating-point vertex attribute
611 // =======================================================================
612 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
613 const GLchar* theName,
614 OpenGl_Vec4& theValue) const
616 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
619 // =======================================================================
620 // function : GetAttribute
621 // purpose : Returns the floating-point vertex attribute
622 // =======================================================================
623 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
625 OpenGl_Vec4& theValue) const
627 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
629 return Standard_False;
632 theCtx->core20->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
633 return Standard_True;
636 // =======================================================================
637 // function : SetAttributeName
639 // =======================================================================
640 Standard_Boolean OpenGl_ShaderProgram::SetAttributeName (const Handle(OpenGl_Context)& theCtx,
642 const GLchar* theName)
644 theCtx->core20fwd->glBindAttribLocation (myProgramID, theIndex, theName);
645 return Standard_True;
648 // =======================================================================
649 // function : SetAttribute
651 // =======================================================================
652 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
653 const GLchar* theName,
656 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
659 // =======================================================================
660 // function : SetAttribute
662 // =======================================================================
663 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
667 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
669 return Standard_False;
672 theCtx->core20fwd->glVertexAttrib1f (theIndex, theValue);
673 return Standard_True;
676 // =======================================================================
677 // function : SetAttribute
679 // =======================================================================
680 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
681 const GLchar* theName,
682 const OpenGl_Vec2& theValue)
684 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
687 // =======================================================================
688 // function : SetAttribute
690 // =======================================================================
691 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
693 const OpenGl_Vec2& theValue)
695 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
697 return Standard_False;
700 theCtx->core20fwd->glVertexAttrib2fv (theIndex, theValue);
701 return Standard_True;
704 // =======================================================================
705 // function : SetAttribute
707 // =======================================================================
708 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
709 const GLchar* theName,
710 const OpenGl_Vec3& theValue)
712 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
715 // =======================================================================
716 // function : SetAttribute
718 // =======================================================================
719 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
721 const OpenGl_Vec3& theValue)
723 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
725 return Standard_False;
728 theCtx->core20fwd->glVertexAttrib3fv (theIndex, theValue);
729 return Standard_True;
732 // =======================================================================
733 // function : SetAttribute
735 // =======================================================================
736 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
737 const GLchar* theName,
738 const OpenGl_Vec4& theValue)
740 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
743 // =======================================================================
744 // function : SetAttribute
746 // =======================================================================
747 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
749 const OpenGl_Vec4& theValue)
751 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
753 return Standard_False;
756 theCtx->core20fwd->glVertexAttrib4fv (theIndex, theValue);
757 return Standard_True;
760 // =======================================================================
761 // function : SetUniform
762 // purpose : Specifies the value of the integer uniform variable
763 // =======================================================================
764 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
765 const GLchar* theName,
768 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
771 // =======================================================================
772 // function : SetUniform
773 // purpose : Specifies the value of the integer uniform variable
774 // =======================================================================
775 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
779 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
781 return Standard_False;
784 theCtx->core20->glUniform1i (theLocation, theValue);
785 return Standard_True;
788 // =======================================================================
789 // function : SetUniform
790 // purpose : Specifies the value of the 64-bit unsigned uniform variable
791 // =======================================================================
792 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
793 const GLchar* theName,
796 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
799 // =======================================================================
800 // function : SetUniform
801 // purpose : Specifies the value of the 64-bit unsigned uniform variable
802 // =======================================================================
803 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
807 if (theCtx->arbTexBindless == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
809 return Standard_False;
812 #if !defined(GL_ES_VERSION_2_0)
813 theCtx->arbTexBindless->glUniformHandleui64ARB (theLocation, theValue);
816 return Standard_True;
819 // =======================================================================
820 // function : SetUniform
821 // purpose : Specifies the value of the 64-bit unsigned uniform array
822 // =======================================================================
823 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
824 const GLchar* theName,
825 const GLsizei theCount,
826 const GLuint64* theValue)
828 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theCount, theValue);
831 // =======================================================================
832 // function : SetUniform
833 // purpose : Specifies the value of the 64-bit unsigned uniform array
834 // =======================================================================
835 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
837 const GLsizei theCount,
838 const GLuint64* theValue)
840 if (theCtx->arbTexBindless == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
842 return Standard_False;
845 #if !defined(GL_ES_VERSION_2_0)
846 theCtx->arbTexBindless->glUniformHandleui64vARB (theLocation, theCount, theValue);
849 return Standard_True;
852 // =======================================================================
853 // function : SetUniform
854 // purpose : Specifies the value of the floating-point uniform variable
855 // =======================================================================
856 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
857 const GLchar* theName,
860 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
863 // =======================================================================
864 // function : SetUniform
865 // purpose : Specifies the value of the floating-point uniform variable
866 // =======================================================================
867 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
871 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
873 return Standard_False;
876 theCtx->core20->glUniform1f (theLocation, theValue);
877 return Standard_True;
880 // =======================================================================
881 // function : SetUniform
882 // purpose : Specifies the value of the integer uniform 2D vector
883 // =======================================================================
884 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
885 const GLchar* theName,
886 const OpenGl_Vec2i& theValue)
888 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
891 // =======================================================================
892 // function : SetUniform
893 // purpose : Specifies the value of the integer uniform 2D vector
894 // =======================================================================
895 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
897 const OpenGl_Vec2i& theValue)
899 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
901 return Standard_False;
904 theCtx->core20->glUniform2iv (theLocation, 1, theValue);
905 return Standard_True;
908 // =======================================================================
909 // function : SetUniform
910 // purpose : Specifies the value of the integer uniform 3D vector
911 // =======================================================================
912 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
913 const GLchar* theName,
914 const OpenGl_Vec3i& theValue)
916 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
919 // =======================================================================
920 // function : SetUniform
921 // purpose : Specifies the value of the integer uniform 3D vector
922 // =======================================================================
923 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
925 const OpenGl_Vec3i& theValue)
927 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
929 return Standard_False;
932 theCtx->core20->glUniform3iv (theLocation, 1, theValue);
933 return Standard_True;
936 // =======================================================================
937 // function : SetUniform
938 // purpose : Specifies the value of the integer uniform 4D vector
939 // =======================================================================
940 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
941 const GLchar* theName,
942 const OpenGl_Vec4i& theValue)
944 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
947 // =======================================================================
948 // function : SetUniform
949 // purpose : Specifies the value of the integer uniform 4D vector
950 // =======================================================================
951 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
953 const OpenGl_Vec4i& theValue)
955 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
957 return Standard_False;
960 theCtx->core20->glUniform4iv (theLocation, 1, theValue);
961 return Standard_True;
964 // =======================================================================
965 // function : SetUniform
966 // purpose : Specifies the value of the floating-point uniform 2D vector
967 // =======================================================================
968 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
969 const GLchar* theName,
970 const OpenGl_Vec2& theValue)
972 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
975 // =======================================================================
976 // function : SetUniform
977 // purpose : Specifies the value of the floating-point uniform 2D vector
978 // =======================================================================
979 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
981 const OpenGl_Vec2& theValue)
983 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
985 return Standard_False;
988 theCtx->core20->glUniform2fv (theLocation, 1, theValue);
989 return Standard_True;
992 // =======================================================================
993 // function : SetUniform
994 // purpose : Specifies the value of the floating-point uniform 3D vector
995 // =======================================================================
996 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
997 const GLchar* theName,
998 const OpenGl_Vec3& theValue)
1000 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1003 // =======================================================================
1004 // function : SetUniform
1005 // purpose : Specifies the value of the floating-point uniform 3D vector
1006 // =======================================================================
1007 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1009 const OpenGl_Vec3& theValue)
1011 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1013 return Standard_False;
1016 theCtx->core20->glUniform3fv (theLocation, 1, theValue);
1017 return Standard_True;
1020 // =======================================================================
1021 // function : SetUniform
1022 // purpose : Specifies the value of the floating-point uniform 4D vector
1023 // =======================================================================
1024 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1025 const GLchar* theName,
1026 const OpenGl_Vec4& theValue)
1028 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1031 // =======================================================================
1032 // function : SetUniform
1033 // purpose : Specifies the value of the floating-point uniform 4D vector
1034 // =======================================================================
1035 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1037 const OpenGl_Vec4& theValue)
1039 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1041 return Standard_False;
1044 theCtx->core20->glUniform4fv (theLocation, 1, theValue);
1045 return Standard_True;
1048 // =======================================================================
1049 // function : SetUniform
1050 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1051 // =======================================================================
1052 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1053 const GLchar* theName,
1054 const OpenGl_Mat4& theValue,
1055 GLboolean theTranspose)
1057 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1060 // =======================================================================
1061 // function : SetUniform
1062 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1063 // =======================================================================
1064 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1066 const OpenGl_Mat4& theValue,
1067 GLboolean theTranspose)
1069 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1071 return Standard_False;
1074 theCtx->core20->glUniformMatrix4fv (theLocation, 1, GL_FALSE, theTranspose ? theValue.Transposed() : theValue);
1075 return Standard_True;
1078 // =======================================================================
1079 // function : SetUniform
1080 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1081 // =======================================================================
1082 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1083 const GLchar* theName,
1084 const OpenGl_Matrix& theValue,
1085 GLboolean theTranspose)
1087 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1090 // =======================================================================
1091 // function : SetUniform
1092 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1093 // =======================================================================
1094 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1096 const OpenGl_Matrix& theValue,
1097 GLboolean theTranspose)
1099 return SetUniform (theCtx, theLocation, OpenGl_Mat4::Map (*theValue.mat), theTranspose);
1102 // =======================================================================
1103 // function : SetUniform
1104 // purpose : Specifies the value of the float uniform array
1105 // =======================================================================
1106 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1109 const Standard_ShortReal* theData)
1111 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1113 return Standard_False;
1116 theCtx->core20->glUniform1fv (theLocation, theCount, theData);
1117 return Standard_True;
1120 // =======================================================================
1121 // function : SetUniform
1122 // purpose : Specifies the value of the float2 uniform array
1123 // =======================================================================
1124 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1127 const OpenGl_Vec2* theData)
1129 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1131 return Standard_False;
1134 theCtx->core20->glUniform2fv (theLocation, theCount, theData[0].GetData());
1135 return Standard_True;
1138 // =======================================================================
1139 // function : SetUniform
1140 // purpose : Specifies the value of the float3 uniform array
1141 // =======================================================================
1142 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1145 const OpenGl_Vec3* theData)
1147 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1149 return Standard_False;
1152 theCtx->core20->glUniform3fv (theLocation, theCount, theData[0].GetData());
1153 return Standard_True;
1156 // =======================================================================
1157 // function : SetUniform
1158 // purpose : Specifies the value of the float4 uniform array
1159 // =======================================================================
1160 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1163 const OpenGl_Vec4* theData)
1165 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1167 return Standard_False;
1170 theCtx->core20->glUniform4fv (theLocation, theCount, theData[0].GetData());
1171 return Standard_True;
1174 // =======================================================================
1175 // function : SetUniform
1176 // purpose : Specifies the value of the integer uniform array
1177 // =======================================================================
1178 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1181 const Standard_Integer* theData)
1183 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1185 return Standard_False;
1188 theCtx->core20->glUniform1iv (theLocation, theCount, theData);
1189 return Standard_True;
1192 // =======================================================================
1193 // function : SetUniform
1194 // purpose : Specifies the value of the int2 uniform array
1195 // =======================================================================
1196 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1199 const OpenGl_Vec2i* theData)
1201 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1203 return Standard_False;
1206 theCtx->core20->glUniform2iv (theLocation, theCount, theData[0].GetData());
1207 return Standard_True;
1210 // =======================================================================
1211 // function : SetUniform
1212 // purpose : Specifies the value of the int3 uniform array
1213 // =======================================================================
1214 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1217 const OpenGl_Vec3i* theData)
1219 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1221 return Standard_False;
1224 theCtx->core20->glUniform3iv (theLocation, theCount, theData[0].GetData());
1225 return Standard_True;
1228 // =======================================================================
1229 // function : SetUniform
1230 // purpose : Specifies the value of the int4 uniform array
1231 // =======================================================================
1232 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1235 const OpenGl_Vec4i* theData)
1237 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1239 return Standard_False;
1242 theCtx->core20->glUniform4iv (theLocation, theCount, theData[0].GetData());
1243 return Standard_True;
1246 // =======================================================================
1247 // function : SetSampler
1248 // purpose : Specifies the value of the sampler uniform variable
1249 // =======================================================================
1250 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1251 const GLchar* theName,
1252 const GLenum theTextureUnit)
1254 return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit);
1257 // =======================================================================
1258 // function : SetSampler
1259 // purpose : Specifies the value of the sampler uniform variable
1260 // =======================================================================
1261 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1263 const GLenum theTextureUnit)
1265 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1267 return Standard_False;
1270 theCtx->core20->glUniform1i (theLocation, theTextureUnit);
1271 return Standard_True;
1274 // =======================================================================
1275 // function : Create
1276 // purpose : Creates new empty shader program of specified type
1277 // =======================================================================
1278 Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx)
1280 if (myProgramID == NO_PROGRAM
1281 && theCtx->core20 != NULL)
1283 myProgramID = theCtx->core20->glCreateProgram();
1286 return myProgramID != NO_PROGRAM;
1289 // =======================================================================
1290 // function : Release
1291 // purpose : Destroys shader program
1292 // =======================================================================
1293 void OpenGl_ShaderProgram::Release (OpenGl_Context* theCtx)
1295 if (myProgramID == NO_PROGRAM)
1300 Standard_ASSERT_RETURN (theCtx != NULL,
1301 "OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...",);
1303 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
1305 if (!anIter.Value().IsNull())
1307 anIter.ChangeValue()->Release (theCtx);
1308 anIter.ChangeValue().Nullify();
1312 if (theCtx->core20 != NULL
1313 && theCtx->IsValid())
1315 theCtx->core20->glDeleteProgram (myProgramID);
1318 myProgramID = NO_PROGRAM;