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>
32 #include <malloc.h> // for alloca()
35 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderProgram,OpenGl_Resource)
37 OpenGl_VariableSetterSelector OpenGl_ShaderProgram::mySetterSelector = OpenGl_VariableSetterSelector();
39 // Declare OCCT-specific OpenGL/GLSL shader variables
40 Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] =
42 "occModelWorldMatrix", // OpenGl_OCC_MODEL_WORLD_MATRIX
43 "occWorldViewMatrix", // OpenGl_OCC_WORLD_VIEW_MATRIX
44 "occProjectionMatrix", // OpenGl_OCC_PROJECTION_MATRIX
45 "occModelWorldMatrixInverse", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE
46 "occWorldViewMatrixInverse", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE
47 "occProjectionMatrixInverse", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE
48 "occModelWorldMatrixTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE
49 "occWorldViewMatrixTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE
50 "occProjectionMatrixTranspose", // OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE
51 "occModelWorldMatrixInverseTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE
52 "occWorldViewMatrixInverseTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE
53 "occProjectionMatrixInverseTranspose", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE
55 "occClipPlaneEquations", // OpenGl_OCC_CLIP_PLANE_EQUATIONS
56 "occClipPlaneCount", // OpenGl_OCC_CLIP_PLANE_COUNT
58 "occLightSourcesCount", // OpenGl_OCC_LIGHT_SOURCE_COUNT
59 "occLightSourcesTypes", // OpenGl_OCC_LIGHT_SOURCE_TYPES
60 "occLightSources", // OpenGl_OCC_LIGHT_SOURCE_PARAMS
61 "occLightAmbient", // OpenGl_OCC_LIGHT_AMBIENT
63 "occActiveSampler", // OpenGl_OCCT_ACTIVE_SAMPLER
64 "occTextureEnable", // OpenGl_OCCT_TEXTURE_ENABLE
65 "occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE
66 "occFrontMaterial", // OpenGl_OCCT_FRONT_MATERIAL
67 "occBackMaterial", // OpenGl_OCCT_BACK_MATERIAL
68 "occColor", // OpenGl_OCCT_COLOR
70 "occTexTrsf2d", // OpenGl_OCCT_TEXTURE_TRSF2D
71 "occPointSize" // OpenGl_OCCT_POINT_SIZE
75 // =======================================================================
76 // function : OpenGl_VariableSetterSelector
77 // purpose : Creates new variable setter selector
78 // =======================================================================
79 OpenGl_VariableSetterSelector::OpenGl_VariableSetterSelector()
81 // Note: Add new variable setters here
82 mySetterList = OpenGl_HashMapInitializer::CreateListOf<size_t, OpenGl_SetterInterface*>
83 (Graphic3d_UniformValueTypeID<int>::ID, new OpenGl_VariableSetter<int>())
84 (Graphic3d_UniformValueTypeID<float>::ID, new OpenGl_VariableSetter<float>())
85 (Graphic3d_UniformValueTypeID<OpenGl_Vec2>::ID, new OpenGl_VariableSetter<OpenGl_Vec2>())
86 (Graphic3d_UniformValueTypeID<OpenGl_Vec3>::ID, new OpenGl_VariableSetter<OpenGl_Vec3>())
87 (Graphic3d_UniformValueTypeID<OpenGl_Vec4>::ID, new OpenGl_VariableSetter<OpenGl_Vec4>())
88 (Graphic3d_UniformValueTypeID<OpenGl_Vec2i>::ID, new OpenGl_VariableSetter<OpenGl_Vec2i>())
89 (Graphic3d_UniformValueTypeID<OpenGl_Vec3i>::ID, new OpenGl_VariableSetter<OpenGl_Vec3i>())
90 (Graphic3d_UniformValueTypeID<OpenGl_Vec4i>::ID, new OpenGl_VariableSetter<OpenGl_Vec4i>());
93 // =======================================================================
94 // function : ~OpenGl_VariableSetterSelector
95 // purpose : Releases memory resources of variable setter selector
96 // =======================================================================
97 OpenGl_VariableSetterSelector::~OpenGl_VariableSetterSelector()
99 for (OpenGl_SetterList::Iterator anIt (mySetterList); anIt.More(); anIt.Next())
104 mySetterList.Clear();
107 // =======================================================================
109 // purpose : Sets generic variable to specified shader program
110 // =======================================================================
111 void OpenGl_VariableSetterSelector::Set (const Handle(OpenGl_Context)& theCtx,
112 const Handle(Graphic3d_ShaderVariable)& theVariable,
113 OpenGl_ShaderProgram* theProgram) const
115 Standard_ASSERT_RETURN (mySetterList.IsBound (theVariable->Value()->TypeID()),
116 "The type of user-defined uniform variable is not supported...", );
118 mySetterList.Find (theVariable->Value()->TypeID())->Set (theCtx, theVariable, theProgram);
121 // =======================================================================
122 // function : OpenGl_ShaderProgram
123 // purpose : Creates uninitialized shader program
124 // =======================================================================
125 OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy)
126 : myProgramID (NO_PROGRAM),
130 memset (myCurrentState, 0, sizeof (myCurrentState));
131 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
133 myStateLocations[aVar] = INVALID_LOCATION;
137 // =======================================================================
138 // function : Initialize
139 // purpose : Initializes program object with the list of shader objects
140 // =======================================================================
141 Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& theCtx,
142 const Graphic3d_ShaderObjectList& theShaders)
144 if (theCtx.IsNull() || !Create (theCtx))
146 return Standard_False;
149 OSD_File aDeclFile (Graphic3d_ShaderProgram::ShadersFolder() + "/Declarations.glsl");
150 OSD_File aDeclImplFile (Graphic3d_ShaderProgram::ShadersFolder() + "/DeclarationsImpl.glsl");
151 if (!aDeclFile.Exists()
152 || !aDeclImplFile.Exists())
154 const TCollection_ExtendedString aMsg = "Error! Failed to load OCCT shader declarations file";
155 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
158 GL_DEBUG_SEVERITY_HIGH,
160 return Standard_False;
163 TCollection_AsciiString aHeader = !myProxy.IsNull() && !myProxy->Header().IsEmpty()
164 ? (myProxy->Header() + "\n")
165 : TCollection_AsciiString();
167 TCollection_AsciiString aDeclarations;
168 aDeclFile.Open (OSD_ReadOnly, OSD_Protection());
169 aDeclFile.Read (aDeclarations, (int)aDeclFile.Size());
172 TCollection_AsciiString aDeclImpl;
173 aDeclImplFile.Open (OSD_ReadOnly, OSD_Protection());
174 aDeclImplFile.Read (aDeclImpl, (int)aDeclImplFile.Size());
175 aDeclImplFile.Close();
176 aDeclarations += aDeclImpl;
178 for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders);
179 anIter.More(); anIter.Next())
181 if (!anIter.Value()->IsDone())
183 const TCollection_ExtendedString aMsg = "Error! Failed to get shader source";
184 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
187 GL_DEBUG_SEVERITY_HIGH,
189 return Standard_False;
192 Handle(OpenGl_ShaderObject) aShader;
194 // Note: Add support of other shader types here
195 switch (anIter.Value()->Type())
197 case Graphic3d_TOS_VERTEX:
198 aShader = new OpenGl_ShaderObject (GL_VERTEX_SHADER);
200 case Graphic3d_TOS_FRAGMENT:
201 aShader = new OpenGl_ShaderObject (GL_FRAGMENT_SHADER);
205 // Is unsupported shader type?
206 if (aShader.IsNull())
208 TCollection_ExtendedString aMsg = "Error! Unsupported shader type";
209 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
212 GL_DEBUG_SEVERITY_HIGH,
214 return Standard_False;
217 if (!aShader->Create (theCtx))
219 aShader->Release (theCtx.operator->());
220 return Standard_False;
223 TCollection_AsciiString aSource = aDeclarations + anIter.Value()->Source();
224 switch (anIter.Value()->Type())
226 case Graphic3d_TOS_VERTEX:
228 aSource = aHeader + TCollection_AsciiString ("#define VERTEX_SHADER\n") + aSource;
231 case Graphic3d_TOS_FRAGMENT:
233 #if defined(GL_ES_VERSION_2_0)
234 TCollection_AsciiString aPrefix (theCtx->hasHighp
235 ? "precision highp float;\n"
236 "precision highp int;\n"
237 : "precision mediump float;\n"
238 "precision mediump int;\n");
239 aSource = aHeader + aPrefix + aSource;
241 aSource = aHeader + aSource;
247 if (!aShader->LoadSource (theCtx, aSource))
249 const TCollection_ExtendedString aMsg = "Error! Failed to set shader source";
250 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
253 GL_DEBUG_SEVERITY_HIGH,
255 aShader->Release (theCtx.operator->());
256 return Standard_False;
259 if (!aShader->Compile (theCtx))
261 TCollection_AsciiString aLog;
262 aShader->FetchInfoLog (theCtx, aLog);
265 aLog = "Compilation log is empty.";
267 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
270 GL_DEBUG_SEVERITY_HIGH,
271 TCollection_ExtendedString ("Failed to compile shader object. Compilation log:\n") + aLog);
272 aShader->Release (theCtx.operator->());
273 return Standard_False;
275 else if (theCtx->caps->glslWarnings)
277 TCollection_AsciiString aLog;
278 aShader->FetchInfoLog (theCtx, aLog);
280 && !aLog.IsEqual ("No errors.\n"))
282 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
283 GL_DEBUG_TYPE_PORTABILITY,
285 GL_DEBUG_SEVERITY_LOW,
286 TCollection_ExtendedString ("Shader compilation log:\n") + aLog);
290 if (!AttachShader (theCtx, aShader))
292 aShader->Release (theCtx.operator->());
293 return Standard_False;
297 // bind locations for pre-defined Vertex Attributes
298 SetAttributeName (theCtx, Graphic3d_TOA_POS, "occVertex");
299 SetAttributeName (theCtx, Graphic3d_TOA_NORM, "occNormal");
300 SetAttributeName (theCtx, Graphic3d_TOA_UV, "occTexCoord");
301 SetAttributeName (theCtx, Graphic3d_TOA_COLOR, "occVertColor");
303 // bind custom Vertex Attributes
304 if (!myProxy.IsNull())
306 for (Graphic3d_ShaderAttributeList::Iterator anAttribIter (myProxy->VertexAttributes());
307 anAttribIter.More(); anAttribIter.Next())
309 SetAttributeName (theCtx, anAttribIter.Value()->Location(), anAttribIter.Value()->Name().ToCString());
315 TCollection_AsciiString aLog;
316 FetchInfoLog (theCtx, aLog);
319 aLog = "Linker log is empty.";
321 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
324 GL_DEBUG_SEVERITY_HIGH,
325 TCollection_ExtendedString ("Failed to link program object! Linker log:\n") + aLog);
326 return Standard_False;
328 else if (theCtx->caps->glslWarnings)
330 TCollection_AsciiString aLog;
331 FetchInfoLog (theCtx, aLog);
333 && !aLog.IsEqual ("No errors.\n"))
335 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
336 GL_DEBUG_TYPE_PORTABILITY,
338 GL_DEBUG_SEVERITY_LOW,
339 TCollection_ExtendedString ("GLSL linker log:\n") + aLog);
343 // set uniform defaults
344 const GLint aLocSampler = GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER);
345 const GLint aLocTexEnable = GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE);
346 if (aLocSampler != INVALID_LOCATION
347 || aLocTexEnable != INVALID_LOCATION)
349 const Handle(OpenGl_ShaderProgram)& anOldProgram = theCtx->ActiveProgram();
350 theCtx->core20fwd->glUseProgram (myProgramID);
351 SetUniform (theCtx, aLocSampler, 0); // GL_TEXTURE0
352 SetUniform (theCtx, aLocTexEnable, 0); // Off
353 theCtx->core20fwd->glUseProgram (!anOldProgram.IsNull() ? anOldProgram->ProgramId() : OpenGl_ShaderProgram::NO_PROGRAM);
356 return Standard_True;
359 // =======================================================================
360 // function : ~OpenGl_ShaderProgram
361 // purpose : Releases resources of shader program
362 // =======================================================================
363 OpenGl_ShaderProgram::~OpenGl_ShaderProgram()
368 // =======================================================================
369 // function : AttachShader
370 // purpose : Attaches shader object to the program object
371 // =======================================================================
372 Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context)& theCtx,
373 const Handle(OpenGl_ShaderObject)& theShader)
375 if (myProgramID == NO_PROGRAM || theShader.IsNull())
377 return Standard_False;
380 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
382 if (theShader == anIter.Value())
384 return Standard_False;
388 myShaderObjects.Append (theShader);
389 theCtx->core20fwd->glAttachShader (myProgramID, theShader->myShaderID);
390 return Standard_True;
393 // =======================================================================
394 // function : DetachShader
395 // purpose : Detaches shader object to the program object
396 // =======================================================================
397 Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context)& theCtx,
398 const Handle(OpenGl_ShaderObject)& theShader)
400 if (myProgramID == NO_PROGRAM
401 || theShader.IsNull())
403 return Standard_False;
406 OpenGl_ShaderList::Iterator anIter (myShaderObjects);
407 while (anIter.More())
409 if (theShader == anIter.Value())
411 myShaderObjects.Remove (anIter);
420 return Standard_False;
423 theCtx->core20fwd->glDetachShader (myProgramID, theShader->myShaderID);
424 return Standard_True;
427 // =======================================================================
429 // purpose : Links the program object
430 // =======================================================================
431 Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx)
433 if (myProgramID == NO_PROGRAM)
435 return Standard_False;
438 GLint aStatus = GL_FALSE;
439 theCtx->core20fwd->glLinkProgram (myProgramID);
440 theCtx->core20fwd->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
441 if (aStatus == GL_FALSE)
443 return Standard_False;
446 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
448 myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]);
450 return Standard_True;
453 // =======================================================================
454 // function : FetchInfoLog
455 // purpose : Fetches information log of the last link operation
456 // =======================================================================
457 Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
458 TCollection_AsciiString& theOutput)
460 if (myProgramID == NO_PROGRAM)
462 return Standard_False;
466 theCtx->core20fwd->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
469 GLchar* aLog = (GLchar*) alloca (aLength);
470 memset (aLog, 0, aLength);
471 theCtx->core20fwd->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
474 return Standard_True;
477 // =======================================================================
478 // function : ApplyVariables
479 // purpose : Fetches uniform variables from proxy shader program
480 // =======================================================================
481 Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Context)& theCtx)
483 if (myProxy.IsNull() || myProxy->Variables().IsEmpty())
485 return Standard_False;
488 for (Graphic3d_ShaderVariableList::Iterator anIter (myProxy->Variables()); anIter.More(); anIter.Next())
490 mySetterSelector.Set (theCtx, anIter.Value(), this);
493 myProxy->ClearVariables();
494 return Standard_True;
497 // =======================================================================
498 // function : ActiveState
499 // purpose : Returns index of last modification for specified state type
500 // =======================================================================
501 Standard_Size OpenGl_ShaderProgram::ActiveState (const OpenGl_UniformStateType theType) const
503 if (theType < MaxStateTypes)
505 return myCurrentState[theType];
510 // =======================================================================
511 // function : UpdateState
512 // purpose : Updates index of last modification for specified state type
513 // =======================================================================
514 void OpenGl_ShaderProgram::UpdateState (const OpenGl_UniformStateType theType,
515 const Standard_Size theIndex)
517 if (theType < MaxStateTypes)
519 myCurrentState[theType] = theIndex;
523 // =======================================================================
524 // function : GetUniformLocation
525 // purpose : Returns location (index) of the specific uniform variable
526 // =======================================================================
527 GLint OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& theCtx,
528 const GLchar* theName) const
530 return myProgramID != NO_PROGRAM
531 ? theCtx->core20fwd->glGetUniformLocation (myProgramID, theName)
535 // =======================================================================
536 // function : GetAttributeLocation
537 // purpose : Returns location (index) of the generic vertex attribute
538 // =======================================================================
539 GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)& theCtx,
540 const GLchar* theName) const
542 return myProgramID != NO_PROGRAM
543 ? theCtx->core20fwd->glGetAttribLocation (myProgramID, theName)
547 // =======================================================================
548 // function : GetStateLocation
549 // purpose : Returns location of the OCCT state uniform variable
550 // =======================================================================
551 GLint OpenGl_ShaderProgram::GetStateLocation (const GLuint theVariable) const
553 if (theVariable < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES)
555 return myStateLocations[theVariable];
557 return INVALID_LOCATION;
560 // =======================================================================
561 // function : GetUniform
562 // purpose : Returns the value of the integer uniform variable
563 // =======================================================================
564 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
565 const GLchar* theName,
566 OpenGl_Vec4i& theValue) const
568 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
571 // =======================================================================
572 // function : GetUniform
573 // purpose : Returns the value of the integer uniform variable
574 // =======================================================================
575 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
577 OpenGl_Vec4i& theValue) const
579 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
581 return Standard_False;
584 theCtx->core20fwd->glGetUniformiv (myProgramID, theLocation, theValue);
585 return Standard_True;
588 // =======================================================================
589 // function : GetUniform
590 // purpose : Returns the value of the floating-point uniform variable
591 // =======================================================================
592 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
593 const GLchar* theName,
594 OpenGl_Vec4& theValue) const
596 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
599 // =======================================================================
600 // function : GetUniform
601 // purpose : Returns the value of the floating-point uniform variable
602 // =======================================================================
603 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
605 OpenGl_Vec4& theValue) const
607 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
609 return Standard_False;
612 theCtx->core20fwd->glGetUniformfv (myProgramID, theLocation, theValue);
613 return Standard_True;
616 // =======================================================================
617 // function : GetAttribute
618 // purpose : Returns the integer vertex attribute
619 // =======================================================================
620 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
621 const GLchar* theName,
622 OpenGl_Vec4i& theValue) const
624 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
627 // =======================================================================
628 // function : GetAttribute
629 // purpose : Returns the integer vertex attribute
630 // =======================================================================
631 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
633 OpenGl_Vec4i& theValue) const
635 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
637 return Standard_False;
640 theCtx->core20fwd->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
641 return Standard_True;
644 // =======================================================================
645 // function : GetAttribute
646 // purpose : Returns the floating-point vertex attribute
647 // =======================================================================
648 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
649 const GLchar* theName,
650 OpenGl_Vec4& theValue) const
652 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
655 // =======================================================================
656 // function : GetAttribute
657 // purpose : Returns the floating-point vertex attribute
658 // =======================================================================
659 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
661 OpenGl_Vec4& theValue) const
663 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
665 return Standard_False;
668 theCtx->core20fwd->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
669 return Standard_True;
672 // =======================================================================
673 // function : SetAttributeName
675 // =======================================================================
676 Standard_Boolean OpenGl_ShaderProgram::SetAttributeName (const Handle(OpenGl_Context)& theCtx,
678 const GLchar* theName)
680 theCtx->core20fwd->glBindAttribLocation (myProgramID, theIndex, theName);
681 return Standard_True;
684 // =======================================================================
685 // function : SetAttribute
687 // =======================================================================
688 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
689 const GLchar* theName,
692 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
695 // =======================================================================
696 // function : SetAttribute
698 // =======================================================================
699 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
703 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
705 return Standard_False;
708 theCtx->core20fwd->glVertexAttrib1f (theIndex, theValue);
709 return Standard_True;
712 // =======================================================================
713 // function : SetAttribute
715 // =======================================================================
716 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
717 const GLchar* theName,
718 const OpenGl_Vec2& theValue)
720 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
723 // =======================================================================
724 // function : SetAttribute
726 // =======================================================================
727 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
729 const OpenGl_Vec2& theValue)
731 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
733 return Standard_False;
736 theCtx->core20fwd->glVertexAttrib2fv (theIndex, theValue);
737 return Standard_True;
740 // =======================================================================
741 // function : SetAttribute
743 // =======================================================================
744 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
745 const GLchar* theName,
746 const OpenGl_Vec3& theValue)
748 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
751 // =======================================================================
752 // function : SetAttribute
754 // =======================================================================
755 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
757 const OpenGl_Vec3& theValue)
759 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
761 return Standard_False;
764 theCtx->core20fwd->glVertexAttrib3fv (theIndex, theValue);
765 return Standard_True;
768 // =======================================================================
769 // function : SetAttribute
771 // =======================================================================
772 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
773 const GLchar* theName,
774 const OpenGl_Vec4& theValue)
776 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
779 // =======================================================================
780 // function : SetAttribute
782 // =======================================================================
783 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
785 const OpenGl_Vec4& theValue)
787 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
789 return Standard_False;
792 theCtx->core20fwd->glVertexAttrib4fv (theIndex, theValue);
793 return Standard_True;
796 // =======================================================================
797 // function : SetUniform
798 // purpose : Specifies the value of the integer uniform variable
799 // =======================================================================
800 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
801 const GLchar* theName,
804 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
807 // =======================================================================
808 // function : SetUniform
809 // purpose : Specifies the value of the integer uniform variable
810 // =======================================================================
811 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
815 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
817 return Standard_False;
820 theCtx->core20fwd->glUniform1i (theLocation, theValue);
821 return Standard_True;
824 // =======================================================================
825 // function : SetUniform
827 // =======================================================================
828 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
829 const GLchar* theName,
830 const OpenGl_Vec2u& theValue)
832 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
835 // =======================================================================
836 // function : SetUniform
838 // =======================================================================
839 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
841 const OpenGl_Vec2u& theValue)
843 if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
845 return Standard_False;
848 #if !defined(GL_ES_VERSION_2_0)
849 theCtx->core32->glUniform2uiv (theLocation, 1, theValue.GetData());
850 return Standard_True;
853 return Standard_False;
857 // =======================================================================
858 // function : SetUniform
860 // =======================================================================
861 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
862 const GLchar* theName,
863 const GLsizei theCount,
864 const OpenGl_Vec2u* theValue)
866 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theCount, theValue);
869 // =======================================================================
870 // function : SetUniform
872 // =======================================================================
873 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
875 const GLsizei theCount,
876 const OpenGl_Vec2u* theValue)
878 if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
880 return Standard_False;
883 #if !defined(GL_ES_VERSION_2_0)
884 theCtx->core32->glUniform2uiv (theLocation, theCount, theValue->GetData());
885 return Standard_True;
889 return Standard_False;
893 // =======================================================================
894 // function : SetUniform
895 // purpose : Specifies the value of the floating-point uniform variable
896 // =======================================================================
897 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
898 const GLchar* theName,
901 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
904 // =======================================================================
905 // function : SetUniform
906 // purpose : Specifies the value of the floating-point uniform variable
907 // =======================================================================
908 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
912 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
914 return Standard_False;
917 theCtx->core20fwd->glUniform1f (theLocation, theValue);
918 return Standard_True;
921 // =======================================================================
922 // function : SetUniform
923 // purpose : Specifies the value of the integer uniform 2D vector
924 // =======================================================================
925 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
926 const GLchar* theName,
927 const OpenGl_Vec2i& theValue)
929 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
932 // =======================================================================
933 // function : SetUniform
934 // purpose : Specifies the value of the integer uniform 2D vector
935 // =======================================================================
936 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
938 const OpenGl_Vec2i& theValue)
940 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
942 return Standard_False;
945 theCtx->core20fwd->glUniform2iv (theLocation, 1, theValue);
946 return Standard_True;
949 // =======================================================================
950 // function : SetUniform
951 // purpose : Specifies the value of the integer uniform 3D vector
952 // =======================================================================
953 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
954 const GLchar* theName,
955 const OpenGl_Vec3i& theValue)
957 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
960 // =======================================================================
961 // function : SetUniform
962 // purpose : Specifies the value of the integer uniform 3D vector
963 // =======================================================================
964 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
966 const OpenGl_Vec3i& theValue)
968 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
970 return Standard_False;
973 theCtx->core20fwd->glUniform3iv (theLocation, 1, theValue);
974 return Standard_True;
977 // =======================================================================
978 // function : SetUniform
979 // purpose : Specifies the value of the integer uniform 4D vector
980 // =======================================================================
981 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
982 const GLchar* theName,
983 const OpenGl_Vec4i& theValue)
985 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
988 // =======================================================================
989 // function : SetUniform
990 // purpose : Specifies the value of the integer uniform 4D vector
991 // =======================================================================
992 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
994 const OpenGl_Vec4i& theValue)
996 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
998 return Standard_False;
1001 theCtx->core20fwd->glUniform4iv (theLocation, 1, theValue);
1002 return Standard_True;
1005 // =======================================================================
1006 // function : SetUniform
1007 // purpose : Specifies the value of the floating-point uniform 2D vector
1008 // =======================================================================
1009 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1010 const GLchar* theName,
1011 const OpenGl_Vec2& theValue)
1013 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1016 // =======================================================================
1017 // function : SetUniform
1018 // purpose : Specifies the value of the floating-point uniform 2D vector
1019 // =======================================================================
1020 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1022 const OpenGl_Vec2& theValue)
1024 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1026 return Standard_False;
1029 theCtx->core20fwd->glUniform2fv (theLocation, 1, theValue);
1030 return Standard_True;
1033 // =======================================================================
1034 // function : SetUniform
1035 // purpose : Specifies the value of the floating-point uniform 3D vector
1036 // =======================================================================
1037 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1038 const GLchar* theName,
1039 const OpenGl_Vec3& theValue)
1041 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1044 // =======================================================================
1045 // function : SetUniform
1046 // purpose : Specifies the value of the floating-point uniform 3D vector
1047 // =======================================================================
1048 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1050 const OpenGl_Vec3& theValue)
1052 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1054 return Standard_False;
1057 theCtx->core20fwd->glUniform3fv (theLocation, 1, theValue);
1058 return Standard_True;
1061 // =======================================================================
1062 // function : SetUniform
1063 // purpose : Specifies the value of the floating-point uniform 4D vector
1064 // =======================================================================
1065 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1066 const GLchar* theName,
1067 const OpenGl_Vec4& theValue)
1069 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1072 // =======================================================================
1073 // function : SetUniform
1074 // purpose : Specifies the value of the floating-point uniform 4D vector
1075 // =======================================================================
1076 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1078 const OpenGl_Vec4& theValue)
1080 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1082 return Standard_False;
1085 theCtx->core20fwd->glUniform4fv (theLocation, 1, theValue);
1086 return Standard_True;
1089 // =======================================================================
1090 // function : SetUniform
1091 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1092 // =======================================================================
1093 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1094 const GLchar* theName,
1095 const OpenGl_Mat4& theValue,
1096 GLboolean theTranspose)
1098 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1101 // =======================================================================
1102 // function : SetUniform
1103 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1104 // =======================================================================
1105 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1107 const OpenGl_Mat4& theValue,
1108 GLboolean theTranspose)
1110 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1112 return Standard_False;
1115 theCtx->core20fwd->glUniformMatrix4fv (theLocation, 1, GL_FALSE, theTranspose ? theValue.Transposed() : theValue);
1116 return Standard_True;
1119 // =======================================================================
1120 // function : SetUniform
1121 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1122 // =======================================================================
1123 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1124 const GLchar* theName,
1125 const OpenGl_Matrix& theValue,
1126 GLboolean theTranspose)
1128 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1131 // =======================================================================
1132 // function : SetUniform
1133 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1134 // =======================================================================
1135 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1137 const OpenGl_Matrix& theValue,
1138 GLboolean theTranspose)
1140 return SetUniform (theCtx, theLocation, OpenGl_Mat4::Map (*theValue.mat), theTranspose);
1143 // =======================================================================
1144 // function : SetUniform
1145 // purpose : Specifies the value of the float uniform array
1146 // =======================================================================
1147 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1150 const Standard_ShortReal* theData)
1152 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1154 return Standard_False;
1157 theCtx->core20fwd->glUniform1fv (theLocation, theCount, theData);
1158 return Standard_True;
1161 // =======================================================================
1162 // function : SetUniform
1163 // purpose : Specifies the value of the float2 uniform array
1164 // =======================================================================
1165 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1168 const OpenGl_Vec2* theData)
1170 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1172 return Standard_False;
1175 theCtx->core20fwd->glUniform2fv (theLocation, theCount, theData[0].GetData());
1176 return Standard_True;
1179 // =======================================================================
1180 // function : SetUniform
1181 // purpose : Specifies the value of the float3 uniform array
1182 // =======================================================================
1183 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1186 const OpenGl_Vec3* theData)
1188 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1190 return Standard_False;
1193 theCtx->core20fwd->glUniform3fv (theLocation, theCount, theData[0].GetData());
1194 return Standard_True;
1197 // =======================================================================
1198 // function : SetUniform
1199 // purpose : Specifies the value of the float4 uniform array
1200 // =======================================================================
1201 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1204 const OpenGl_Vec4* theData)
1206 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1208 return Standard_False;
1211 theCtx->core20fwd->glUniform4fv (theLocation, theCount, theData[0].GetData());
1212 return Standard_True;
1215 // =======================================================================
1216 // function : SetUniform
1217 // purpose : Specifies the value of the integer uniform array
1218 // =======================================================================
1219 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1222 const Standard_Integer* theData)
1224 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1226 return Standard_False;
1229 theCtx->core20fwd->glUniform1iv (theLocation, theCount, theData);
1230 return Standard_True;
1233 // =======================================================================
1234 // function : SetUniform
1235 // purpose : Specifies the value of the int2 uniform array
1236 // =======================================================================
1237 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1240 const OpenGl_Vec2i* theData)
1242 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1244 return Standard_False;
1247 theCtx->core20fwd->glUniform2iv (theLocation, theCount, theData[0].GetData());
1248 return Standard_True;
1251 // =======================================================================
1252 // function : SetUniform
1253 // purpose : Specifies the value of the int3 uniform array
1254 // =======================================================================
1255 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1258 const OpenGl_Vec3i* theData)
1260 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1262 return Standard_False;
1265 theCtx->core20fwd->glUniform3iv (theLocation, theCount, theData[0].GetData());
1266 return Standard_True;
1269 // =======================================================================
1270 // function : SetUniform
1271 // purpose : Specifies the value of the int4 uniform array
1272 // =======================================================================
1273 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1276 const OpenGl_Vec4i* theData)
1278 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1280 return Standard_False;
1283 theCtx->core20fwd->glUniform4iv (theLocation, theCount, theData[0].GetData());
1284 return Standard_True;
1287 // =======================================================================
1288 // function : SetSampler
1289 // purpose : Specifies the value of the sampler uniform variable
1290 // =======================================================================
1291 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1292 const GLchar* theName,
1293 const GLenum theTextureUnit)
1295 return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit);
1298 // =======================================================================
1299 // function : SetSampler
1300 // purpose : Specifies the value of the sampler uniform variable
1301 // =======================================================================
1302 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1304 const GLenum theTextureUnit)
1306 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1308 return Standard_False;
1311 theCtx->core20fwd->glUniform1i (theLocation, theTextureUnit);
1312 return Standard_True;
1315 // =======================================================================
1316 // function : Create
1317 // purpose : Creates new empty shader program of specified type
1318 // =======================================================================
1319 Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx)
1321 if (myProgramID == NO_PROGRAM
1322 && theCtx->core20fwd != NULL)
1324 myProgramID = theCtx->core20fwd->glCreateProgram();
1327 return myProgramID != NO_PROGRAM;
1330 // =======================================================================
1331 // function : Release
1332 // purpose : Destroys shader program
1333 // =======================================================================
1334 void OpenGl_ShaderProgram::Release (OpenGl_Context* theCtx)
1336 if (myProgramID == NO_PROGRAM)
1341 Standard_ASSERT_RETURN (theCtx != NULL,
1342 "OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...",);
1344 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
1346 if (!anIter.Value().IsNull())
1348 anIter.ChangeValue()->Release (theCtx);
1349 anIter.ChangeValue().Nullify();
1353 if (theCtx->core20fwd != NULL
1354 && theCtx->IsValid())
1356 theCtx->core20fwd->glDeleteProgram (myProgramID);
1359 myProgramID = NO_PROGRAM;