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 "occClipPlaneSpaces", // OpenGl_OCC_CLIP_PLANE_SPACES
57 "occClipPlaneCount", // OpenGl_OCC_CLIP_PLANE_COUNT
59 "occLightSourcesCount", // OpenGl_OCC_LIGHT_SOURCE_COUNT
60 "occLightSourcesTypes", // OpenGl_OCC_LIGHT_SOURCE_TYPES
61 "occLightSources", // OpenGl_OCC_LIGHT_SOURCE_PARAMS
62 "occLightAmbient", // OpenGl_OCC_LIGHT_AMBIENT
64 "occActiveSampler", // OpenGl_OCCT_ACTIVE_SAMPLER
65 "occTextureEnable", // OpenGl_OCCT_TEXTURE_ENABLE
66 "occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE
67 "occFrontMaterial", // OpenGl_OCCT_FRONT_MATERIAL
68 "occBackMaterial", // OpenGl_OCCT_BACK_MATERIAL
69 "occColor", // OpenGl_OCCT_COLOR
71 "occTexTrsf2d", // OpenGl_OCCT_TEXTURE_TRSF2D
72 "occPointSize" // OpenGl_OCCT_POINT_SIZE
76 // =======================================================================
77 // function : OpenGl_VariableSetterSelector
78 // purpose : Creates new variable setter selector
79 // =======================================================================
80 OpenGl_VariableSetterSelector::OpenGl_VariableSetterSelector()
82 // Note: Add new variable setters here
83 mySetterList = OpenGl_HashMapInitializer::CreateListOf<size_t, OpenGl_SetterInterface*>
84 (Graphic3d_UniformValueTypeID<int>::ID, new OpenGl_VariableSetter<int>())
85 (Graphic3d_UniformValueTypeID<float>::ID, new OpenGl_VariableSetter<float>())
86 (Graphic3d_UniformValueTypeID<OpenGl_Vec2>::ID, new OpenGl_VariableSetter<OpenGl_Vec2>())
87 (Graphic3d_UniformValueTypeID<OpenGl_Vec3>::ID, new OpenGl_VariableSetter<OpenGl_Vec3>())
88 (Graphic3d_UniformValueTypeID<OpenGl_Vec4>::ID, new OpenGl_VariableSetter<OpenGl_Vec4>())
89 (Graphic3d_UniformValueTypeID<OpenGl_Vec2i>::ID, new OpenGl_VariableSetter<OpenGl_Vec2i>())
90 (Graphic3d_UniformValueTypeID<OpenGl_Vec3i>::ID, new OpenGl_VariableSetter<OpenGl_Vec3i>())
91 (Graphic3d_UniformValueTypeID<OpenGl_Vec4i>::ID, new OpenGl_VariableSetter<OpenGl_Vec4i>());
94 // =======================================================================
95 // function : ~OpenGl_VariableSetterSelector
96 // purpose : Releases memory resources of variable setter selector
97 // =======================================================================
98 OpenGl_VariableSetterSelector::~OpenGl_VariableSetterSelector()
100 for (OpenGl_SetterList::Iterator anIt (mySetterList); anIt.More(); anIt.Next())
105 mySetterList.Clear();
108 // =======================================================================
110 // purpose : Sets generic variable to specified shader program
111 // =======================================================================
112 void OpenGl_VariableSetterSelector::Set (const Handle(OpenGl_Context)& theCtx,
113 const Handle(Graphic3d_ShaderVariable)& theVariable,
114 OpenGl_ShaderProgram* theProgram) const
116 Standard_ASSERT_RETURN (mySetterList.IsBound (theVariable->Value()->TypeID()),
117 "The type of user-defined uniform variable is not supported...", );
119 mySetterList.Find (theVariable->Value()->TypeID())->Set (theCtx, theVariable, theProgram);
122 // =======================================================================
123 // function : OpenGl_ShaderProgram
124 // purpose : Creates uninitialized shader program
125 // =======================================================================
126 OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy)
127 : myProgramID (NO_PROGRAM),
131 memset (myCurrentState, 0, sizeof (myCurrentState));
132 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
134 myStateLocations[aVar] = INVALID_LOCATION;
138 // =======================================================================
139 // function : Initialize
140 // purpose : Initializes program object with the list of shader objects
141 // =======================================================================
142 Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& theCtx,
143 const Graphic3d_ShaderObjectList& theShaders)
145 if (theCtx.IsNull() || !Create (theCtx))
147 return Standard_False;
150 OSD_File aDeclFile (Graphic3d_ShaderProgram::ShadersFolder() + "/Declarations.glsl");
151 OSD_File aDeclImplFile (Graphic3d_ShaderProgram::ShadersFolder() + "/DeclarationsImpl.glsl");
152 if (!aDeclFile.Exists()
153 || !aDeclImplFile.Exists())
155 const TCollection_ExtendedString aMsg = "Error! Failed to load OCCT shader declarations file";
156 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
159 GL_DEBUG_SEVERITY_HIGH,
161 return Standard_False;
164 TCollection_AsciiString aHeader = !myProxy.IsNull() && !myProxy->Header().IsEmpty()
165 ? (myProxy->Header() + "\n")
166 : TCollection_AsciiString();
168 TCollection_AsciiString aDeclarations;
169 aDeclFile.Open (OSD_ReadOnly, OSD_Protection());
170 aDeclFile.Read (aDeclarations, (int)aDeclFile.Size());
173 TCollection_AsciiString aDeclImpl;
174 aDeclImplFile.Open (OSD_ReadOnly, OSD_Protection());
175 aDeclImplFile.Read (aDeclImpl, (int)aDeclImplFile.Size());
176 aDeclImplFile.Close();
177 aDeclarations += aDeclImpl;
179 for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders);
180 anIter.More(); anIter.Next())
182 if (!anIter.Value()->IsDone())
184 const TCollection_ExtendedString aMsg = "Error! Failed to get shader source";
185 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
188 GL_DEBUG_SEVERITY_HIGH,
190 return Standard_False;
193 Handle(OpenGl_ShaderObject) aShader;
195 // Note: Add support of other shader types here
196 switch (anIter.Value()->Type())
198 case Graphic3d_TOS_VERTEX:
199 aShader = new OpenGl_ShaderObject (GL_VERTEX_SHADER);
201 case Graphic3d_TOS_FRAGMENT:
202 aShader = new OpenGl_ShaderObject (GL_FRAGMENT_SHADER);
206 // Is unsupported shader type?
207 if (aShader.IsNull())
209 TCollection_ExtendedString aMsg = "Error! Unsupported shader type";
210 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
213 GL_DEBUG_SEVERITY_HIGH,
215 return Standard_False;
218 if (!aShader->Create (theCtx))
220 aShader->Release (theCtx.operator->());
221 return Standard_False;
224 TCollection_AsciiString aSource = aDeclarations + anIter.Value()->Source();
225 switch (anIter.Value()->Type())
227 case Graphic3d_TOS_VERTEX:
229 aSource = aHeader + TCollection_AsciiString ("#define VERTEX_SHADER\n") + aSource;
232 case Graphic3d_TOS_FRAGMENT:
234 #if defined(GL_ES_VERSION_2_0)
235 TCollection_AsciiString aPrefix (theCtx->hasHighp
236 ? "precision highp float;\n"
237 "precision highp int;\n"
238 : "precision mediump float;\n"
239 "precision mediump int;\n");
240 aSource = aHeader + aPrefix + aSource;
242 aSource = aHeader + aSource;
248 if (!aShader->LoadSource (theCtx, aSource))
250 const TCollection_ExtendedString aMsg = "Error! Failed to set shader source";
251 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
254 GL_DEBUG_SEVERITY_HIGH,
256 aShader->Release (theCtx.operator->());
257 return Standard_False;
260 if (!aShader->Compile (theCtx))
262 TCollection_AsciiString aLog;
263 aShader->FetchInfoLog (theCtx, aLog);
266 aLog = "Compilation log is empty.";
268 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
271 GL_DEBUG_SEVERITY_HIGH,
272 TCollection_ExtendedString ("Failed to compile shader object. Compilation log:\n") + aLog);
273 aShader->Release (theCtx.operator->());
274 return Standard_False;
276 else if (theCtx->caps->glslWarnings)
278 TCollection_AsciiString aLog;
279 aShader->FetchInfoLog (theCtx, aLog);
281 && !aLog.IsEqual ("No errors.\n"))
283 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
284 GL_DEBUG_TYPE_PORTABILITY,
286 GL_DEBUG_SEVERITY_LOW,
287 TCollection_ExtendedString ("Shader compilation log:\n") + aLog);
291 if (!AttachShader (theCtx, aShader))
293 aShader->Release (theCtx.operator->());
294 return Standard_False;
298 // bind locations for pre-defined Vertex Attributes
299 SetAttributeName (theCtx, Graphic3d_TOA_POS, "occVertex");
300 SetAttributeName (theCtx, Graphic3d_TOA_NORM, "occNormal");
301 SetAttributeName (theCtx, Graphic3d_TOA_UV, "occTexCoord");
302 SetAttributeName (theCtx, Graphic3d_TOA_COLOR, "occVertColor");
304 // bind custom Vertex Attributes
305 if (!myProxy.IsNull())
307 for (Graphic3d_ShaderAttributeList::Iterator anAttribIter (myProxy->VertexAttributes());
308 anAttribIter.More(); anAttribIter.Next())
310 SetAttributeName (theCtx, anAttribIter.Value()->Location(), anAttribIter.Value()->Name().ToCString());
316 TCollection_AsciiString aLog;
317 FetchInfoLog (theCtx, aLog);
320 aLog = "Linker log is empty.";
322 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
325 GL_DEBUG_SEVERITY_HIGH,
326 TCollection_ExtendedString ("Failed to link program object! Linker log:\n") + aLog);
327 return Standard_False;
329 else if (theCtx->caps->glslWarnings)
331 TCollection_AsciiString aLog;
332 FetchInfoLog (theCtx, aLog);
334 && !aLog.IsEqual ("No errors.\n"))
336 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
337 GL_DEBUG_TYPE_PORTABILITY,
339 GL_DEBUG_SEVERITY_LOW,
340 TCollection_ExtendedString ("GLSL linker log:\n") + aLog);
344 // set uniform defaults
345 const GLint aLocSampler = GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER);
346 const GLint aLocTexEnable = GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE);
347 if (aLocSampler != INVALID_LOCATION
348 || aLocTexEnable != INVALID_LOCATION)
350 const Handle(OpenGl_ShaderProgram)& anOldProgram = theCtx->ActiveProgram();
351 theCtx->core20fwd->glUseProgram (myProgramID);
352 SetUniform (theCtx, aLocSampler, 0); // GL_TEXTURE0
353 SetUniform (theCtx, aLocTexEnable, 0); // Off
354 theCtx->core20fwd->glUseProgram (!anOldProgram.IsNull() ? anOldProgram->ProgramId() : OpenGl_ShaderProgram::NO_PROGRAM);
357 return Standard_True;
360 // =======================================================================
361 // function : ~OpenGl_ShaderProgram
362 // purpose : Releases resources of shader program
363 // =======================================================================
364 OpenGl_ShaderProgram::~OpenGl_ShaderProgram()
369 // =======================================================================
370 // function : AttachShader
371 // purpose : Attaches shader object to the program object
372 // =======================================================================
373 Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context)& theCtx,
374 const Handle(OpenGl_ShaderObject)& theShader)
376 if (myProgramID == NO_PROGRAM || theShader.IsNull())
378 return Standard_False;
381 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
383 if (theShader == anIter.Value())
385 return Standard_False;
389 myShaderObjects.Append (theShader);
390 theCtx->core20fwd->glAttachShader (myProgramID, theShader->myShaderID);
391 return Standard_True;
394 // =======================================================================
395 // function : DetachShader
396 // purpose : Detaches shader object to the program object
397 // =======================================================================
398 Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context)& theCtx,
399 const Handle(OpenGl_ShaderObject)& theShader)
401 if (myProgramID == NO_PROGRAM
402 || theShader.IsNull())
404 return Standard_False;
407 OpenGl_ShaderList::Iterator anIter (myShaderObjects);
408 while (anIter.More())
410 if (theShader == anIter.Value())
412 myShaderObjects.Remove (anIter);
421 return Standard_False;
424 theCtx->core20fwd->glDetachShader (myProgramID, theShader->myShaderID);
425 return Standard_True;
428 // =======================================================================
430 // purpose : Links the program object
431 // =======================================================================
432 Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx)
434 if (myProgramID == NO_PROGRAM)
436 return Standard_False;
439 GLint aStatus = GL_FALSE;
440 theCtx->core20fwd->glLinkProgram (myProgramID);
441 theCtx->core20fwd->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
442 if (aStatus == GL_FALSE)
444 return Standard_False;
447 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
449 myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]);
451 return Standard_True;
454 // =======================================================================
455 // function : FetchInfoLog
456 // purpose : Fetches information log of the last link operation
457 // =======================================================================
458 Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
459 TCollection_AsciiString& theOutput)
461 if (myProgramID == NO_PROGRAM)
463 return Standard_False;
467 theCtx->core20fwd->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
470 GLchar* aLog = (GLchar*) alloca (aLength);
471 memset (aLog, 0, aLength);
472 theCtx->core20fwd->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
475 return Standard_True;
478 // =======================================================================
479 // function : ApplyVariables
480 // purpose : Fetches uniform variables from proxy shader program
481 // =======================================================================
482 Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Context)& theCtx)
484 if (myProxy.IsNull() || myProxy->Variables().IsEmpty())
486 return Standard_False;
489 for (Graphic3d_ShaderVariableList::Iterator anIter (myProxy->Variables()); anIter.More(); anIter.Next())
491 mySetterSelector.Set (theCtx, anIter.Value(), this);
494 myProxy->ClearVariables();
495 return Standard_True;
498 // =======================================================================
499 // function : ActiveState
500 // purpose : Returns index of last modification for specified state type
501 // =======================================================================
502 Standard_Size OpenGl_ShaderProgram::ActiveState (const OpenGl_UniformStateType theType) const
504 if (theType < MaxStateTypes)
506 return myCurrentState[theType];
511 // =======================================================================
512 // function : UpdateState
513 // purpose : Updates index of last modification for specified state type
514 // =======================================================================
515 void OpenGl_ShaderProgram::UpdateState (const OpenGl_UniformStateType theType,
516 const Standard_Size theIndex)
518 if (theType < MaxStateTypes)
520 myCurrentState[theType] = theIndex;
524 // =======================================================================
525 // function : GetUniformLocation
526 // purpose : Returns location (index) of the specific uniform variable
527 // =======================================================================
528 GLint OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& theCtx,
529 const GLchar* theName) const
531 return myProgramID != NO_PROGRAM
532 ? theCtx->core20fwd->glGetUniformLocation (myProgramID, theName)
536 // =======================================================================
537 // function : GetAttributeLocation
538 // purpose : Returns location (index) of the generic vertex attribute
539 // =======================================================================
540 GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)& theCtx,
541 const GLchar* theName) const
543 return myProgramID != NO_PROGRAM
544 ? theCtx->core20fwd->glGetAttribLocation (myProgramID, theName)
548 // =======================================================================
549 // function : GetStateLocation
550 // purpose : Returns location of the OCCT state uniform variable
551 // =======================================================================
552 GLint OpenGl_ShaderProgram::GetStateLocation (const GLuint theVariable) const
554 if (theVariable < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES)
556 return myStateLocations[theVariable];
558 return INVALID_LOCATION;
561 // =======================================================================
562 // function : GetUniform
563 // purpose : Returns the value of the integer uniform variable
564 // =======================================================================
565 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
566 const GLchar* theName,
567 OpenGl_Vec4i& theValue) const
569 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
572 // =======================================================================
573 // function : GetUniform
574 // purpose : Returns the value of the integer uniform variable
575 // =======================================================================
576 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
578 OpenGl_Vec4i& theValue) const
580 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
582 return Standard_False;
585 theCtx->core20fwd->glGetUniformiv (myProgramID, theLocation, theValue);
586 return Standard_True;
589 // =======================================================================
590 // function : GetUniform
591 // purpose : Returns the value of the floating-point uniform variable
592 // =======================================================================
593 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
594 const GLchar* theName,
595 OpenGl_Vec4& theValue) const
597 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
600 // =======================================================================
601 // function : GetUniform
602 // purpose : Returns the value of the floating-point uniform variable
603 // =======================================================================
604 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
606 OpenGl_Vec4& theValue) const
608 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
610 return Standard_False;
613 theCtx->core20fwd->glGetUniformfv (myProgramID, theLocation, theValue);
614 return Standard_True;
617 // =======================================================================
618 // function : GetAttribute
619 // purpose : Returns the integer vertex attribute
620 // =======================================================================
621 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
622 const GLchar* theName,
623 OpenGl_Vec4i& theValue) const
625 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
628 // =======================================================================
629 // function : GetAttribute
630 // purpose : Returns the integer vertex attribute
631 // =======================================================================
632 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
634 OpenGl_Vec4i& theValue) const
636 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
638 return Standard_False;
641 theCtx->core20fwd->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
642 return Standard_True;
645 // =======================================================================
646 // function : GetAttribute
647 // purpose : Returns the floating-point vertex attribute
648 // =======================================================================
649 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
650 const GLchar* theName,
651 OpenGl_Vec4& theValue) const
653 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
656 // =======================================================================
657 // function : GetAttribute
658 // purpose : Returns the floating-point vertex attribute
659 // =======================================================================
660 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
662 OpenGl_Vec4& theValue) const
664 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
666 return Standard_False;
669 theCtx->core20fwd->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
670 return Standard_True;
673 // =======================================================================
674 // function : SetAttributeName
676 // =======================================================================
677 Standard_Boolean OpenGl_ShaderProgram::SetAttributeName (const Handle(OpenGl_Context)& theCtx,
679 const GLchar* theName)
681 theCtx->core20fwd->glBindAttribLocation (myProgramID, theIndex, theName);
682 return Standard_True;
685 // =======================================================================
686 // function : SetAttribute
688 // =======================================================================
689 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
690 const GLchar* theName,
693 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
696 // =======================================================================
697 // function : SetAttribute
699 // =======================================================================
700 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
704 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
706 return Standard_False;
709 theCtx->core20fwd->glVertexAttrib1f (theIndex, theValue);
710 return Standard_True;
713 // =======================================================================
714 // function : SetAttribute
716 // =======================================================================
717 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
718 const GLchar* theName,
719 const OpenGl_Vec2& theValue)
721 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
724 // =======================================================================
725 // function : SetAttribute
727 // =======================================================================
728 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
730 const OpenGl_Vec2& theValue)
732 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
734 return Standard_False;
737 theCtx->core20fwd->glVertexAttrib2fv (theIndex, theValue);
738 return Standard_True;
741 // =======================================================================
742 // function : SetAttribute
744 // =======================================================================
745 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
746 const GLchar* theName,
747 const OpenGl_Vec3& theValue)
749 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
752 // =======================================================================
753 // function : SetAttribute
755 // =======================================================================
756 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
758 const OpenGl_Vec3& theValue)
760 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
762 return Standard_False;
765 theCtx->core20fwd->glVertexAttrib3fv (theIndex, theValue);
766 return Standard_True;
769 // =======================================================================
770 // function : SetAttribute
772 // =======================================================================
773 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
774 const GLchar* theName,
775 const OpenGl_Vec4& theValue)
777 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
780 // =======================================================================
781 // function : SetAttribute
783 // =======================================================================
784 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
786 const OpenGl_Vec4& theValue)
788 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
790 return Standard_False;
793 theCtx->core20fwd->glVertexAttrib4fv (theIndex, theValue);
794 return Standard_True;
797 // =======================================================================
798 // function : SetUniform
799 // purpose : Specifies the value of the integer uniform variable
800 // =======================================================================
801 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
802 const GLchar* theName,
805 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
808 // =======================================================================
809 // function : SetUniform
810 // purpose : Specifies the value of the integer uniform variable
811 // =======================================================================
812 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
816 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
818 return Standard_False;
821 theCtx->core20fwd->glUniform1i (theLocation, theValue);
822 return Standard_True;
825 // =======================================================================
826 // function : SetUniform
828 // =======================================================================
829 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
830 const GLchar* theName,
831 const OpenGl_Vec2u& theValue)
833 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
836 // =======================================================================
837 // function : SetUniform
839 // =======================================================================
840 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
842 const OpenGl_Vec2u& theValue)
844 if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
846 return Standard_False;
849 #if !defined(GL_ES_VERSION_2_0)
850 theCtx->core32->glUniform2uiv (theLocation, 1, theValue.GetData());
851 return Standard_True;
854 return Standard_False;
858 // =======================================================================
859 // function : SetUniform
861 // =======================================================================
862 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
863 const GLchar* theName,
864 const GLsizei theCount,
865 const OpenGl_Vec2u* theValue)
867 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theCount, theValue);
870 // =======================================================================
871 // function : SetUniform
873 // =======================================================================
874 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
876 const GLsizei theCount,
877 const OpenGl_Vec2u* theValue)
879 if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
881 return Standard_False;
884 #if !defined(GL_ES_VERSION_2_0)
885 theCtx->core32->glUniform2uiv (theLocation, theCount, theValue->GetData());
886 return Standard_True;
890 return Standard_False;
894 // =======================================================================
895 // function : SetUniform
896 // purpose : Specifies the value of the floating-point uniform variable
897 // =======================================================================
898 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
899 const GLchar* theName,
902 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
905 // =======================================================================
906 // function : SetUniform
907 // purpose : Specifies the value of the floating-point uniform variable
908 // =======================================================================
909 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
913 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
915 return Standard_False;
918 theCtx->core20fwd->glUniform1f (theLocation, theValue);
919 return Standard_True;
922 // =======================================================================
923 // function : SetUniform
924 // purpose : Specifies the value of the integer uniform 2D vector
925 // =======================================================================
926 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
927 const GLchar* theName,
928 const OpenGl_Vec2i& theValue)
930 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
933 // =======================================================================
934 // function : SetUniform
935 // purpose : Specifies the value of the integer uniform 2D vector
936 // =======================================================================
937 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
939 const OpenGl_Vec2i& theValue)
941 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
943 return Standard_False;
946 theCtx->core20fwd->glUniform2iv (theLocation, 1, theValue);
947 return Standard_True;
950 // =======================================================================
951 // function : SetUniform
952 // purpose : Specifies the value of the integer uniform 3D vector
953 // =======================================================================
954 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
955 const GLchar* theName,
956 const OpenGl_Vec3i& theValue)
958 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
961 // =======================================================================
962 // function : SetUniform
963 // purpose : Specifies the value of the integer uniform 3D vector
964 // =======================================================================
965 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
967 const OpenGl_Vec3i& theValue)
969 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
971 return Standard_False;
974 theCtx->core20fwd->glUniform3iv (theLocation, 1, theValue);
975 return Standard_True;
978 // =======================================================================
979 // function : SetUniform
980 // purpose : Specifies the value of the integer uniform 4D vector
981 // =======================================================================
982 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
983 const GLchar* theName,
984 const OpenGl_Vec4i& theValue)
986 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
989 // =======================================================================
990 // function : SetUniform
991 // purpose : Specifies the value of the integer uniform 4D vector
992 // =======================================================================
993 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
995 const OpenGl_Vec4i& theValue)
997 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
999 return Standard_False;
1002 theCtx->core20fwd->glUniform4iv (theLocation, 1, theValue);
1003 return Standard_True;
1006 // =======================================================================
1007 // function : SetUniform
1008 // purpose : Specifies the value of the floating-point uniform 2D vector
1009 // =======================================================================
1010 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1011 const GLchar* theName,
1012 const OpenGl_Vec2& theValue)
1014 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1017 // =======================================================================
1018 // function : SetUniform
1019 // purpose : Specifies the value of the floating-point uniform 2D vector
1020 // =======================================================================
1021 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1023 const OpenGl_Vec2& theValue)
1025 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1027 return Standard_False;
1030 theCtx->core20fwd->glUniform2fv (theLocation, 1, theValue);
1031 return Standard_True;
1034 // =======================================================================
1035 // function : SetUniform
1036 // purpose : Specifies the value of the floating-point uniform 3D vector
1037 // =======================================================================
1038 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1039 const GLchar* theName,
1040 const OpenGl_Vec3& theValue)
1042 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1045 // =======================================================================
1046 // function : SetUniform
1047 // purpose : Specifies the value of the floating-point uniform 3D vector
1048 // =======================================================================
1049 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1051 const OpenGl_Vec3& theValue)
1053 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1055 return Standard_False;
1058 theCtx->core20fwd->glUniform3fv (theLocation, 1, theValue);
1059 return Standard_True;
1062 // =======================================================================
1063 // function : SetUniform
1064 // purpose : Specifies the value of the floating-point uniform 4D vector
1065 // =======================================================================
1066 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1067 const GLchar* theName,
1068 const OpenGl_Vec4& theValue)
1070 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1073 // =======================================================================
1074 // function : SetUniform
1075 // purpose : Specifies the value of the floating-point uniform 4D vector
1076 // =======================================================================
1077 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1079 const OpenGl_Vec4& theValue)
1081 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1083 return Standard_False;
1086 theCtx->core20fwd->glUniform4fv (theLocation, 1, theValue);
1087 return Standard_True;
1090 // =======================================================================
1091 // function : SetUniform
1092 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1093 // =======================================================================
1094 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1095 const GLchar* theName,
1096 const OpenGl_Mat4& theValue,
1097 GLboolean theTranspose)
1099 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1102 // =======================================================================
1103 // function : SetUniform
1104 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1105 // =======================================================================
1106 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1108 const OpenGl_Mat4& theValue,
1109 GLboolean theTranspose)
1111 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1113 return Standard_False;
1116 theCtx->core20fwd->glUniformMatrix4fv (theLocation, 1, GL_FALSE, theTranspose ? theValue.Transposed() : theValue);
1117 return Standard_True;
1120 // =======================================================================
1121 // function : SetUniform
1122 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1123 // =======================================================================
1124 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1125 const GLchar* theName,
1126 const OpenGl_Matrix& theValue,
1127 GLboolean theTranspose)
1129 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1132 // =======================================================================
1133 // function : SetUniform
1134 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1135 // =======================================================================
1136 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1138 const OpenGl_Matrix& theValue,
1139 GLboolean theTranspose)
1141 return SetUniform (theCtx, theLocation, OpenGl_Mat4::Map (*theValue.mat), theTranspose);
1144 // =======================================================================
1145 // function : SetUniform
1146 // purpose : Specifies the value of the float uniform array
1147 // =======================================================================
1148 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1151 const Standard_ShortReal* theData)
1153 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1155 return Standard_False;
1158 theCtx->core20fwd->glUniform1fv (theLocation, theCount, theData);
1159 return Standard_True;
1162 // =======================================================================
1163 // function : SetUniform
1164 // purpose : Specifies the value of the float2 uniform array
1165 // =======================================================================
1166 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1169 const OpenGl_Vec2* theData)
1171 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1173 return Standard_False;
1176 theCtx->core20fwd->glUniform2fv (theLocation, theCount, theData[0].GetData());
1177 return Standard_True;
1180 // =======================================================================
1181 // function : SetUniform
1182 // purpose : Specifies the value of the float3 uniform array
1183 // =======================================================================
1184 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1187 const OpenGl_Vec3* theData)
1189 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1191 return Standard_False;
1194 theCtx->core20fwd->glUniform3fv (theLocation, theCount, theData[0].GetData());
1195 return Standard_True;
1198 // =======================================================================
1199 // function : SetUniform
1200 // purpose : Specifies the value of the float4 uniform array
1201 // =======================================================================
1202 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1205 const OpenGl_Vec4* theData)
1207 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1209 return Standard_False;
1212 theCtx->core20fwd->glUniform4fv (theLocation, theCount, theData[0].GetData());
1213 return Standard_True;
1216 // =======================================================================
1217 // function : SetUniform
1218 // purpose : Specifies the value of the integer uniform array
1219 // =======================================================================
1220 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1223 const Standard_Integer* theData)
1225 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1227 return Standard_False;
1230 theCtx->core20fwd->glUniform1iv (theLocation, theCount, theData);
1231 return Standard_True;
1234 // =======================================================================
1235 // function : SetUniform
1236 // purpose : Specifies the value of the int2 uniform array
1237 // =======================================================================
1238 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1241 const OpenGl_Vec2i* theData)
1243 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1245 return Standard_False;
1248 theCtx->core20fwd->glUniform2iv (theLocation, theCount, theData[0].GetData());
1249 return Standard_True;
1252 // =======================================================================
1253 // function : SetUniform
1254 // purpose : Specifies the value of the int3 uniform array
1255 // =======================================================================
1256 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1259 const OpenGl_Vec3i* theData)
1261 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1263 return Standard_False;
1266 theCtx->core20fwd->glUniform3iv (theLocation, theCount, theData[0].GetData());
1267 return Standard_True;
1270 // =======================================================================
1271 // function : SetUniform
1272 // purpose : Specifies the value of the int4 uniform array
1273 // =======================================================================
1274 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1277 const OpenGl_Vec4i* theData)
1279 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1281 return Standard_False;
1284 theCtx->core20fwd->glUniform4iv (theLocation, theCount, theData[0].GetData());
1285 return Standard_True;
1288 // =======================================================================
1289 // function : SetSampler
1290 // purpose : Specifies the value of the sampler uniform variable
1291 // =======================================================================
1292 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1293 const GLchar* theName,
1294 const GLenum theTextureUnit)
1296 return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit);
1299 // =======================================================================
1300 // function : SetSampler
1301 // purpose : Specifies the value of the sampler uniform variable
1302 // =======================================================================
1303 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1305 const GLenum theTextureUnit)
1307 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1309 return Standard_False;
1312 theCtx->core20fwd->glUniform1i (theLocation, theTextureUnit);
1313 return Standard_True;
1316 // =======================================================================
1317 // function : Create
1318 // purpose : Creates new empty shader program of specified type
1319 // =======================================================================
1320 Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx)
1322 if (myProgramID == NO_PROGRAM
1323 && theCtx->core20fwd != NULL)
1325 myProgramID = theCtx->core20fwd->glCreateProgram();
1328 return myProgramID != NO_PROGRAM;
1331 // =======================================================================
1332 // function : Release
1333 // purpose : Destroys shader program
1334 // =======================================================================
1335 void OpenGl_ShaderProgram::Release (OpenGl_Context* theCtx)
1337 if (myProgramID == NO_PROGRAM)
1342 Standard_ASSERT_RETURN (theCtx != NULL,
1343 "OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...",);
1345 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
1347 if (!anIter.Value().IsNull())
1349 anIter.ChangeValue()->Release (theCtx);
1350 anIter.ChangeValue().Nullify();
1354 if (theCtx->core20fwd != NULL
1355 && theCtx->IsValid())
1357 theCtx->core20fwd->glDeleteProgram (myProgramID);
1360 myProgramID = NO_PROGRAM;