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 #include <OpenGl_GlCore32.hxx>
31 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderProgram,OpenGl_Resource)
33 OpenGl_VariableSetterSelector OpenGl_ShaderProgram::mySetterSelector = OpenGl_VariableSetterSelector();
35 // Declare OCCT-specific OpenGL/GLSL shader variables
36 Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] =
38 "occModelWorldMatrix", // OpenGl_OCC_MODEL_WORLD_MATRIX
39 "occWorldViewMatrix", // OpenGl_OCC_WORLD_VIEW_MATRIX
40 "occProjectionMatrix", // OpenGl_OCC_PROJECTION_MATRIX
41 "occModelWorldMatrixInverse", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE
42 "occWorldViewMatrixInverse", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE
43 "occProjectionMatrixInverse", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE
44 "occModelWorldMatrixTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE
45 "occWorldViewMatrixTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE
46 "occProjectionMatrixTranspose", // OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE
47 "occModelWorldMatrixInverseTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE
48 "occWorldViewMatrixInverseTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE
49 "occProjectionMatrixInverseTranspose", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE
51 "occClipPlaneEquations", // OpenGl_OCC_CLIP_PLANE_EQUATIONS
52 "occClipPlaneSpaces", // OpenGl_OCC_CLIP_PLANE_SPACES
53 "occClipPlaneCount", // OpenGl_OCC_CLIP_PLANE_COUNT
55 "occLightSourcesCount", // OpenGl_OCC_LIGHT_SOURCE_COUNT
56 "occLightSourcesTypes", // OpenGl_OCC_LIGHT_SOURCE_TYPES
57 "occLightSources", // OpenGl_OCC_LIGHT_SOURCE_PARAMS
58 "occLightAmbient", // OpenGl_OCC_LIGHT_AMBIENT
60 "occActiveSampler", // OpenGl_OCCT_ACTIVE_SAMPLER
61 "occTextureEnable", // OpenGl_OCCT_TEXTURE_ENABLE
62 "occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE
63 "occFrontMaterial", // OpenGl_OCCT_FRONT_MATERIAL
64 "occBackMaterial", // OpenGl_OCCT_BACK_MATERIAL
65 "occColor", // OpenGl_OCCT_COLOR
67 "occTexTrsf2d", // OpenGl_OCCT_TEXTURE_TRSF2D
68 "occPointSize" // OpenGl_OCCT_POINT_SIZE
72 // =======================================================================
73 // function : OpenGl_VariableSetterSelector
74 // purpose : Creates new variable setter selector
75 // =======================================================================
76 OpenGl_VariableSetterSelector::OpenGl_VariableSetterSelector()
78 // Note: Add new variable setters here
79 mySetterList = OpenGl_HashMapInitializer::CreateListOf<size_t, OpenGl_SetterInterface*>
80 (Graphic3d_UniformValueTypeID<int>::ID, new OpenGl_VariableSetter<int>())
81 (Graphic3d_UniformValueTypeID<float>::ID, new OpenGl_VariableSetter<float>())
82 (Graphic3d_UniformValueTypeID<OpenGl_Vec2>::ID, new OpenGl_VariableSetter<OpenGl_Vec2>())
83 (Graphic3d_UniformValueTypeID<OpenGl_Vec3>::ID, new OpenGl_VariableSetter<OpenGl_Vec3>())
84 (Graphic3d_UniformValueTypeID<OpenGl_Vec4>::ID, new OpenGl_VariableSetter<OpenGl_Vec4>())
85 (Graphic3d_UniformValueTypeID<OpenGl_Vec2i>::ID, new OpenGl_VariableSetter<OpenGl_Vec2i>())
86 (Graphic3d_UniformValueTypeID<OpenGl_Vec3i>::ID, new OpenGl_VariableSetter<OpenGl_Vec3i>())
87 (Graphic3d_UniformValueTypeID<OpenGl_Vec4i>::ID, new OpenGl_VariableSetter<OpenGl_Vec4i>());
90 // =======================================================================
91 // function : ~OpenGl_VariableSetterSelector
92 // purpose : Releases memory resources of variable setter selector
93 // =======================================================================
94 OpenGl_VariableSetterSelector::~OpenGl_VariableSetterSelector()
96 for (OpenGl_SetterList::Iterator anIt (mySetterList); anIt.More(); anIt.Next())
101 mySetterList.Clear();
104 // =======================================================================
106 // purpose : Sets generic variable to specified shader program
107 // =======================================================================
108 void OpenGl_VariableSetterSelector::Set (const Handle(OpenGl_Context)& theCtx,
109 const Handle(Graphic3d_ShaderVariable)& theVariable,
110 OpenGl_ShaderProgram* theProgram) const
112 Standard_ASSERT_RETURN (mySetterList.IsBound (theVariable->Value()->TypeID()),
113 "The type of user-defined uniform variable is not supported...", );
115 mySetterList.Find (theVariable->Value()->TypeID())->Set (theCtx, theVariable, theProgram);
118 // =======================================================================
119 // function : OpenGl_ShaderProgram
120 // purpose : Creates uninitialized shader program
121 // =======================================================================
122 OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy)
123 : myProgramID (NO_PROGRAM),
127 memset (myCurrentState, 0, sizeof (myCurrentState));
128 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
130 myStateLocations[aVar] = INVALID_LOCATION;
134 // =======================================================================
135 // function : Initialize
136 // purpose : Initializes program object with the list of shader objects
137 // =======================================================================
138 Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& theCtx,
139 const Graphic3d_ShaderObjectList& theShaders)
141 if (theCtx.IsNull() || !Create (theCtx))
143 return Standard_False;
146 OSD_File aDeclFile (Graphic3d_ShaderProgram::ShadersFolder() + "/Declarations.glsl");
147 OSD_File aDeclImplFile (Graphic3d_ShaderProgram::ShadersFolder() + "/DeclarationsImpl.glsl");
148 if (!aDeclFile.Exists()
149 || !aDeclImplFile.Exists())
151 const TCollection_ExtendedString aMsg = "Error! Failed to load OCCT shader declarations file";
152 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
155 GL_DEBUG_SEVERITY_HIGH,
157 return Standard_False;
160 TCollection_AsciiString aHeader = !myProxy.IsNull() && !myProxy->Header().IsEmpty()
161 ? (myProxy->Header() + "\n")
162 : TCollection_AsciiString();
164 TCollection_AsciiString aDeclarations;
165 aDeclFile.Open (OSD_ReadOnly, OSD_Protection());
166 aDeclFile.Read (aDeclarations, (int)aDeclFile.Size());
169 TCollection_AsciiString aDeclImpl;
170 aDeclImplFile.Open (OSD_ReadOnly, OSD_Protection());
171 aDeclImplFile.Read (aDeclImpl, (int)aDeclImplFile.Size());
172 aDeclImplFile.Close();
173 aDeclarations += aDeclImpl;
175 for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders);
176 anIter.More(); anIter.Next())
178 if (!anIter.Value()->IsDone())
180 const TCollection_ExtendedString aMsg = "Error! Failed to get shader source";
181 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
184 GL_DEBUG_SEVERITY_HIGH,
186 return Standard_False;
189 Handle(OpenGl_ShaderObject) aShader;
191 // Note: Add support of other shader types here
192 switch (anIter.Value()->Type())
194 case Graphic3d_TOS_VERTEX:
195 aShader = new OpenGl_ShaderObject (GL_VERTEX_SHADER);
197 case Graphic3d_TOS_FRAGMENT:
198 aShader = new OpenGl_ShaderObject (GL_FRAGMENT_SHADER);
202 // Is unsupported shader type?
203 if (aShader.IsNull())
205 TCollection_ExtendedString aMsg = "Error! Unsupported shader type";
206 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
209 GL_DEBUG_SEVERITY_HIGH,
211 return Standard_False;
214 if (!aShader->Create (theCtx))
216 aShader->Release (theCtx.operator->());
217 return Standard_False;
220 TCollection_AsciiString aSource = aDeclarations + anIter.Value()->Source();
221 switch (anIter.Value()->Type())
223 case Graphic3d_TOS_VERTEX:
225 aSource = aHeader + TCollection_AsciiString ("#define VERTEX_SHADER\n") + aSource;
228 case Graphic3d_TOS_FRAGMENT:
230 #if defined(GL_ES_VERSION_2_0)
231 TCollection_AsciiString aPrefix (theCtx->hasHighp
232 ? "precision highp float;\n"
233 "precision highp int;\n"
234 : "precision mediump float;\n"
235 "precision mediump int;\n");
236 aSource = aHeader + aPrefix + aSource;
238 aSource = aHeader + aSource;
244 if (!aShader->LoadSource (theCtx, aSource))
246 const TCollection_ExtendedString aMsg = "Error! Failed to set shader source";
247 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
250 GL_DEBUG_SEVERITY_HIGH,
252 aShader->Release (theCtx.operator->());
253 return Standard_False;
256 if (!aShader->Compile (theCtx))
258 TCollection_AsciiString aLog;
259 aShader->FetchInfoLog (theCtx, aLog);
262 aLog = "Compilation log is empty.";
264 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
267 GL_DEBUG_SEVERITY_HIGH,
268 TCollection_ExtendedString ("Failed to compile shader object. Compilation log:\n") + aLog);
269 aShader->Release (theCtx.operator->());
270 return Standard_False;
272 else if (theCtx->caps->glslWarnings)
274 TCollection_AsciiString aLog;
275 aShader->FetchInfoLog (theCtx, aLog);
277 && !aLog.IsEqual ("No errors.\n"))
279 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
280 GL_DEBUG_TYPE_PORTABILITY,
282 GL_DEBUG_SEVERITY_LOW,
283 TCollection_ExtendedString ("Shader compilation log:\n") + aLog);
287 if (!AttachShader (theCtx, aShader))
289 aShader->Release (theCtx.operator->());
290 return Standard_False;
294 // bind locations for pre-defined Vertex Attributes
295 SetAttributeName (theCtx, Graphic3d_TOA_POS, "occVertex");
296 SetAttributeName (theCtx, Graphic3d_TOA_NORM, "occNormal");
297 SetAttributeName (theCtx, Graphic3d_TOA_UV, "occTexCoord");
298 SetAttributeName (theCtx, Graphic3d_TOA_COLOR, "occVertColor");
302 TCollection_AsciiString aLog;
303 FetchInfoLog (theCtx, aLog);
306 aLog = "Linker log is empty.";
308 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
311 GL_DEBUG_SEVERITY_HIGH,
312 TCollection_ExtendedString ("Failed to link program object! Linker log:\n") + aLog);
313 return Standard_False;
315 else if (theCtx->caps->glslWarnings)
317 TCollection_AsciiString aLog;
318 FetchInfoLog (theCtx, aLog);
320 && !aLog.IsEqual ("No errors.\n"))
322 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
323 GL_DEBUG_TYPE_PORTABILITY,
325 GL_DEBUG_SEVERITY_LOW,
326 TCollection_ExtendedString ("GLSL linker log:\n") + aLog);
330 return Standard_True;
333 // =======================================================================
334 // function : ~OpenGl_ShaderProgram
335 // purpose : Releases resources of shader program
336 // =======================================================================
337 OpenGl_ShaderProgram::~OpenGl_ShaderProgram()
342 // =======================================================================
343 // function : AttachShader
344 // purpose : Attaches shader object to the program object
345 // =======================================================================
346 Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context)& theCtx,
347 const Handle(OpenGl_ShaderObject)& theShader)
349 if (myProgramID == NO_PROGRAM || theShader.IsNull())
351 return Standard_False;
354 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
356 if (theShader == anIter.Value())
358 return Standard_False;
362 myShaderObjects.Append (theShader);
363 theCtx->core20fwd->glAttachShader (myProgramID, theShader->myShaderID);
364 return Standard_True;
367 // =======================================================================
368 // function : DetachShader
369 // purpose : Detaches shader object to the program object
370 // =======================================================================
371 Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context)& theCtx,
372 const Handle(OpenGl_ShaderObject)& theShader)
374 if (myProgramID == NO_PROGRAM
375 || theShader.IsNull())
377 return Standard_False;
380 OpenGl_ShaderList::Iterator anIter (myShaderObjects);
381 while (anIter.More())
383 if (theShader == anIter.Value())
385 myShaderObjects.Remove (anIter);
394 return Standard_False;
397 theCtx->core20fwd->glDetachShader (myProgramID, theShader->myShaderID);
398 return Standard_True;
401 // =======================================================================
403 // purpose : Links the program object
404 // =======================================================================
405 Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx)
407 if (myProgramID == NO_PROGRAM)
409 return Standard_False;
412 GLint aStatus = GL_FALSE;
413 theCtx->core20fwd->glLinkProgram (myProgramID);
414 theCtx->core20fwd->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
415 if (aStatus == GL_FALSE)
417 return Standard_False;
420 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
422 myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]);
424 return Standard_True;
427 // =======================================================================
428 // function : FetchInfoLog
429 // purpose : Fetches information log of the last link operation
430 // =======================================================================
431 Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
432 TCollection_AsciiString& theOutput)
434 if (myProgramID == NO_PROGRAM)
436 return Standard_False;
440 theCtx->core20fwd->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
443 GLchar* aLog = (GLchar*) alloca (aLength);
444 memset (aLog, 0, aLength);
445 theCtx->core20fwd->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
448 return Standard_True;
451 // =======================================================================
452 // function : ApplyVariables
453 // purpose : Fetches uniform variables from proxy shader program
454 // =======================================================================
455 Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Context)& theCtx)
457 if (myProxy.IsNull() || myProxy->Variables().IsEmpty())
459 return Standard_False;
462 for (Graphic3d_ShaderVariableList::Iterator anIter (myProxy->Variables()); anIter.More(); anIter.Next())
464 mySetterSelector.Set (theCtx, anIter.Value(), this);
467 myProxy->ClearVariables();
468 return Standard_True;
471 // =======================================================================
472 // function : ActiveState
473 // purpose : Returns index of last modification for specified state type
474 // =======================================================================
475 Standard_Size OpenGl_ShaderProgram::ActiveState (const OpenGl_UniformStateType theType) const
477 if (theType < MaxStateTypes)
479 return myCurrentState[theType];
484 // =======================================================================
485 // function : UpdateState
486 // purpose : Updates index of last modification for specified state type
487 // =======================================================================
488 void OpenGl_ShaderProgram::UpdateState (const OpenGl_UniformStateType theType,
489 const Standard_Size theIndex)
491 if (theType < MaxStateTypes)
493 myCurrentState[theType] = theIndex;
497 // =======================================================================
498 // function : GetUniformLocation
499 // purpose : Returns location (index) of the specific uniform variable
500 // =======================================================================
501 GLint OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& theCtx,
502 const GLchar* theName) const
504 return myProgramID != NO_PROGRAM
505 ? theCtx->core20fwd->glGetUniformLocation (myProgramID, theName)
509 // =======================================================================
510 // function : GetAttributeLocation
511 // purpose : Returns location (index) of the generic vertex attribute
512 // =======================================================================
513 GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)& theCtx,
514 const GLchar* theName) const
516 return myProgramID != NO_PROGRAM
517 ? theCtx->core20fwd->glGetAttribLocation (myProgramID, theName)
521 // =======================================================================
522 // function : GetStateLocation
523 // purpose : Returns location of the OCCT state uniform variable
524 // =======================================================================
525 GLint OpenGl_ShaderProgram::GetStateLocation (const GLuint theVariable) const
527 if (theVariable < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES)
529 return myStateLocations[theVariable];
531 return INVALID_LOCATION;
534 // =======================================================================
535 // function : GetUniform
536 // purpose : Returns the value of the integer uniform variable
537 // =======================================================================
538 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
539 const GLchar* theName,
540 OpenGl_Vec4i& theValue) const
542 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
545 // =======================================================================
546 // function : GetUniform
547 // purpose : Returns the value of the integer uniform variable
548 // =======================================================================
549 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
551 OpenGl_Vec4i& theValue) const
553 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
555 return Standard_False;
558 theCtx->core20fwd->glGetUniformiv (myProgramID, theLocation, theValue);
559 return Standard_True;
562 // =======================================================================
563 // function : GetUniform
564 // purpose : Returns the value of the floating-point uniform variable
565 // =======================================================================
566 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
567 const GLchar* theName,
568 OpenGl_Vec4& theValue) const
570 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
573 // =======================================================================
574 // function : GetUniform
575 // purpose : Returns the value of the floating-point uniform variable
576 // =======================================================================
577 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
579 OpenGl_Vec4& theValue) const
581 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
583 return Standard_False;
586 theCtx->core20fwd->glGetUniformfv (myProgramID, theLocation, theValue);
587 return Standard_True;
590 // =======================================================================
591 // function : GetAttribute
592 // purpose : Returns the integer vertex attribute
593 // =======================================================================
594 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
595 const GLchar* theName,
596 OpenGl_Vec4i& theValue) const
598 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
601 // =======================================================================
602 // function : GetAttribute
603 // purpose : Returns the integer vertex attribute
604 // =======================================================================
605 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
607 OpenGl_Vec4i& theValue) const
609 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
611 return Standard_False;
614 theCtx->core20fwd->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
615 return Standard_True;
618 // =======================================================================
619 // function : GetAttribute
620 // purpose : Returns the floating-point vertex attribute
621 // =======================================================================
622 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
623 const GLchar* theName,
624 OpenGl_Vec4& theValue) const
626 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
629 // =======================================================================
630 // function : GetAttribute
631 // purpose : Returns the floating-point vertex attribute
632 // =======================================================================
633 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
635 OpenGl_Vec4& theValue) const
637 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
639 return Standard_False;
642 theCtx->core20fwd->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
643 return Standard_True;
646 // =======================================================================
647 // function : SetAttributeName
649 // =======================================================================
650 Standard_Boolean OpenGl_ShaderProgram::SetAttributeName (const Handle(OpenGl_Context)& theCtx,
652 const GLchar* theName)
654 theCtx->core20fwd->glBindAttribLocation (myProgramID, theIndex, theName);
655 return Standard_True;
658 // =======================================================================
659 // function : SetAttribute
661 // =======================================================================
662 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
663 const GLchar* theName,
666 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
669 // =======================================================================
670 // function : SetAttribute
672 // =======================================================================
673 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
677 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
679 return Standard_False;
682 theCtx->core20fwd->glVertexAttrib1f (theIndex, theValue);
683 return Standard_True;
686 // =======================================================================
687 // function : SetAttribute
689 // =======================================================================
690 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
691 const GLchar* theName,
692 const OpenGl_Vec2& theValue)
694 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
697 // =======================================================================
698 // function : SetAttribute
700 // =======================================================================
701 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
703 const OpenGl_Vec2& theValue)
705 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
707 return Standard_False;
710 theCtx->core20fwd->glVertexAttrib2fv (theIndex, theValue);
711 return Standard_True;
714 // =======================================================================
715 // function : SetAttribute
717 // =======================================================================
718 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
719 const GLchar* theName,
720 const OpenGl_Vec3& theValue)
722 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
725 // =======================================================================
726 // function : SetAttribute
728 // =======================================================================
729 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
731 const OpenGl_Vec3& theValue)
733 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
735 return Standard_False;
738 theCtx->core20fwd->glVertexAttrib3fv (theIndex, theValue);
739 return Standard_True;
742 // =======================================================================
743 // function : SetAttribute
745 // =======================================================================
746 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
747 const GLchar* theName,
748 const OpenGl_Vec4& theValue)
750 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
753 // =======================================================================
754 // function : SetAttribute
756 // =======================================================================
757 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
759 const OpenGl_Vec4& theValue)
761 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
763 return Standard_False;
766 theCtx->core20fwd->glVertexAttrib4fv (theIndex, theValue);
767 return Standard_True;
770 // =======================================================================
771 // function : SetUniform
772 // purpose : Specifies the value of the integer uniform variable
773 // =======================================================================
774 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
775 const GLchar* theName,
778 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
781 // =======================================================================
782 // function : SetUniform
783 // purpose : Specifies the value of the integer uniform variable
784 // =======================================================================
785 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
789 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
791 return Standard_False;
794 theCtx->core20fwd->glUniform1i (theLocation, theValue);
795 return Standard_True;
798 // =======================================================================
799 // function : SetUniform
801 // =======================================================================
802 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
803 const GLchar* theName,
804 const OpenGl_Vec2u& theValue)
806 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
809 // =======================================================================
810 // function : SetUniform
812 // =======================================================================
813 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
815 const OpenGl_Vec2u& theValue)
817 if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
819 return Standard_False;
822 #if !defined(GL_ES_VERSION_2_0)
823 theCtx->core32->glUniform2uiv (theLocation, 1, theValue.GetData());
826 return Standard_True;
829 // =======================================================================
830 // function : SetUniform
832 // =======================================================================
833 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
834 const GLchar* theName,
835 const GLsizei theCount,
836 const OpenGl_Vec2u* theValue)
838 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theCount, theValue);
841 // =======================================================================
842 // function : SetUniform
844 // =======================================================================
845 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
847 const GLsizei theCount,
848 const OpenGl_Vec2u* theValue)
850 if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
852 return Standard_False;
855 #if !defined(GL_ES_VERSION_2_0)
856 theCtx->core32->glUniform2uiv (theLocation, theCount, theValue->GetData());
859 return Standard_True;
862 // =======================================================================
863 // function : SetUniform
864 // purpose : Specifies the value of the floating-point uniform variable
865 // =======================================================================
866 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
867 const GLchar* theName,
870 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
873 // =======================================================================
874 // function : SetUniform
875 // purpose : Specifies the value of the floating-point uniform variable
876 // =======================================================================
877 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
881 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
883 return Standard_False;
886 theCtx->core20fwd->glUniform1f (theLocation, theValue);
887 return Standard_True;
890 // =======================================================================
891 // function : SetUniform
892 // purpose : Specifies the value of the integer uniform 2D vector
893 // =======================================================================
894 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
895 const GLchar* theName,
896 const OpenGl_Vec2i& theValue)
898 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
901 // =======================================================================
902 // function : SetUniform
903 // purpose : Specifies the value of the integer uniform 2D vector
904 // =======================================================================
905 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
907 const OpenGl_Vec2i& theValue)
909 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
911 return Standard_False;
914 theCtx->core20fwd->glUniform2iv (theLocation, 1, theValue);
915 return Standard_True;
918 // =======================================================================
919 // function : SetUniform
920 // purpose : Specifies the value of the integer uniform 3D vector
921 // =======================================================================
922 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
923 const GLchar* theName,
924 const OpenGl_Vec3i& theValue)
926 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
929 // =======================================================================
930 // function : SetUniform
931 // purpose : Specifies the value of the integer uniform 3D vector
932 // =======================================================================
933 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
935 const OpenGl_Vec3i& theValue)
937 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
939 return Standard_False;
942 theCtx->core20fwd->glUniform3iv (theLocation, 1, theValue);
943 return Standard_True;
946 // =======================================================================
947 // function : SetUniform
948 // purpose : Specifies the value of the integer uniform 4D vector
949 // =======================================================================
950 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
951 const GLchar* theName,
952 const OpenGl_Vec4i& theValue)
954 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
957 // =======================================================================
958 // function : SetUniform
959 // purpose : Specifies the value of the integer uniform 4D vector
960 // =======================================================================
961 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
963 const OpenGl_Vec4i& theValue)
965 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
967 return Standard_False;
970 theCtx->core20fwd->glUniform4iv (theLocation, 1, theValue);
971 return Standard_True;
974 // =======================================================================
975 // function : SetUniform
976 // purpose : Specifies the value of the floating-point uniform 2D vector
977 // =======================================================================
978 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
979 const GLchar* theName,
980 const OpenGl_Vec2& theValue)
982 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
985 // =======================================================================
986 // function : SetUniform
987 // purpose : Specifies the value of the floating-point uniform 2D vector
988 // =======================================================================
989 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
991 const OpenGl_Vec2& theValue)
993 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
995 return Standard_False;
998 theCtx->core20fwd->glUniform2fv (theLocation, 1, theValue);
999 return Standard_True;
1002 // =======================================================================
1003 // function : SetUniform
1004 // purpose : Specifies the value of the floating-point uniform 3D vector
1005 // =======================================================================
1006 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1007 const GLchar* theName,
1008 const OpenGl_Vec3& theValue)
1010 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1013 // =======================================================================
1014 // function : SetUniform
1015 // purpose : Specifies the value of the floating-point uniform 3D vector
1016 // =======================================================================
1017 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1019 const OpenGl_Vec3& theValue)
1021 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1023 return Standard_False;
1026 theCtx->core20fwd->glUniform3fv (theLocation, 1, theValue);
1027 return Standard_True;
1030 // =======================================================================
1031 // function : SetUniform
1032 // purpose : Specifies the value of the floating-point uniform 4D vector
1033 // =======================================================================
1034 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1035 const GLchar* theName,
1036 const OpenGl_Vec4& theValue)
1038 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1041 // =======================================================================
1042 // function : SetUniform
1043 // purpose : Specifies the value of the floating-point uniform 4D vector
1044 // =======================================================================
1045 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1047 const OpenGl_Vec4& theValue)
1049 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1051 return Standard_False;
1054 theCtx->core20fwd->glUniform4fv (theLocation, 1, theValue);
1055 return Standard_True;
1058 // =======================================================================
1059 // function : SetUniform
1060 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1061 // =======================================================================
1062 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1063 const GLchar* theName,
1064 const OpenGl_Mat4& theValue,
1065 GLboolean theTranspose)
1067 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1070 // =======================================================================
1071 // function : SetUniform
1072 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1073 // =======================================================================
1074 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1076 const OpenGl_Mat4& theValue,
1077 GLboolean theTranspose)
1079 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1081 return Standard_False;
1084 theCtx->core20fwd->glUniformMatrix4fv (theLocation, 1, GL_FALSE, theTranspose ? theValue.Transposed() : theValue);
1085 return Standard_True;
1088 // =======================================================================
1089 // function : SetUniform
1090 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1091 // =======================================================================
1092 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1093 const GLchar* theName,
1094 const OpenGl_Matrix& theValue,
1095 GLboolean theTranspose)
1097 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1100 // =======================================================================
1101 // function : SetUniform
1102 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1103 // =======================================================================
1104 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1106 const OpenGl_Matrix& theValue,
1107 GLboolean theTranspose)
1109 return SetUniform (theCtx, theLocation, OpenGl_Mat4::Map (*theValue.mat), theTranspose);
1112 // =======================================================================
1113 // function : SetUniform
1114 // purpose : Specifies the value of the float uniform array
1115 // =======================================================================
1116 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1119 const Standard_ShortReal* theData)
1121 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1123 return Standard_False;
1126 theCtx->core20fwd->glUniform1fv (theLocation, theCount, theData);
1127 return Standard_True;
1130 // =======================================================================
1131 // function : SetUniform
1132 // purpose : Specifies the value of the float2 uniform array
1133 // =======================================================================
1134 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1137 const OpenGl_Vec2* theData)
1139 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1141 return Standard_False;
1144 theCtx->core20fwd->glUniform2fv (theLocation, theCount, theData[0].GetData());
1145 return Standard_True;
1148 // =======================================================================
1149 // function : SetUniform
1150 // purpose : Specifies the value of the float3 uniform array
1151 // =======================================================================
1152 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1155 const OpenGl_Vec3* theData)
1157 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1159 return Standard_False;
1162 theCtx->core20fwd->glUniform3fv (theLocation, theCount, theData[0].GetData());
1163 return Standard_True;
1166 // =======================================================================
1167 // function : SetUniform
1168 // purpose : Specifies the value of the float4 uniform array
1169 // =======================================================================
1170 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1173 const OpenGl_Vec4* theData)
1175 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1177 return Standard_False;
1180 theCtx->core20fwd->glUniform4fv (theLocation, theCount, theData[0].GetData());
1181 return Standard_True;
1184 // =======================================================================
1185 // function : SetUniform
1186 // purpose : Specifies the value of the integer uniform array
1187 // =======================================================================
1188 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1191 const Standard_Integer* theData)
1193 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1195 return Standard_False;
1198 theCtx->core20fwd->glUniform1iv (theLocation, theCount, theData);
1199 return Standard_True;
1202 // =======================================================================
1203 // function : SetUniform
1204 // purpose : Specifies the value of the int2 uniform array
1205 // =======================================================================
1206 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1209 const OpenGl_Vec2i* theData)
1211 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1213 return Standard_False;
1216 theCtx->core20fwd->glUniform2iv (theLocation, theCount, theData[0].GetData());
1217 return Standard_True;
1220 // =======================================================================
1221 // function : SetUniform
1222 // purpose : Specifies the value of the int3 uniform array
1223 // =======================================================================
1224 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1227 const OpenGl_Vec3i* theData)
1229 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1231 return Standard_False;
1234 theCtx->core20fwd->glUniform3iv (theLocation, theCount, theData[0].GetData());
1235 return Standard_True;
1238 // =======================================================================
1239 // function : SetUniform
1240 // purpose : Specifies the value of the int4 uniform array
1241 // =======================================================================
1242 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1245 const OpenGl_Vec4i* theData)
1247 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1249 return Standard_False;
1252 theCtx->core20fwd->glUniform4iv (theLocation, theCount, theData[0].GetData());
1253 return Standard_True;
1256 // =======================================================================
1257 // function : SetSampler
1258 // purpose : Specifies the value of the sampler uniform variable
1259 // =======================================================================
1260 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1261 const GLchar* theName,
1262 const GLenum theTextureUnit)
1264 return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit);
1267 // =======================================================================
1268 // function : SetSampler
1269 // purpose : Specifies the value of the sampler uniform variable
1270 // =======================================================================
1271 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1273 const GLenum theTextureUnit)
1275 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1277 return Standard_False;
1280 theCtx->core20fwd->glUniform1i (theLocation, theTextureUnit);
1281 return Standard_True;
1284 // =======================================================================
1285 // function : Create
1286 // purpose : Creates new empty shader program of specified type
1287 // =======================================================================
1288 Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx)
1290 if (myProgramID == NO_PROGRAM
1291 && theCtx->core20fwd != NULL)
1293 myProgramID = theCtx->core20fwd->glCreateProgram();
1296 return myProgramID != NO_PROGRAM;
1299 // =======================================================================
1300 // function : Release
1301 // purpose : Destroys shader program
1302 // =======================================================================
1303 void OpenGl_ShaderProgram::Release (OpenGl_Context* theCtx)
1305 if (myProgramID == NO_PROGRAM)
1310 Standard_ASSERT_RETURN (theCtx != NULL,
1311 "OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...",);
1313 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
1315 if (!anIter.Value().IsNull())
1317 anIter.ChangeValue()->Release (theCtx);
1318 anIter.ChangeValue().Nullify();
1322 if (theCtx->core20fwd != NULL
1323 && theCtx->IsValid())
1325 theCtx->core20fwd->glDeleteProgram (myProgramID);
1328 myProgramID = NO_PROGRAM;