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>
28 IMPLEMENT_STANDARD_HANDLE (OpenGl_ShaderProgram, OpenGl_Resource)
29 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderProgram, OpenGl_Resource)
31 OpenGl_VariableSetterSelector OpenGl_ShaderProgram::mySetterSelector = OpenGl_VariableSetterSelector();
33 // Declare OCCT-specific OpenGL/GLSL shader variables
34 Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] =
36 "occModelWorldMatrix", // OpenGl_OCC_MODEL_WORLD_MATRIX
37 "occWorldViewMatrix", // OpenGl_OCC_WORLD_VIEW_MATRIX
38 "occProjectionMatrix", // OpenGl_OCC_PROJECTION_MATRIX
39 "occModelWorldMatrixInverse", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE
40 "occWorldViewMatrixInverse", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE
41 "occProjectionMatrixInverse", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE
42 "occModelWorldMatrixTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE
43 "occWorldViewMatrixTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE
44 "occProjectionMatrixTranspose", // OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE
45 "occModelWorldMatrixInverseTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE
46 "occWorldViewMatrixInverseTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE
47 "occProjectionMatrixInverseTranspose", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE
49 "occClipPlaneEquations", // OpenGl_OCC_CLIP_PLANE_EQUATIONS
50 "occClipPlaneSpaces", // OpenGl_OCC_CLIP_PLANE_SPACES
51 "occClipPlaneCount", // OpenGl_OCC_CLIP_PLANE_COUNT
53 "occLightSourcesCount", // OpenGl_OCC_LIGHT_SOURCE_COUNT
54 "occLightSourcesTypes", // OpenGl_OCC_LIGHT_SOURCE_TYPES
55 "occLightSources", // OpenGl_OCC_LIGHT_SOURCE_PARAMS
56 "occLightAmbient", // OpenGl_OCC_LIGHT_AMBIENT
58 "occActiveSampler", // OpenGl_OCCT_ACTIVE_SAMPLER
59 "occTextureEnable", // OpenGl_OCCT_TEXTURE_ENABLE
60 "occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE
61 "occFrontMaterial", // OpenGl_OCCT_FRONT_MATERIAL
62 "occBackMaterial", // OpenGl_OCCT_BACK_MATERIAL
63 "occColor", // OpenGl_OCCT_COLOR
65 "occPointSize" // OpenGl_OCCT_POINT_SIZE
69 // =======================================================================
70 // function : OpenGl_VariableSetterSelector
71 // purpose : Creates new variable setter selector
72 // =======================================================================
73 OpenGl_VariableSetterSelector::OpenGl_VariableSetterSelector()
75 // Note: Add new variable setters here
76 mySetterList = OpenGl_HashMapInitializer::CreateListOf<size_t, OpenGl_SetterInterface*>
77 (Graphic3d_UniformValueTypeID<int>::ID, new OpenGl_VariableSetter<int>())
78 (Graphic3d_UniformValueTypeID<float>::ID, new OpenGl_VariableSetter<float>())
79 (Graphic3d_UniformValueTypeID<OpenGl_Vec2>::ID, new OpenGl_VariableSetter<OpenGl_Vec2>())
80 (Graphic3d_UniformValueTypeID<OpenGl_Vec3>::ID, new OpenGl_VariableSetter<OpenGl_Vec3>())
81 (Graphic3d_UniformValueTypeID<OpenGl_Vec4>::ID, new OpenGl_VariableSetter<OpenGl_Vec4>())
82 (Graphic3d_UniformValueTypeID<OpenGl_Vec2i>::ID, new OpenGl_VariableSetter<OpenGl_Vec2i>())
83 (Graphic3d_UniformValueTypeID<OpenGl_Vec3i>::ID, new OpenGl_VariableSetter<OpenGl_Vec3i>())
84 (Graphic3d_UniformValueTypeID<OpenGl_Vec4i>::ID, new OpenGl_VariableSetter<OpenGl_Vec4i>());
87 // =======================================================================
88 // function : ~OpenGl_VariableSetterSelector
89 // purpose : Releases memory resources of variable setter selector
90 // =======================================================================
91 OpenGl_VariableSetterSelector::~OpenGl_VariableSetterSelector()
93 for (OpenGl_SetterList::Iterator anIt (mySetterList); anIt.More(); anIt.Next())
101 // =======================================================================
103 // purpose : Sets generic variable to specified shader program
104 // =======================================================================
105 void OpenGl_VariableSetterSelector::Set (const Handle(OpenGl_Context)& theCtx,
106 const Handle(Graphic3d_ShaderVariable)& theVariable,
107 OpenGl_ShaderProgram* theProgram) const
109 Standard_ASSERT_RETURN (mySetterList.IsBound (theVariable->Value()->TypeID()),
110 "The type of user-defined uniform variable is not supported...", );
112 mySetterList.Find (theVariable->Value()->TypeID())->Set (theCtx, theVariable, theProgram);
115 // =======================================================================
116 // function : OpenGl_ShaderProgram
117 // purpose : Creates uninitialized shader program
118 // =======================================================================
119 OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy)
120 : myProgramID (NO_PROGRAM),
124 memset (myCurrentState, 0, sizeof (myCurrentState));
125 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
127 myStateLocations[aVar] = INVALID_LOCATION;
131 // =======================================================================
132 // function : Initialize
133 // purpose : Initializes program object with the list of shader objects
134 // =======================================================================
135 Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& theCtx,
136 const Graphic3d_ShaderObjectList& theShaders)
138 if (theCtx.IsNull() || !Create (theCtx))
140 return Standard_False;
143 OSD_File aDeclFile (Graphic3d_ShaderProgram::ShadersFolder() + "/Declarations.glsl");
144 OSD_File aDeclImplFile (Graphic3d_ShaderProgram::ShadersFolder() + "/DeclarationsImpl.glsl");
145 if (!aDeclFile.Exists()
146 || !aDeclImplFile.Exists())
148 const TCollection_ExtendedString aMsg = "Error! Failed to load OCCT shader declarations file";
149 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
150 GL_DEBUG_TYPE_ERROR_ARB,
152 GL_DEBUG_SEVERITY_HIGH_ARB,
154 return Standard_False;
157 TCollection_AsciiString aDeclarations;
158 aDeclFile.Open (OSD_ReadOnly, OSD_Protection());
159 aDeclFile.Read (aDeclarations, (int)aDeclFile.Size());
162 TCollection_AsciiString aDeclImpl;
163 aDeclImplFile.Open (OSD_ReadOnly, OSD_Protection());
164 aDeclImplFile.Read (aDeclImpl, (int)aDeclImplFile.Size());
165 aDeclImplFile.Close();
166 aDeclarations += aDeclImpl;
168 for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders);
169 anIter.More(); anIter.Next())
171 if (!anIter.Value()->IsDone())
173 const TCollection_ExtendedString aMsg = "Error! Failed to get shader source";
174 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
175 GL_DEBUG_TYPE_ERROR_ARB,
177 GL_DEBUG_SEVERITY_HIGH_ARB,
179 return Standard_False;
182 Handle(OpenGl_ShaderObject) aShader;
184 // Note: Add support of other shader types here
185 switch (anIter.Value()->Type())
187 case Graphic3d_TOS_VERTEX:
188 aShader = new OpenGl_ShaderObject (GL_VERTEX_SHADER);
190 case Graphic3d_TOS_FRAGMENT:
191 aShader = new OpenGl_ShaderObject (GL_FRAGMENT_SHADER);
195 // Is unsupported shader type?
196 if (aShader.IsNull())
198 TCollection_ExtendedString aMsg = "Error! Unsupported shader type";
199 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
200 GL_DEBUG_TYPE_ERROR_ARB,
202 GL_DEBUG_SEVERITY_HIGH_ARB,
204 return Standard_False;
207 if (!aShader->Create (theCtx))
209 aShader->Release (theCtx.operator->());
210 return Standard_False;
213 TCollection_AsciiString aSource = aDeclarations + anIter.Value()->Source();
214 switch (anIter.Value()->Type())
216 case Graphic3d_TOS_VERTEX:
218 aSource = TCollection_AsciiString ("#define VERTEX_SHADER\n") + aSource;
221 case Graphic3d_TOS_FRAGMENT:
223 #if defined(GL_ES_VERSION_2_0)
224 TCollection_AsciiString aPrefix (theCtx->hasHighp
225 ? "precision highp float;\n"
226 : "precision mediump float;\n");
227 aSource = aPrefix + aSource;
233 if (!aShader->LoadSource (theCtx, aSource))
235 const TCollection_ExtendedString aMsg = "Error! Failed to set shader source";
236 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
237 GL_DEBUG_TYPE_ERROR_ARB,
239 GL_DEBUG_SEVERITY_HIGH_ARB,
241 aShader->Release (theCtx.operator->());
242 return Standard_False;
245 if (!aShader->Compile (theCtx))
247 TCollection_AsciiString aLog;
248 aShader->FetchInfoLog (theCtx, aLog);
251 aLog = "Compilation log is empty.";
253 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
254 GL_DEBUG_TYPE_ERROR_ARB,
256 GL_DEBUG_SEVERITY_HIGH_ARB,
257 TCollection_ExtendedString ("Failed to compile shader object. Compilation log:\n") + aLog);
258 aShader->Release (theCtx.operator->());
259 return Standard_False;
261 else if (theCtx->caps->glslWarnings)
263 TCollection_AsciiString aLog;
264 aShader->FetchInfoLog (theCtx, aLog);
266 && !aLog.IsEqual ("No errors.\n"))
268 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
269 GL_DEBUG_TYPE_PORTABILITY_ARB,
271 GL_DEBUG_SEVERITY_LOW_ARB,
272 TCollection_ExtendedString ("Shader compilation log:\n") + aLog);
276 if (!AttachShader (theCtx, aShader))
278 aShader->Release (theCtx.operator->());
279 return Standard_False;
283 // bind locations for pre-defined Vertex Attributes
284 SetAttributeName (theCtx, Graphic3d_TOA_POS, "occVertex");
285 SetAttributeName (theCtx, Graphic3d_TOA_NORM, "occNormal");
286 SetAttributeName (theCtx, Graphic3d_TOA_UV, "occTexCoord");
287 SetAttributeName (theCtx, Graphic3d_TOA_COLOR, "occVertColor");
291 TCollection_AsciiString aLog;
292 FetchInfoLog (theCtx, aLog);
295 aLog = "Linker log is empty.";
297 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
298 GL_DEBUG_TYPE_ERROR_ARB,
300 GL_DEBUG_SEVERITY_HIGH_ARB,
301 TCollection_ExtendedString ("Failed to link program object! Linker log:\n") + aLog);
302 return Standard_False;
304 else if (theCtx->caps->glslWarnings)
306 TCollection_AsciiString aLog;
307 FetchInfoLog (theCtx, aLog);
309 && !aLog.IsEqual ("No errors.\n"))
311 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
312 GL_DEBUG_TYPE_PORTABILITY_ARB,
314 GL_DEBUG_SEVERITY_LOW_ARB,
315 TCollection_ExtendedString ("GLSL linker log:\n") + aLog);
319 return Standard_True;
322 // =======================================================================
323 // function : ~OpenGl_ShaderProgram
324 // purpose : Releases resources of shader program
325 // =======================================================================
326 OpenGl_ShaderProgram::~OpenGl_ShaderProgram()
331 // =======================================================================
332 // function : AttachShader
333 // purpose : Attaches shader object to the program object
334 // =======================================================================
335 Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context)& theCtx,
336 const Handle(OpenGl_ShaderObject)& theShader)
338 if (myProgramID == NO_PROGRAM || theShader.IsNull())
340 return Standard_False;
343 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
345 if (theShader == anIter.Value())
347 return Standard_False;
351 myShaderObjects.Append (theShader);
352 theCtx->core20->glAttachShader (myProgramID, theShader->myShaderID);
353 return Standard_True;
356 // =======================================================================
357 // function : DetachShader
358 // purpose : Detaches shader object to the program object
359 // =======================================================================
360 Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context)& theCtx,
361 const Handle(OpenGl_ShaderObject)& theShader)
363 if (myProgramID == NO_PROGRAM
364 || theShader.IsNull())
366 return Standard_False;
369 OpenGl_ShaderList::Iterator anIter (myShaderObjects);
370 while (anIter.More())
372 if (theShader == anIter.Value())
374 myShaderObjects.Remove (anIter);
383 return Standard_False;
386 theCtx->core20->glDetachShader (myProgramID, theShader->myShaderID);
387 return Standard_True;
390 // =======================================================================
392 // purpose : Links the program object
393 // =======================================================================
394 Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx)
396 if (myProgramID == NO_PROGRAM)
398 return Standard_False;
401 GLint aStatus = GL_FALSE;
402 theCtx->core20->glLinkProgram (myProgramID);
403 theCtx->core20->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
404 if (aStatus == GL_FALSE)
406 return Standard_False;
409 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
411 myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]);
413 return Standard_True;
416 // =======================================================================
417 // function : FetchInfoLog
418 // purpose : Fetches information log of the last link operation
419 // =======================================================================
420 Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
421 TCollection_AsciiString& theOutput)
423 if (myProgramID == NO_PROGRAM)
425 return Standard_False;
429 theCtx->core20->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
432 GLchar* aLog = (GLchar*) alloca (aLength);
433 memset (aLog, 0, aLength);
434 theCtx->core20->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
437 return Standard_True;
440 // =======================================================================
441 // function : ApplyVariables
442 // purpose : Fetches uniform variables from proxy shader program
443 // =======================================================================
444 Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Context)& theCtx)
446 if (myProxy.IsNull() || myProxy->Variables().IsEmpty())
448 return Standard_False;
451 for (Graphic3d_ShaderVariableList::Iterator anIter (myProxy->Variables()); anIter.More(); anIter.Next())
453 mySetterSelector.Set (theCtx, anIter.Value(), this);
456 myProxy->ClearVariables();
457 return Standard_True;
460 // =======================================================================
461 // function : ActiveState
462 // purpose : Returns index of last modification for specified state type
463 // =======================================================================
464 Standard_Size OpenGl_ShaderProgram::ActiveState (const OpenGl_UniformStateType theType) const
466 if (theType < MaxStateTypes)
468 return myCurrentState[theType];
473 // =======================================================================
474 // function : UpdateState
475 // purpose : Updates index of last modification for specified state type
476 // =======================================================================
477 void OpenGl_ShaderProgram::UpdateState (const OpenGl_UniformStateType theType,
478 const Standard_Size theIndex)
480 if (theType < MaxStateTypes)
482 myCurrentState[theType] = theIndex;
486 // =======================================================================
487 // function : GetUniformLocation
488 // purpose : Returns location (index) of the specific uniform variable
489 // =======================================================================
490 GLint OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& theCtx,
491 const GLchar* theName) const
493 return myProgramID != NO_PROGRAM
494 ? theCtx->core20->glGetUniformLocation (myProgramID, theName)
498 // =======================================================================
499 // function : GetAttributeLocation
500 // purpose : Returns location (index) of the generic vertex attribute
501 // =======================================================================
502 GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)& theCtx,
503 const GLchar* theName) const
505 return myProgramID != NO_PROGRAM
506 ? theCtx->core20->glGetAttribLocation (myProgramID, theName)
510 // =======================================================================
511 // function : GetStateLocation
512 // purpose : Returns location of the OCCT state uniform variable
513 // =======================================================================
514 GLint OpenGl_ShaderProgram::GetStateLocation (const GLuint theVariable) const
516 if (theVariable < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES)
518 return myStateLocations[theVariable];
520 return INVALID_LOCATION;
523 // =======================================================================
524 // function : GetUniform
525 // purpose : Returns the value of the integer uniform variable
526 // =======================================================================
527 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
528 const GLchar* theName,
529 OpenGl_Vec4i& theValue) const
531 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
534 // =======================================================================
535 // function : GetUniform
536 // purpose : Returns the value of the integer uniform variable
537 // =======================================================================
538 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
540 OpenGl_Vec4i& theValue) const
542 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
544 return Standard_False;
547 theCtx->core20->glGetUniformiv (myProgramID, theLocation, theValue);
548 return Standard_True;
551 // =======================================================================
552 // function : GetUniform
553 // purpose : Returns the value of the floating-point uniform variable
554 // =======================================================================
555 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
556 const GLchar* theName,
557 OpenGl_Vec4& theValue) const
559 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
562 // =======================================================================
563 // function : GetUniform
564 // purpose : Returns the value of the floating-point uniform variable
565 // =======================================================================
566 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
568 OpenGl_Vec4& theValue) const
570 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
572 return Standard_False;
575 theCtx->core20->glGetUniformfv (myProgramID, theLocation, theValue);
576 return Standard_True;
579 // =======================================================================
580 // function : GetAttribute
581 // purpose : Returns the integer vertex attribute
582 // =======================================================================
583 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
584 const GLchar* theName,
585 OpenGl_Vec4i& theValue) const
587 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
590 // =======================================================================
591 // function : GetAttribute
592 // purpose : Returns the integer vertex attribute
593 // =======================================================================
594 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
596 OpenGl_Vec4i& theValue) const
598 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
600 return Standard_False;
603 theCtx->core20->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
604 return Standard_True;
607 // =======================================================================
608 // function : GetAttribute
609 // purpose : Returns the floating-point vertex attribute
610 // =======================================================================
611 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
612 const GLchar* theName,
613 OpenGl_Vec4& theValue) const
615 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
618 // =======================================================================
619 // function : GetAttribute
620 // purpose : Returns the floating-point vertex attribute
621 // =======================================================================
622 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
624 OpenGl_Vec4& theValue) const
626 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
628 return Standard_False;
631 theCtx->core20->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
632 return Standard_True;
635 // =======================================================================
636 // function : SetAttributeName
638 // =======================================================================
639 Standard_Boolean OpenGl_ShaderProgram::SetAttributeName (const Handle(OpenGl_Context)& theCtx,
641 const GLchar* theName)
643 theCtx->core20fwd->glBindAttribLocation (myProgramID, theIndex, theName);
644 return Standard_True;
647 // =======================================================================
648 // function : SetAttribute
650 // =======================================================================
651 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
652 const GLchar* theName,
655 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
658 // =======================================================================
659 // function : SetAttribute
661 // =======================================================================
662 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
666 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
668 return Standard_False;
671 theCtx->core20fwd->glVertexAttrib1f (theIndex, theValue);
672 return Standard_True;
675 // =======================================================================
676 // function : SetAttribute
678 // =======================================================================
679 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
680 const GLchar* theName,
681 const OpenGl_Vec2& theValue)
683 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
686 // =======================================================================
687 // function : SetAttribute
689 // =======================================================================
690 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
692 const OpenGl_Vec2& theValue)
694 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
696 return Standard_False;
699 theCtx->core20fwd->glVertexAttrib2fv (theIndex, theValue);
700 return Standard_True;
703 // =======================================================================
704 // function : SetAttribute
706 // =======================================================================
707 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
708 const GLchar* theName,
709 const OpenGl_Vec3& theValue)
711 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
714 // =======================================================================
715 // function : SetAttribute
717 // =======================================================================
718 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
720 const OpenGl_Vec3& theValue)
722 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
724 return Standard_False;
727 theCtx->core20fwd->glVertexAttrib3fv (theIndex, theValue);
728 return Standard_True;
731 // =======================================================================
732 // function : SetAttribute
734 // =======================================================================
735 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
736 const GLchar* theName,
737 const OpenGl_Vec4& theValue)
739 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
742 // =======================================================================
743 // function : SetAttribute
745 // =======================================================================
746 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
748 const OpenGl_Vec4& theValue)
750 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
752 return Standard_False;
755 theCtx->core20fwd->glVertexAttrib4fv (theIndex, theValue);
756 return Standard_True;
759 // =======================================================================
760 // function : SetUniform
761 // purpose : Specifies the value of the integer uniform variable
762 // =======================================================================
763 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
764 const GLchar* theName,
767 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
770 // =======================================================================
771 // function : SetUniform
772 // purpose : Specifies the value of the integer uniform variable
773 // =======================================================================
774 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
778 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
780 return Standard_False;
783 theCtx->core20->glUniform1i (theLocation, theValue);
784 return Standard_True;
787 // =======================================================================
788 // function : SetUniform
789 // purpose : Specifies the value of the floating-point uniform variable
790 // =======================================================================
791 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
792 const GLchar* theName,
795 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
798 // =======================================================================
799 // function : SetUniform
800 // purpose : Specifies the value of the floating-point uniform variable
801 // =======================================================================
802 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
806 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
808 return Standard_False;
811 theCtx->core20->glUniform1f (theLocation, theValue);
812 return Standard_True;
815 // =======================================================================
816 // function : SetUniform
817 // purpose : Specifies the value of the integer uniform 2D vector
818 // =======================================================================
819 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
820 const GLchar* theName,
821 const OpenGl_Vec2i& theValue)
823 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
826 // =======================================================================
827 // function : SetUniform
828 // purpose : Specifies the value of the integer uniform 2D vector
829 // =======================================================================
830 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
832 const OpenGl_Vec2i& theValue)
834 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
836 return Standard_False;
839 theCtx->core20->glUniform2iv (theLocation, 1, theValue);
840 return Standard_True;
843 // =======================================================================
844 // function : SetUniform
845 // purpose : Specifies the value of the integer uniform 3D vector
846 // =======================================================================
847 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
848 const GLchar* theName,
849 const OpenGl_Vec3i& theValue)
851 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
854 // =======================================================================
855 // function : SetUniform
856 // purpose : Specifies the value of the integer uniform 3D vector
857 // =======================================================================
858 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
860 const OpenGl_Vec3i& theValue)
862 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
864 return Standard_False;
867 theCtx->core20->glUniform3iv (theLocation, 1, theValue);
868 return Standard_True;
871 // =======================================================================
872 // function : SetUniform
873 // purpose : Specifies the value of the integer uniform 4D vector
874 // =======================================================================
875 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
876 const GLchar* theName,
877 const OpenGl_Vec4i& theValue)
879 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
882 // =======================================================================
883 // function : SetUniform
884 // purpose : Specifies the value of the integer uniform 4D vector
885 // =======================================================================
886 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
888 const OpenGl_Vec4i& theValue)
890 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
892 return Standard_False;
895 theCtx->core20->glUniform4iv (theLocation, 1, theValue);
896 return Standard_True;
899 // =======================================================================
900 // function : SetUniform
901 // purpose : Specifies the value of the floating-point uniform 2D vector
902 // =======================================================================
903 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
904 const GLchar* theName,
905 const OpenGl_Vec2& theValue)
907 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
910 // =======================================================================
911 // function : SetUniform
912 // purpose : Specifies the value of the floating-point uniform 2D vector
913 // =======================================================================
914 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
916 const OpenGl_Vec2& theValue)
918 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
920 return Standard_False;
923 theCtx->core20->glUniform2fv (theLocation, 1, theValue);
924 return Standard_True;
927 // =======================================================================
928 // function : SetUniform
929 // purpose : Specifies the value of the floating-point uniform 3D vector
930 // =======================================================================
931 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
932 const GLchar* theName,
933 const OpenGl_Vec3& theValue)
935 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
938 // =======================================================================
939 // function : SetUniform
940 // purpose : Specifies the value of the floating-point uniform 3D vector
941 // =======================================================================
942 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
944 const OpenGl_Vec3& theValue)
946 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
948 return Standard_False;
951 theCtx->core20->glUniform3fv (theLocation, 1, theValue);
952 return Standard_True;
955 // =======================================================================
956 // function : SetUniform
957 // purpose : Specifies the value of the floating-point uniform 4D vector
958 // =======================================================================
959 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
960 const GLchar* theName,
961 const OpenGl_Vec4& theValue)
963 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
966 // =======================================================================
967 // function : SetUniform
968 // purpose : Specifies the value of the floating-point uniform 4D vector
969 // =======================================================================
970 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
972 const OpenGl_Vec4& theValue)
974 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
976 return Standard_False;
979 theCtx->core20->glUniform4fv (theLocation, 1, theValue);
980 return Standard_True;
983 // =======================================================================
984 // function : SetUniform
985 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
986 // =======================================================================
987 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
988 const GLchar* theName,
989 const OpenGl_Matrix& theValue,
990 GLboolean theTranspose)
992 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
995 // =======================================================================
996 // function : SetUniform
997 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
998 // =======================================================================
999 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1001 const OpenGl_Matrix& theValue,
1002 GLboolean theTranspose)
1004 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1006 return Standard_False;
1009 theCtx->core20->glUniformMatrix4fv (theLocation, 1, theTranspose, *theValue.mat);
1010 return Standard_True;
1013 // =======================================================================
1014 // function : SetUniform
1015 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1016 // =======================================================================
1017 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1018 const GLchar* theName,
1019 const Tmatrix3& theValue,
1020 GLboolean theTranspose)
1022 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1025 // =======================================================================
1026 // function : SetUniform
1027 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1028 // =======================================================================
1029 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1031 const Tmatrix3& theValue,
1032 GLboolean theTranspose)
1034 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1036 return Standard_False;
1039 theCtx->core20->glUniformMatrix4fv (theLocation, 1, theTranspose, *theValue);
1040 return Standard_True;
1043 // =======================================================================
1044 // function : SetUniform
1045 // purpose : Specifies the value of the float uniform array
1046 // =======================================================================
1047 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1050 const Standard_ShortReal* theData)
1052 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1054 return Standard_False;
1057 theCtx->core20->glUniform1fv (theLocation, theCount, theData);
1058 return Standard_True;
1061 // =======================================================================
1062 // function : SetUniform
1063 // purpose : Specifies the value of the float2 uniform array
1064 // =======================================================================
1065 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1068 const OpenGl_Vec2* theData)
1070 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1072 return Standard_False;
1075 theCtx->core20->glUniform2fv (theLocation, theCount, theData[0].GetData());
1076 return Standard_True;
1079 // =======================================================================
1080 // function : SetUniform
1081 // purpose : Specifies the value of the float3 uniform array
1082 // =======================================================================
1083 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1086 const OpenGl_Vec3* theData)
1088 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1090 return Standard_False;
1093 theCtx->core20->glUniform3fv (theLocation, theCount, theData[0].GetData());
1094 return Standard_True;
1097 // =======================================================================
1098 // function : SetUniform
1099 // purpose : Specifies the value of the float4 uniform array
1100 // =======================================================================
1101 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1104 const OpenGl_Vec4* theData)
1106 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1108 return Standard_False;
1111 theCtx->core20->glUniform4fv (theLocation, theCount, theData[0].GetData());
1112 return Standard_True;
1115 // =======================================================================
1116 // function : SetUniform
1117 // purpose : Specifies the value of the integer uniform array
1118 // =======================================================================
1119 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1122 const Standard_Integer* theData)
1124 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1126 return Standard_False;
1129 theCtx->core20->glUniform1iv (theLocation, theCount, theData);
1130 return Standard_True;
1133 // =======================================================================
1134 // function : SetUniform
1135 // purpose : Specifies the value of the int2 uniform array
1136 // =======================================================================
1137 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1140 const OpenGl_Vec2i* theData)
1142 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1144 return Standard_False;
1147 theCtx->core20->glUniform2iv (theLocation, theCount, theData[0].GetData());
1148 return Standard_True;
1151 // =======================================================================
1152 // function : SetUniform
1153 // purpose : Specifies the value of the int3 uniform array
1154 // =======================================================================
1155 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1158 const OpenGl_Vec3i* theData)
1160 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1162 return Standard_False;
1165 theCtx->core20->glUniform3iv (theLocation, theCount, theData[0].GetData());
1166 return Standard_True;
1169 // =======================================================================
1170 // function : SetUniform
1171 // purpose : Specifies the value of the int4 uniform array
1172 // =======================================================================
1173 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1176 const OpenGl_Vec4i* theData)
1178 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1180 return Standard_False;
1183 theCtx->core20->glUniform4iv (theLocation, theCount, theData[0].GetData());
1184 return Standard_True;
1187 // =======================================================================
1188 // function : SetSampler
1189 // purpose : Specifies the value of the sampler uniform variable
1190 // =======================================================================
1191 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1192 const GLchar* theName,
1193 const GLenum theTextureUnit)
1195 return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit);
1198 // =======================================================================
1199 // function : SetSampler
1200 // purpose : Specifies the value of the sampler uniform variable
1201 // =======================================================================
1202 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1204 const GLenum theTextureUnit)
1206 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1208 return Standard_False;
1211 theCtx->core20->glUniform1i (theLocation, theTextureUnit);
1212 return Standard_True;
1215 // =======================================================================
1216 // function : Create
1217 // purpose : Creates new empty shader program of specified type
1218 // =======================================================================
1219 Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx)
1221 if (myProgramID == NO_PROGRAM
1222 && theCtx->core20 != NULL)
1224 myProgramID = theCtx->core20->glCreateProgram();
1227 return myProgramID != NO_PROGRAM;
1230 // =======================================================================
1231 // function : Release
1232 // purpose : Destroys shader program
1233 // =======================================================================
1234 void OpenGl_ShaderProgram::Release (OpenGl_Context* theCtx)
1236 if (myProgramID == NO_PROGRAM)
1241 Standard_ASSERT_RETURN (theCtx != NULL,
1242 "OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...",);
1244 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
1246 if (!anIter.Value().IsNull())
1248 anIter.ChangeValue()->Release (theCtx);
1249 anIter.ChangeValue().Nullify();
1253 if (theCtx->core20 != NULL
1254 && theCtx->IsValid())
1256 theCtx->core20->glDeleteProgram (myProgramID);
1259 myProgramID = NO_PROGRAM;