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>
30 OpenGl_VariableSetterSelector OpenGl_ShaderProgram::mySetterSelector = OpenGl_VariableSetterSelector();
32 // Declare OCCT-specific OpenGL/GLSL shader variables
33 Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] =
35 "occModelWorldMatrix", // OpenGl_OCC_MODEL_WORLD_MATRIX
36 "occWorldViewMatrix", // OpenGl_OCC_WORLD_VIEW_MATRIX
37 "occProjectionMatrix", // OpenGl_OCC_PROJECTION_MATRIX
38 "occModelWorldMatrixInverse", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE
39 "occWorldViewMatrixInverse", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE
40 "occProjectionMatrixInverse", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE
41 "occModelWorldMatrixTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE
42 "occWorldViewMatrixTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE
43 "occProjectionMatrixTranspose", // OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE
44 "occModelWorldMatrixInverseTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE
45 "occWorldViewMatrixInverseTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE
46 "occProjectionMatrixInverseTranspose", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE
48 "occClipPlaneEquations", // OpenGl_OCC_CLIP_PLANE_EQUATIONS
49 "occClipPlaneSpaces", // OpenGl_OCC_CLIP_PLANE_SPACES
50 "occClipPlaneCount", // OpenGl_OCC_CLIP_PLANE_COUNT
52 "occLightSourcesCount", // OpenGl_OCC_LIGHT_SOURCE_COUNT
53 "occLightSourcesTypes", // OpenGl_OCC_LIGHT_SOURCE_TYPES
54 "occLightSources", // OpenGl_OCC_LIGHT_SOURCE_PARAMS
55 "occLightAmbient", // OpenGl_OCC_LIGHT_AMBIENT
57 "occActiveSampler", // OpenGl_OCCT_ACTIVE_SAMPLER
58 "occTextureEnable", // OpenGl_OCCT_TEXTURE_ENABLE
59 "occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE
60 "occFrontMaterial", // OpenGl_OCCT_FRONT_MATERIAL
61 "occBackMaterial", // OpenGl_OCCT_BACK_MATERIAL
62 "occColor", // OpenGl_OCCT_COLOR
64 "occPointSize" // OpenGl_OCCT_POINT_SIZE
68 // =======================================================================
69 // function : OpenGl_VariableSetterSelector
70 // purpose : Creates new variable setter selector
71 // =======================================================================
72 OpenGl_VariableSetterSelector::OpenGl_VariableSetterSelector()
74 // Note: Add new variable setters here
75 mySetterList = OpenGl_HashMapInitializer::CreateListOf<size_t, OpenGl_SetterInterface*>
76 (Graphic3d_UniformValueTypeID<int>::ID, new OpenGl_VariableSetter<int>())
77 (Graphic3d_UniformValueTypeID<float>::ID, new OpenGl_VariableSetter<float>())
78 (Graphic3d_UniformValueTypeID<OpenGl_Vec2>::ID, new OpenGl_VariableSetter<OpenGl_Vec2>())
79 (Graphic3d_UniformValueTypeID<OpenGl_Vec3>::ID, new OpenGl_VariableSetter<OpenGl_Vec3>())
80 (Graphic3d_UniformValueTypeID<OpenGl_Vec4>::ID, new OpenGl_VariableSetter<OpenGl_Vec4>())
81 (Graphic3d_UniformValueTypeID<OpenGl_Vec2i>::ID, new OpenGl_VariableSetter<OpenGl_Vec2i>())
82 (Graphic3d_UniformValueTypeID<OpenGl_Vec3i>::ID, new OpenGl_VariableSetter<OpenGl_Vec3i>())
83 (Graphic3d_UniformValueTypeID<OpenGl_Vec4i>::ID, new OpenGl_VariableSetter<OpenGl_Vec4i>());
86 // =======================================================================
87 // function : ~OpenGl_VariableSetterSelector
88 // purpose : Releases memory resources of variable setter selector
89 // =======================================================================
90 OpenGl_VariableSetterSelector::~OpenGl_VariableSetterSelector()
92 for (OpenGl_SetterList::Iterator anIt (mySetterList); anIt.More(); anIt.Next())
100 // =======================================================================
102 // purpose : Sets generic variable to specified shader program
103 // =======================================================================
104 void OpenGl_VariableSetterSelector::Set (const Handle(OpenGl_Context)& theCtx,
105 const Handle(Graphic3d_ShaderVariable)& theVariable,
106 OpenGl_ShaderProgram* theProgram) const
108 Standard_ASSERT_RETURN (mySetterList.IsBound (theVariable->Value()->TypeID()),
109 "The type of user-defined uniform variable is not supported...", );
111 mySetterList.Find (theVariable->Value()->TypeID())->Set (theCtx, theVariable, theProgram);
114 // =======================================================================
115 // function : OpenGl_ShaderProgram
116 // purpose : Creates uninitialized shader program
117 // =======================================================================
118 OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy)
119 : myProgramID (NO_PROGRAM),
123 memset (myCurrentState, 0, sizeof (myCurrentState));
124 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
126 myStateLocations[aVar] = INVALID_LOCATION;
130 // =======================================================================
131 // function : Initialize
132 // purpose : Initializes program object with the list of shader objects
133 // =======================================================================
134 Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& theCtx,
135 const Graphic3d_ShaderObjectList& theShaders)
137 if (theCtx.IsNull() || !Create (theCtx))
139 return Standard_False;
142 OSD_File aDeclFile (Graphic3d_ShaderProgram::ShadersFolder() + "/Declarations.glsl");
143 OSD_File aDeclImplFile (Graphic3d_ShaderProgram::ShadersFolder() + "/DeclarationsImpl.glsl");
144 if (!aDeclFile.Exists()
145 || !aDeclImplFile.Exists())
147 const TCollection_ExtendedString aMsg = "Error! Failed to load OCCT shader declarations file";
148 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
149 GL_DEBUG_TYPE_ERROR_ARB,
151 GL_DEBUG_SEVERITY_HIGH_ARB,
153 return Standard_False;
156 TCollection_AsciiString aHeader = !myProxy.IsNull() && !myProxy->Header().IsEmpty()
157 ? (myProxy->Header() + "\n")
158 : TCollection_AsciiString();
160 TCollection_AsciiString aDeclarations;
161 aDeclFile.Open (OSD_ReadOnly, OSD_Protection());
162 aDeclFile.Read (aDeclarations, (int)aDeclFile.Size());
165 TCollection_AsciiString aDeclImpl;
166 aDeclImplFile.Open (OSD_ReadOnly, OSD_Protection());
167 aDeclImplFile.Read (aDeclImpl, (int)aDeclImplFile.Size());
168 aDeclImplFile.Close();
169 aDeclarations += aDeclImpl;
171 for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders);
172 anIter.More(); anIter.Next())
174 if (!anIter.Value()->IsDone())
176 const TCollection_ExtendedString aMsg = "Error! Failed to get shader source";
177 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
178 GL_DEBUG_TYPE_ERROR_ARB,
180 GL_DEBUG_SEVERITY_HIGH_ARB,
182 return Standard_False;
185 Handle(OpenGl_ShaderObject) aShader;
187 // Note: Add support of other shader types here
188 switch (anIter.Value()->Type())
190 case Graphic3d_TOS_VERTEX:
191 aShader = new OpenGl_ShaderObject (GL_VERTEX_SHADER);
193 case Graphic3d_TOS_FRAGMENT:
194 aShader = new OpenGl_ShaderObject (GL_FRAGMENT_SHADER);
198 // Is unsupported shader type?
199 if (aShader.IsNull())
201 TCollection_ExtendedString aMsg = "Error! Unsupported shader type";
202 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
203 GL_DEBUG_TYPE_ERROR_ARB,
205 GL_DEBUG_SEVERITY_HIGH_ARB,
207 return Standard_False;
210 if (!aShader->Create (theCtx))
212 aShader->Release (theCtx.operator->());
213 return Standard_False;
216 TCollection_AsciiString aSource = aDeclarations + anIter.Value()->Source();
217 switch (anIter.Value()->Type())
219 case Graphic3d_TOS_VERTEX:
221 aSource = aHeader + TCollection_AsciiString ("#define VERTEX_SHADER\n") + aSource;
224 case Graphic3d_TOS_FRAGMENT:
226 #if defined(GL_ES_VERSION_2_0)
227 TCollection_AsciiString aPrefix (theCtx->hasHighp
228 ? "precision highp float;\n"
229 : "precision mediump float;\n");
230 aSource = aHeader + aPrefix + aSource;
232 aSource = aHeader + aSource;
238 if (!aShader->LoadSource (theCtx, aSource))
240 const TCollection_ExtendedString aMsg = "Error! Failed to set shader source";
241 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
242 GL_DEBUG_TYPE_ERROR_ARB,
244 GL_DEBUG_SEVERITY_HIGH_ARB,
246 aShader->Release (theCtx.operator->());
247 return Standard_False;
250 if (!aShader->Compile (theCtx))
252 TCollection_AsciiString aLog;
253 aShader->FetchInfoLog (theCtx, aLog);
256 aLog = "Compilation log is empty.";
258 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
259 GL_DEBUG_TYPE_ERROR_ARB,
261 GL_DEBUG_SEVERITY_HIGH_ARB,
262 TCollection_ExtendedString ("Failed to compile shader object. Compilation log:\n") + aLog);
263 aShader->Release (theCtx.operator->());
264 return Standard_False;
266 else if (theCtx->caps->glslWarnings)
268 TCollection_AsciiString aLog;
269 aShader->FetchInfoLog (theCtx, aLog);
271 && !aLog.IsEqual ("No errors.\n"))
273 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
274 GL_DEBUG_TYPE_PORTABILITY_ARB,
276 GL_DEBUG_SEVERITY_LOW_ARB,
277 TCollection_ExtendedString ("Shader compilation log:\n") + aLog);
281 if (!AttachShader (theCtx, aShader))
283 aShader->Release (theCtx.operator->());
284 return Standard_False;
288 // bind locations for pre-defined Vertex Attributes
289 SetAttributeName (theCtx, Graphic3d_TOA_POS, "occVertex");
290 SetAttributeName (theCtx, Graphic3d_TOA_NORM, "occNormal");
291 SetAttributeName (theCtx, Graphic3d_TOA_UV, "occTexCoord");
292 SetAttributeName (theCtx, Graphic3d_TOA_COLOR, "occVertColor");
296 TCollection_AsciiString aLog;
297 FetchInfoLog (theCtx, aLog);
300 aLog = "Linker log is empty.";
302 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
303 GL_DEBUG_TYPE_ERROR_ARB,
305 GL_DEBUG_SEVERITY_HIGH_ARB,
306 TCollection_ExtendedString ("Failed to link program object! Linker log:\n") + aLog);
307 return Standard_False;
309 else if (theCtx->caps->glslWarnings)
311 TCollection_AsciiString aLog;
312 FetchInfoLog (theCtx, aLog);
314 && !aLog.IsEqual ("No errors.\n"))
316 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
317 GL_DEBUG_TYPE_PORTABILITY_ARB,
319 GL_DEBUG_SEVERITY_LOW_ARB,
320 TCollection_ExtendedString ("GLSL linker log:\n") + aLog);
324 return Standard_True;
327 // =======================================================================
328 // function : ~OpenGl_ShaderProgram
329 // purpose : Releases resources of shader program
330 // =======================================================================
331 OpenGl_ShaderProgram::~OpenGl_ShaderProgram()
336 // =======================================================================
337 // function : AttachShader
338 // purpose : Attaches shader object to the program object
339 // =======================================================================
340 Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context)& theCtx,
341 const Handle(OpenGl_ShaderObject)& theShader)
343 if (myProgramID == NO_PROGRAM || theShader.IsNull())
345 return Standard_False;
348 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
350 if (theShader == anIter.Value())
352 return Standard_False;
356 myShaderObjects.Append (theShader);
357 theCtx->core20fwd->glAttachShader (myProgramID, theShader->myShaderID);
358 return Standard_True;
361 // =======================================================================
362 // function : DetachShader
363 // purpose : Detaches shader object to the program object
364 // =======================================================================
365 Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context)& theCtx,
366 const Handle(OpenGl_ShaderObject)& theShader)
368 if (myProgramID == NO_PROGRAM
369 || theShader.IsNull())
371 return Standard_False;
374 OpenGl_ShaderList::Iterator anIter (myShaderObjects);
375 while (anIter.More())
377 if (theShader == anIter.Value())
379 myShaderObjects.Remove (anIter);
388 return Standard_False;
391 theCtx->core20fwd->glDetachShader (myProgramID, theShader->myShaderID);
392 return Standard_True;
395 // =======================================================================
397 // purpose : Links the program object
398 // =======================================================================
399 Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx)
401 if (myProgramID == NO_PROGRAM)
403 return Standard_False;
406 GLint aStatus = GL_FALSE;
407 theCtx->core20fwd->glLinkProgram (myProgramID);
408 theCtx->core20fwd->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
409 if (aStatus == GL_FALSE)
411 return Standard_False;
414 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
416 myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]);
418 return Standard_True;
421 // =======================================================================
422 // function : FetchInfoLog
423 // purpose : Fetches information log of the last link operation
424 // =======================================================================
425 Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
426 TCollection_AsciiString& theOutput)
428 if (myProgramID == NO_PROGRAM)
430 return Standard_False;
434 theCtx->core20fwd->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
437 GLchar* aLog = (GLchar*) alloca (aLength);
438 memset (aLog, 0, aLength);
439 theCtx->core20fwd->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
442 return Standard_True;
445 // =======================================================================
446 // function : ApplyVariables
447 // purpose : Fetches uniform variables from proxy shader program
448 // =======================================================================
449 Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Context)& theCtx)
451 if (myProxy.IsNull() || myProxy->Variables().IsEmpty())
453 return Standard_False;
456 for (Graphic3d_ShaderVariableList::Iterator anIter (myProxy->Variables()); anIter.More(); anIter.Next())
458 mySetterSelector.Set (theCtx, anIter.Value(), this);
461 myProxy->ClearVariables();
462 return Standard_True;
465 // =======================================================================
466 // function : ActiveState
467 // purpose : Returns index of last modification for specified state type
468 // =======================================================================
469 Standard_Size OpenGl_ShaderProgram::ActiveState (const OpenGl_UniformStateType theType) const
471 if (theType < MaxStateTypes)
473 return myCurrentState[theType];
478 // =======================================================================
479 // function : UpdateState
480 // purpose : Updates index of last modification for specified state type
481 // =======================================================================
482 void OpenGl_ShaderProgram::UpdateState (const OpenGl_UniformStateType theType,
483 const Standard_Size theIndex)
485 if (theType < MaxStateTypes)
487 myCurrentState[theType] = theIndex;
491 // =======================================================================
492 // function : GetUniformLocation
493 // purpose : Returns location (index) of the specific uniform variable
494 // =======================================================================
495 GLint OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& theCtx,
496 const GLchar* theName) const
498 return myProgramID != NO_PROGRAM
499 ? theCtx->core20fwd->glGetUniformLocation (myProgramID, theName)
503 // =======================================================================
504 // function : GetAttributeLocation
505 // purpose : Returns location (index) of the generic vertex attribute
506 // =======================================================================
507 GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)& theCtx,
508 const GLchar* theName) const
510 return myProgramID != NO_PROGRAM
511 ? theCtx->core20fwd->glGetAttribLocation (myProgramID, theName)
515 // =======================================================================
516 // function : GetStateLocation
517 // purpose : Returns location of the OCCT state uniform variable
518 // =======================================================================
519 GLint OpenGl_ShaderProgram::GetStateLocation (const GLuint theVariable) const
521 if (theVariable < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES)
523 return myStateLocations[theVariable];
525 return INVALID_LOCATION;
528 // =======================================================================
529 // function : GetUniform
530 // purpose : Returns the value of the integer uniform variable
531 // =======================================================================
532 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
533 const GLchar* theName,
534 OpenGl_Vec4i& theValue) const
536 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
539 // =======================================================================
540 // function : GetUniform
541 // purpose : Returns the value of the integer uniform variable
542 // =======================================================================
543 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
545 OpenGl_Vec4i& theValue) const
547 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
549 return Standard_False;
552 theCtx->core20fwd->glGetUniformiv (myProgramID, theLocation, theValue);
553 return Standard_True;
556 // =======================================================================
557 // function : GetUniform
558 // purpose : Returns the value of the floating-point uniform variable
559 // =======================================================================
560 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
561 const GLchar* theName,
562 OpenGl_Vec4& theValue) const
564 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
567 // =======================================================================
568 // function : GetUniform
569 // purpose : Returns the value of the floating-point uniform variable
570 // =======================================================================
571 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
573 OpenGl_Vec4& theValue) const
575 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
577 return Standard_False;
580 theCtx->core20fwd->glGetUniformfv (myProgramID, theLocation, theValue);
581 return Standard_True;
584 // =======================================================================
585 // function : GetAttribute
586 // purpose : Returns the integer vertex attribute
587 // =======================================================================
588 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
589 const GLchar* theName,
590 OpenGl_Vec4i& theValue) const
592 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
595 // =======================================================================
596 // function : GetAttribute
597 // purpose : Returns the integer vertex attribute
598 // =======================================================================
599 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
601 OpenGl_Vec4i& theValue) const
603 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
605 return Standard_False;
608 theCtx->core20fwd->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
609 return Standard_True;
612 // =======================================================================
613 // function : GetAttribute
614 // purpose : Returns the floating-point vertex attribute
615 // =======================================================================
616 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
617 const GLchar* theName,
618 OpenGl_Vec4& theValue) const
620 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
623 // =======================================================================
624 // function : GetAttribute
625 // purpose : Returns the floating-point vertex attribute
626 // =======================================================================
627 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
629 OpenGl_Vec4& theValue) const
631 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
633 return Standard_False;
636 theCtx->core20fwd->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
637 return Standard_True;
640 // =======================================================================
641 // function : SetAttributeName
643 // =======================================================================
644 Standard_Boolean OpenGl_ShaderProgram::SetAttributeName (const Handle(OpenGl_Context)& theCtx,
646 const GLchar* theName)
648 theCtx->core20fwd->glBindAttribLocation (myProgramID, theIndex, theName);
649 return Standard_True;
652 // =======================================================================
653 // function : SetAttribute
655 // =======================================================================
656 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
657 const GLchar* theName,
660 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
663 // =======================================================================
664 // function : SetAttribute
666 // =======================================================================
667 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
671 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
673 return Standard_False;
676 theCtx->core20fwd->glVertexAttrib1f (theIndex, theValue);
677 return Standard_True;
680 // =======================================================================
681 // function : SetAttribute
683 // =======================================================================
684 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
685 const GLchar* theName,
686 const OpenGl_Vec2& theValue)
688 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
691 // =======================================================================
692 // function : SetAttribute
694 // =======================================================================
695 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
697 const OpenGl_Vec2& theValue)
699 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
701 return Standard_False;
704 theCtx->core20fwd->glVertexAttrib2fv (theIndex, theValue);
705 return Standard_True;
708 // =======================================================================
709 // function : SetAttribute
711 // =======================================================================
712 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
713 const GLchar* theName,
714 const OpenGl_Vec3& theValue)
716 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
719 // =======================================================================
720 // function : SetAttribute
722 // =======================================================================
723 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
725 const OpenGl_Vec3& theValue)
727 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
729 return Standard_False;
732 theCtx->core20fwd->glVertexAttrib3fv (theIndex, theValue);
733 return Standard_True;
736 // =======================================================================
737 // function : SetAttribute
739 // =======================================================================
740 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
741 const GLchar* theName,
742 const OpenGl_Vec4& theValue)
744 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
747 // =======================================================================
748 // function : SetAttribute
750 // =======================================================================
751 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
753 const OpenGl_Vec4& theValue)
755 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
757 return Standard_False;
760 theCtx->core20fwd->glVertexAttrib4fv (theIndex, theValue);
761 return Standard_True;
764 // =======================================================================
765 // function : SetUniform
766 // purpose : Specifies the value of the integer uniform variable
767 // =======================================================================
768 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
769 const GLchar* theName,
772 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
775 // =======================================================================
776 // function : SetUniform
777 // purpose : Specifies the value of the integer uniform variable
778 // =======================================================================
779 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
783 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
785 return Standard_False;
788 theCtx->core20fwd->glUniform1i (theLocation, theValue);
789 return Standard_True;
792 // =======================================================================
793 // function : SetUniform
794 // purpose : Specifies the value of the 64-bit unsigned uniform variable
795 // =======================================================================
796 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
797 const GLchar* theName,
800 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
803 // =======================================================================
804 // function : SetUniform
805 // purpose : Specifies the value of the 64-bit unsigned uniform variable
806 // =======================================================================
807 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
811 if (theCtx->arbTexBindless == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
813 return Standard_False;
816 #if !defined(GL_ES_VERSION_2_0)
817 theCtx->arbTexBindless->glUniformHandleui64ARB (theLocation, theValue);
820 return Standard_True;
823 // =======================================================================
824 // function : SetUniform
825 // purpose : Specifies the value of the 64-bit unsigned uniform array
826 // =======================================================================
827 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
828 const GLchar* theName,
829 const GLsizei theCount,
830 const GLuint64* theValue)
832 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theCount, theValue);
835 // =======================================================================
836 // function : SetUniform
837 // purpose : Specifies the value of the 64-bit unsigned uniform array
838 // =======================================================================
839 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
841 const GLsizei theCount,
842 const GLuint64* theValue)
844 if (theCtx->arbTexBindless == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
846 return Standard_False;
849 #if !defined(GL_ES_VERSION_2_0)
850 theCtx->arbTexBindless->glUniformHandleui64vARB (theLocation, theCount, theValue);
853 return Standard_True;
856 // =======================================================================
857 // function : SetUniform
858 // purpose : Specifies the value of the floating-point uniform variable
859 // =======================================================================
860 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
861 const GLchar* theName,
864 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
867 // =======================================================================
868 // function : SetUniform
869 // purpose : Specifies the value of the floating-point uniform variable
870 // =======================================================================
871 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
875 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
877 return Standard_False;
880 theCtx->core20fwd->glUniform1f (theLocation, theValue);
881 return Standard_True;
884 // =======================================================================
885 // function : SetUniform
886 // purpose : Specifies the value of the integer uniform 2D vector
887 // =======================================================================
888 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
889 const GLchar* theName,
890 const OpenGl_Vec2i& theValue)
892 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
895 // =======================================================================
896 // function : SetUniform
897 // purpose : Specifies the value of the integer uniform 2D vector
898 // =======================================================================
899 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
901 const OpenGl_Vec2i& theValue)
903 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
905 return Standard_False;
908 theCtx->core20fwd->glUniform2iv (theLocation, 1, theValue);
909 return Standard_True;
912 // =======================================================================
913 // function : SetUniform
914 // purpose : Specifies the value of the integer uniform 3D vector
915 // =======================================================================
916 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
917 const GLchar* theName,
918 const OpenGl_Vec3i& theValue)
920 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
923 // =======================================================================
924 // function : SetUniform
925 // purpose : Specifies the value of the integer uniform 3D vector
926 // =======================================================================
927 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
929 const OpenGl_Vec3i& theValue)
931 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
933 return Standard_False;
936 theCtx->core20fwd->glUniform3iv (theLocation, 1, theValue);
937 return Standard_True;
940 // =======================================================================
941 // function : SetUniform
942 // purpose : Specifies the value of the integer uniform 4D vector
943 // =======================================================================
944 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
945 const GLchar* theName,
946 const OpenGl_Vec4i& theValue)
948 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
951 // =======================================================================
952 // function : SetUniform
953 // purpose : Specifies the value of the integer uniform 4D vector
954 // =======================================================================
955 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
957 const OpenGl_Vec4i& theValue)
959 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
961 return Standard_False;
964 theCtx->core20fwd->glUniform4iv (theLocation, 1, theValue);
965 return Standard_True;
968 // =======================================================================
969 // function : SetUniform
970 // purpose : Specifies the value of the floating-point uniform 2D vector
971 // =======================================================================
972 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
973 const GLchar* theName,
974 const OpenGl_Vec2& theValue)
976 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
979 // =======================================================================
980 // function : SetUniform
981 // purpose : Specifies the value of the floating-point uniform 2D vector
982 // =======================================================================
983 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
985 const OpenGl_Vec2& theValue)
987 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
989 return Standard_False;
992 theCtx->core20fwd->glUniform2fv (theLocation, 1, theValue);
993 return Standard_True;
996 // =======================================================================
997 // function : SetUniform
998 // purpose : Specifies the value of the floating-point uniform 3D vector
999 // =======================================================================
1000 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1001 const GLchar* theName,
1002 const OpenGl_Vec3& theValue)
1004 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1007 // =======================================================================
1008 // function : SetUniform
1009 // purpose : Specifies the value of the floating-point uniform 3D vector
1010 // =======================================================================
1011 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1013 const OpenGl_Vec3& theValue)
1015 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1017 return Standard_False;
1020 theCtx->core20fwd->glUniform3fv (theLocation, 1, theValue);
1021 return Standard_True;
1024 // =======================================================================
1025 // function : SetUniform
1026 // purpose : Specifies the value of the floating-point uniform 4D vector
1027 // =======================================================================
1028 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1029 const GLchar* theName,
1030 const OpenGl_Vec4& theValue)
1032 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1035 // =======================================================================
1036 // function : SetUniform
1037 // purpose : Specifies the value of the floating-point uniform 4D vector
1038 // =======================================================================
1039 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1041 const OpenGl_Vec4& theValue)
1043 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1045 return Standard_False;
1048 theCtx->core20fwd->glUniform4fv (theLocation, 1, theValue);
1049 return Standard_True;
1052 // =======================================================================
1053 // function : SetUniform
1054 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1055 // =======================================================================
1056 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1057 const GLchar* theName,
1058 const OpenGl_Mat4& theValue,
1059 GLboolean theTranspose)
1061 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1064 // =======================================================================
1065 // function : SetUniform
1066 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1067 // =======================================================================
1068 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1070 const OpenGl_Mat4& theValue,
1071 GLboolean theTranspose)
1073 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1075 return Standard_False;
1078 theCtx->core20fwd->glUniformMatrix4fv (theLocation, 1, GL_FALSE, theTranspose ? theValue.Transposed() : theValue);
1079 return Standard_True;
1082 // =======================================================================
1083 // function : SetUniform
1084 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1085 // =======================================================================
1086 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1087 const GLchar* theName,
1088 const OpenGl_Matrix& theValue,
1089 GLboolean theTranspose)
1091 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1094 // =======================================================================
1095 // function : SetUniform
1096 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1097 // =======================================================================
1098 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1100 const OpenGl_Matrix& theValue,
1101 GLboolean theTranspose)
1103 return SetUniform (theCtx, theLocation, OpenGl_Mat4::Map (*theValue.mat), theTranspose);
1106 // =======================================================================
1107 // function : SetUniform
1108 // purpose : Specifies the value of the float uniform array
1109 // =======================================================================
1110 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1113 const Standard_ShortReal* theData)
1115 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1117 return Standard_False;
1120 theCtx->core20fwd->glUniform1fv (theLocation, theCount, theData);
1121 return Standard_True;
1124 // =======================================================================
1125 // function : SetUniform
1126 // purpose : Specifies the value of the float2 uniform array
1127 // =======================================================================
1128 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1131 const OpenGl_Vec2* theData)
1133 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1135 return Standard_False;
1138 theCtx->core20fwd->glUniform2fv (theLocation, theCount, theData[0].GetData());
1139 return Standard_True;
1142 // =======================================================================
1143 // function : SetUniform
1144 // purpose : Specifies the value of the float3 uniform array
1145 // =======================================================================
1146 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1149 const OpenGl_Vec3* theData)
1151 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1153 return Standard_False;
1156 theCtx->core20fwd->glUniform3fv (theLocation, theCount, theData[0].GetData());
1157 return Standard_True;
1160 // =======================================================================
1161 // function : SetUniform
1162 // purpose : Specifies the value of the float4 uniform array
1163 // =======================================================================
1164 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1167 const OpenGl_Vec4* theData)
1169 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1171 return Standard_False;
1174 theCtx->core20fwd->glUniform4fv (theLocation, theCount, theData[0].GetData());
1175 return Standard_True;
1178 // =======================================================================
1179 // function : SetUniform
1180 // purpose : Specifies the value of the integer uniform array
1181 // =======================================================================
1182 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1185 const Standard_Integer* theData)
1187 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1189 return Standard_False;
1192 theCtx->core20fwd->glUniform1iv (theLocation, theCount, theData);
1193 return Standard_True;
1196 // =======================================================================
1197 // function : SetUniform
1198 // purpose : Specifies the value of the int2 uniform array
1199 // =======================================================================
1200 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1203 const OpenGl_Vec2i* theData)
1205 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1207 return Standard_False;
1210 theCtx->core20fwd->glUniform2iv (theLocation, theCount, theData[0].GetData());
1211 return Standard_True;
1214 // =======================================================================
1215 // function : SetUniform
1216 // purpose : Specifies the value of the int3 uniform array
1217 // =======================================================================
1218 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1221 const OpenGl_Vec3i* theData)
1223 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1225 return Standard_False;
1228 theCtx->core20fwd->glUniform3iv (theLocation, theCount, theData[0].GetData());
1229 return Standard_True;
1232 // =======================================================================
1233 // function : SetUniform
1234 // purpose : Specifies the value of the int4 uniform array
1235 // =======================================================================
1236 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1239 const OpenGl_Vec4i* theData)
1241 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1243 return Standard_False;
1246 theCtx->core20fwd->glUniform4iv (theLocation, theCount, theData[0].GetData());
1247 return Standard_True;
1250 // =======================================================================
1251 // function : SetSampler
1252 // purpose : Specifies the value of the sampler uniform variable
1253 // =======================================================================
1254 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1255 const GLchar* theName,
1256 const GLenum theTextureUnit)
1258 return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit);
1261 // =======================================================================
1262 // function : SetSampler
1263 // purpose : Specifies the value of the sampler uniform variable
1264 // =======================================================================
1265 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1267 const GLenum theTextureUnit)
1269 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1271 return Standard_False;
1274 theCtx->core20fwd->glUniform1i (theLocation, theTextureUnit);
1275 return Standard_True;
1278 // =======================================================================
1279 // function : Create
1280 // purpose : Creates new empty shader program of specified type
1281 // =======================================================================
1282 Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx)
1284 if (myProgramID == NO_PROGRAM
1285 && theCtx->core20fwd != NULL)
1287 myProgramID = theCtx->core20fwd->glCreateProgram();
1290 return myProgramID != NO_PROGRAM;
1293 // =======================================================================
1294 // function : Release
1295 // purpose : Destroys shader program
1296 // =======================================================================
1297 void OpenGl_ShaderProgram::Release (OpenGl_Context* theCtx)
1299 if (myProgramID == NO_PROGRAM)
1304 Standard_ASSERT_RETURN (theCtx != NULL,
1305 "OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...",);
1307 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
1309 if (!anIter.Value().IsNull())
1311 anIter.ChangeValue()->Release (theCtx);
1312 anIter.ChangeValue().Nullify();
1316 if (theCtx->core20fwd != NULL
1317 && theCtx->IsValid())
1319 theCtx->core20fwd->glDeleteProgram (myProgramID);
1322 myProgramID = NO_PROGRAM;