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
66 // =======================================================================
67 // function : OpenGl_VariableSetterSelector
68 // purpose : Creates new variable setter selector
69 // =======================================================================
70 OpenGl_VariableSetterSelector::OpenGl_VariableSetterSelector()
72 // Note: Add new variable setters here
73 mySetterList = OpenGl_HashMapInitializer::CreateListOf<size_t, OpenGl_SetterInterface*>
74 (Graphic3d_UniformValueTypeID<int>::ID, new OpenGl_VariableSetter<int>())
75 (Graphic3d_UniformValueTypeID<float>::ID, new OpenGl_VariableSetter<float>())
76 (Graphic3d_UniformValueTypeID<OpenGl_Vec2>::ID, new OpenGl_VariableSetter<OpenGl_Vec2>())
77 (Graphic3d_UniformValueTypeID<OpenGl_Vec3>::ID, new OpenGl_VariableSetter<OpenGl_Vec3>())
78 (Graphic3d_UniformValueTypeID<OpenGl_Vec4>::ID, new OpenGl_VariableSetter<OpenGl_Vec4>())
79 (Graphic3d_UniformValueTypeID<OpenGl_Vec2i>::ID, new OpenGl_VariableSetter<OpenGl_Vec2i>())
80 (Graphic3d_UniformValueTypeID<OpenGl_Vec3i>::ID, new OpenGl_VariableSetter<OpenGl_Vec3i>())
81 (Graphic3d_UniformValueTypeID<OpenGl_Vec4i>::ID, new OpenGl_VariableSetter<OpenGl_Vec4i>());
84 // =======================================================================
85 // function : ~OpenGl_VariableSetterSelector
86 // purpose : Releases memory resources of variable setter selector
87 // =======================================================================
88 OpenGl_VariableSetterSelector::~OpenGl_VariableSetterSelector()
90 for (OpenGl_SetterList::Iterator anIt (mySetterList); anIt.More(); anIt.Next())
98 // =======================================================================
100 // purpose : Sets generic variable to specified shader program
101 // =======================================================================
102 void OpenGl_VariableSetterSelector::Set (const Handle(OpenGl_Context)& theCtx,
103 const Handle(Graphic3d_ShaderVariable)& theVariable,
104 OpenGl_ShaderProgram* theProgram) const
106 Standard_ASSERT_RETURN (mySetterList.IsBound (theVariable->Value()->TypeID()),
107 "The type of user-defined uniform variable is not supported...", );
109 mySetterList.Find (theVariable->Value()->TypeID())->Set (theCtx, theVariable, theProgram);
112 // =======================================================================
113 // function : OpenGl_ShaderProgram
114 // purpose : Creates uninitialized shader program
115 // =======================================================================
116 OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy)
117 : myProgramID (NO_PROGRAM),
121 memset (myCurrentState, 0, sizeof (myCurrentState));
122 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
124 myStateLocations[aVar] = INVALID_LOCATION;
128 // =======================================================================
129 // function : Initialize
130 // purpose : Initializes program object with the list of shader objects
131 // =======================================================================
132 Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& theCtx,
133 const Graphic3d_ShaderObjectList& theShaders)
135 if (theCtx.IsNull() || !Create (theCtx))
137 return Standard_False;
140 OSD_File aDeclFile (Graphic3d_ShaderProgram::ShadersFolder() + "/Declarations.glsl");
141 OSD_File aDeclImplFile (Graphic3d_ShaderProgram::ShadersFolder() + "/DeclarationsImpl.glsl");
142 if (!aDeclFile.Exists()
143 || !aDeclImplFile.Exists())
145 const TCollection_ExtendedString aMsg = "Error! Failed to load OCCT shader declarations file";
146 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
147 GL_DEBUG_TYPE_ERROR_ARB,
149 GL_DEBUG_SEVERITY_HIGH_ARB,
151 return Standard_False;
154 TCollection_AsciiString aDeclarations;
155 aDeclFile.Open (OSD_ReadOnly, OSD_Protection());
156 aDeclFile.Read (aDeclarations, (int)aDeclFile.Size());
159 TCollection_AsciiString aDeclImpl;
160 aDeclImplFile.Open (OSD_ReadOnly, OSD_Protection());
161 aDeclImplFile.Read (aDeclImpl, (int)aDeclImplFile.Size());
162 aDeclImplFile.Close();
163 aDeclarations += aDeclImpl;
165 for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders);
166 anIter.More(); anIter.Next())
168 if (!anIter.Value()->IsDone())
170 const TCollection_ExtendedString aMsg = "Error! Failed to get shader source";
171 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
172 GL_DEBUG_TYPE_ERROR_ARB,
174 GL_DEBUG_SEVERITY_HIGH_ARB,
176 return Standard_False;
179 Handle(OpenGl_ShaderObject) aShader;
181 // Note: Add support of other shader types here
182 switch (anIter.Value()->Type())
184 case Graphic3d_TOS_VERTEX:
185 aShader = new OpenGl_ShaderObject (GL_VERTEX_SHADER);
187 case Graphic3d_TOS_FRAGMENT:
188 aShader = new OpenGl_ShaderObject (GL_FRAGMENT_SHADER);
192 // Is unsupported shader type?
193 if (aShader.IsNull())
195 TCollection_ExtendedString aMsg = "Error! Unsupported shader type";
196 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
197 GL_DEBUG_TYPE_ERROR_ARB,
199 GL_DEBUG_SEVERITY_HIGH_ARB,
201 return Standard_False;
204 if (!aShader->Create (theCtx))
206 aShader->Release (theCtx.operator->());
207 return Standard_False;
210 TCollection_AsciiString aSource = aDeclarations + anIter.Value()->Source();
211 if (anIter.Value()->Type() == Graphic3d_TOS_VERTEX)
213 aSource = TCollection_AsciiString ("#define VERTEX_SHADER\n") + aSource;
216 if (!aShader->LoadSource (theCtx, aSource))
218 const TCollection_ExtendedString aMsg = "Error! Failed to set shader source";
219 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
220 GL_DEBUG_TYPE_ERROR_ARB,
222 GL_DEBUG_SEVERITY_HIGH_ARB,
224 aShader->Release (theCtx.operator->());
225 return Standard_False;
228 if (!aShader->Compile (theCtx))
230 TCollection_AsciiString aLog;
231 aShader->FetchInfoLog (theCtx, aLog);
234 aLog = "Compilation log is empty.";
236 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
237 GL_DEBUG_TYPE_ERROR_ARB,
239 GL_DEBUG_SEVERITY_HIGH_ARB,
240 TCollection_ExtendedString ("Failed to compile shader object. Compilation log:\n") + aLog);
241 aShader->Release (theCtx.operator->());
242 return Standard_False;
244 else if (theCtx->caps->glslWarnings)
246 TCollection_AsciiString aLog;
247 aShader->FetchInfoLog (theCtx, aLog);
249 && !aLog.IsEqual ("No errors.\n"))
251 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
252 GL_DEBUG_TYPE_PORTABILITY_ARB,
254 GL_DEBUG_SEVERITY_LOW_ARB,
255 TCollection_ExtendedString ("Shader compilation log:\n") + aLog);
259 if (!AttachShader (theCtx, aShader))
261 aShader->Release (theCtx.operator->());
262 return Standard_False;
266 // bind locations for pre-defined Vertex Attributes
267 SetAttributeName (theCtx, Graphic3d_TOA_POS, "occVertex");
268 SetAttributeName (theCtx, Graphic3d_TOA_NORM, "occNormal");
269 SetAttributeName (theCtx, Graphic3d_TOA_UV, "occTexCoord");
270 SetAttributeName (theCtx, Graphic3d_TOA_COLOR, "occColor");
274 TCollection_AsciiString aLog;
275 FetchInfoLog (theCtx, aLog);
278 aLog = "Linker log is empty.";
280 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
281 GL_DEBUG_TYPE_ERROR_ARB,
283 GL_DEBUG_SEVERITY_HIGH_ARB,
284 TCollection_ExtendedString ("Failed to link program object! Linker log:\n") + aLog);
285 return Standard_False;
287 else if (theCtx->caps->glslWarnings)
289 TCollection_AsciiString aLog;
290 FetchInfoLog (theCtx, aLog);
292 && !aLog.IsEqual ("No errors.\n"))
294 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
295 GL_DEBUG_TYPE_PORTABILITY_ARB,
297 GL_DEBUG_SEVERITY_LOW_ARB,
298 TCollection_ExtendedString ("GLSL linker log:\n") + aLog);
302 return Standard_True;
305 // =======================================================================
306 // function : ~OpenGl_ShaderProgram
307 // purpose : Releases resources of shader program
308 // =======================================================================
309 OpenGl_ShaderProgram::~OpenGl_ShaderProgram()
314 // =======================================================================
315 // function : AttachShader
316 // purpose : Attaches shader object to the program object
317 // =======================================================================
318 Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context)& theCtx,
319 const Handle(OpenGl_ShaderObject)& theShader)
321 if (myProgramID == NO_PROGRAM || theShader.IsNull())
323 return Standard_False;
326 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
328 if (theShader == anIter.Value())
330 return Standard_False;
334 myShaderObjects.Append (theShader);
335 theCtx->core20->glAttachShader (myProgramID, theShader->myShaderID);
336 return Standard_True;
339 // =======================================================================
340 // function : DetachShader
341 // purpose : Detaches shader object to the program object
342 // =======================================================================
343 Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context)& theCtx,
344 const Handle(OpenGl_ShaderObject)& theShader)
346 if (myProgramID == NO_PROGRAM
347 || theShader.IsNull())
349 return Standard_False;
352 OpenGl_ShaderList::Iterator anIter (myShaderObjects);
353 while (anIter.More())
355 if (theShader == anIter.Value())
357 myShaderObjects.Remove (anIter);
366 return Standard_False;
369 theCtx->core20->glDetachShader (myProgramID, theShader->myShaderID);
370 return Standard_True;
373 // =======================================================================
375 // purpose : Links the program object
376 // =======================================================================
377 Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx)
379 if (myProgramID == NO_PROGRAM)
381 return Standard_False;
384 GLint aStatus = GL_FALSE;
385 theCtx->core20->glLinkProgram (myProgramID);
386 theCtx->core20->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
387 if (aStatus == GL_FALSE)
389 return Standard_False;
392 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
394 myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]);
396 return Standard_True;
399 // =======================================================================
400 // function : FetchInfoLog
401 // purpose : Fetches information log of the last link operation
402 // =======================================================================
403 Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
404 TCollection_AsciiString& theOutput)
406 if (myProgramID == NO_PROGRAM)
408 return Standard_False;
412 theCtx->core20->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
415 GLchar* aLog = (GLchar*) alloca (aLength);
416 memset (aLog, 0, aLength);
417 theCtx->core20->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
420 return Standard_True;
423 // =======================================================================
424 // function : ApplyVariables
425 // purpose : Fetches uniform variables from proxy shader program
426 // =======================================================================
427 Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Context)& theCtx)
429 if (myProxy.IsNull() || myProxy->Variables().IsEmpty())
431 return Standard_False;
434 for (Graphic3d_ShaderVariableList::Iterator anIter (myProxy->Variables()); anIter.More(); anIter.Next())
436 mySetterSelector.Set (theCtx, anIter.Value(), this);
439 myProxy->ClearVariables();
440 return Standard_True;
443 // =======================================================================
444 // function : ActiveState
445 // purpose : Returns index of last modification for specified state type
446 // =======================================================================
447 Standard_Size OpenGl_ShaderProgram::ActiveState (const OpenGl_UniformStateType theType) const
449 if (theType < MaxStateTypes)
451 return myCurrentState[theType];
456 // =======================================================================
457 // function : UpdateState
458 // purpose : Updates index of last modification for specified state type
459 // =======================================================================
460 void OpenGl_ShaderProgram::UpdateState (const OpenGl_UniformStateType theType,
461 const Standard_Size theIndex)
463 if (theType < MaxStateTypes)
465 myCurrentState[theType] = theIndex;
469 // =======================================================================
470 // function : GetUniformLocation
471 // purpose : Returns location (index) of the specific uniform variable
472 // =======================================================================
473 GLint OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& theCtx,
474 const GLchar* theName) const
476 return myProgramID != NO_PROGRAM
477 ? theCtx->core20->glGetUniformLocation (myProgramID, theName)
481 // =======================================================================
482 // function : GetAttributeLocation
483 // purpose : Returns location (index) of the generic vertex attribute
484 // =======================================================================
485 GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)& theCtx,
486 const GLchar* theName) const
488 return myProgramID != NO_PROGRAM
489 ? theCtx->core20->glGetAttribLocation (myProgramID, theName)
493 // =======================================================================
494 // function : GetStateLocation
495 // purpose : Returns location of the OCCT state uniform variable
496 // =======================================================================
497 GLint OpenGl_ShaderProgram::GetStateLocation (const GLuint theVariable) const
499 if (theVariable < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES)
501 return myStateLocations[theVariable];
503 return INVALID_LOCATION;
506 // =======================================================================
507 // function : GetUniform
508 // purpose : Returns the value of the integer uniform variable
509 // =======================================================================
510 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
511 const GLchar* theName,
512 OpenGl_Vec4i& theValue) const
514 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
517 // =======================================================================
518 // function : GetUniform
519 // purpose : Returns the value of the integer uniform variable
520 // =======================================================================
521 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
523 OpenGl_Vec4i& theValue) const
525 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
527 return Standard_False;
530 theCtx->core20->glGetUniformiv (myProgramID, theLocation, theValue);
531 return Standard_True;
534 // =======================================================================
535 // function : GetUniform
536 // purpose : Returns the value of the floating-point uniform variable
537 // =======================================================================
538 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
539 const GLchar* theName,
540 OpenGl_Vec4& theValue) const
542 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
545 // =======================================================================
546 // function : GetUniform
547 // purpose : Returns the value of the floating-point uniform variable
548 // =======================================================================
549 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
551 OpenGl_Vec4& theValue) const
553 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
555 return Standard_False;
558 theCtx->core20->glGetUniformfv (myProgramID, theLocation, theValue);
559 return Standard_True;
562 // =======================================================================
563 // function : GetAttribute
564 // purpose : Returns the integer vertex attribute
565 // =======================================================================
566 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
567 const GLchar* theName,
568 OpenGl_Vec4i& theValue) const
570 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
573 // =======================================================================
574 // function : GetAttribute
575 // purpose : Returns the integer vertex attribute
576 // =======================================================================
577 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
579 OpenGl_Vec4i& theValue) const
581 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
583 return Standard_False;
586 theCtx->core20->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
587 return Standard_True;
590 // =======================================================================
591 // function : GetAttribute
592 // purpose : Returns the floating-point vertex attribute
593 // =======================================================================
594 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
595 const GLchar* theName,
596 OpenGl_Vec4& theValue) const
598 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
601 // =======================================================================
602 // function : GetAttribute
603 // purpose : Returns the floating-point vertex attribute
604 // =======================================================================
605 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
607 OpenGl_Vec4& theValue) const
609 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
611 return Standard_False;
614 theCtx->core20->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
615 return Standard_True;
618 // =======================================================================
619 // function : SetAttributeName
621 // =======================================================================
622 Standard_Boolean OpenGl_ShaderProgram::SetAttributeName (const Handle(OpenGl_Context)& theCtx,
624 const GLchar* theName)
626 theCtx->core20fwd->glBindAttribLocation (myProgramID, theIndex, theName);
627 return Standard_True;
630 // =======================================================================
631 // function : SetAttribute
633 // =======================================================================
634 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
635 const GLchar* theName,
638 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
641 // =======================================================================
642 // function : SetAttribute
644 // =======================================================================
645 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
649 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
651 return Standard_False;
654 theCtx->core20fwd->glVertexAttrib1f (theIndex, theValue);
655 return Standard_True;
658 // =======================================================================
659 // function : SetAttribute
661 // =======================================================================
662 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
663 const GLchar* theName,
664 const OpenGl_Vec2& theValue)
666 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
669 // =======================================================================
670 // function : SetAttribute
672 // =======================================================================
673 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
675 const OpenGl_Vec2& theValue)
677 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
679 return Standard_False;
682 theCtx->core20fwd->glVertexAttrib2fv (theIndex, theValue);
683 return Standard_True;
686 // =======================================================================
687 // function : SetAttribute
689 // =======================================================================
690 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
691 const GLchar* theName,
692 const OpenGl_Vec3& theValue)
694 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
697 // =======================================================================
698 // function : SetAttribute
700 // =======================================================================
701 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
703 const OpenGl_Vec3& theValue)
705 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
707 return Standard_False;
710 theCtx->core20fwd->glVertexAttrib3fv (theIndex, theValue);
711 return Standard_True;
714 // =======================================================================
715 // function : SetAttribute
717 // =======================================================================
718 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
719 const GLchar* theName,
720 const OpenGl_Vec4& theValue)
722 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
725 // =======================================================================
726 // function : SetAttribute
728 // =======================================================================
729 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
731 const OpenGl_Vec4& theValue)
733 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
735 return Standard_False;
738 theCtx->core20fwd->glVertexAttrib4fv (theIndex, theValue);
739 return Standard_True;
742 // =======================================================================
743 // function : SetUniform
744 // purpose : Specifies the value of the integer uniform variable
745 // =======================================================================
746 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
747 const GLchar* theName,
750 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
753 // =======================================================================
754 // function : SetUniform
755 // purpose : Specifies the value of the integer uniform variable
756 // =======================================================================
757 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
761 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
763 return Standard_False;
766 theCtx->core20->glUniform1i (theLocation, theValue);
767 return Standard_True;
770 // =======================================================================
771 // function : SetUniform
772 // purpose : Specifies the value of the floating-point uniform variable
773 // =======================================================================
774 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
775 const GLchar* theName,
778 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
781 // =======================================================================
782 // function : SetUniform
783 // purpose : Specifies the value of the floating-point uniform variable
784 // =======================================================================
785 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
789 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
791 return Standard_False;
794 theCtx->core20->glUniform1f (theLocation, theValue);
795 return Standard_True;
798 // =======================================================================
799 // function : SetUniform
800 // purpose : Specifies the value of the integer uniform 2D vector
801 // =======================================================================
802 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
803 const GLchar* theName,
804 const OpenGl_Vec2i& theValue)
806 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
809 // =======================================================================
810 // function : SetUniform
811 // purpose : Specifies the value of the integer uniform 2D vector
812 // =======================================================================
813 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
815 const OpenGl_Vec2i& theValue)
817 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
819 return Standard_False;
822 theCtx->core20->glUniform2iv (theLocation, 1, theValue);
823 return Standard_True;
826 // =======================================================================
827 // function : SetUniform
828 // purpose : Specifies the value of the integer uniform 3D vector
829 // =======================================================================
830 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
831 const GLchar* theName,
832 const OpenGl_Vec3i& theValue)
834 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
837 // =======================================================================
838 // function : SetUniform
839 // purpose : Specifies the value of the integer uniform 3D vector
840 // =======================================================================
841 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
843 const OpenGl_Vec3i& theValue)
845 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
847 return Standard_False;
850 theCtx->core20->glUniform3iv (theLocation, 1, theValue);
851 return Standard_True;
854 // =======================================================================
855 // function : SetUniform
856 // purpose : Specifies the value of the integer uniform 4D vector
857 // =======================================================================
858 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
859 const GLchar* theName,
860 const OpenGl_Vec4i& theValue)
862 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
865 // =======================================================================
866 // function : SetUniform
867 // purpose : Specifies the value of the integer uniform 4D vector
868 // =======================================================================
869 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
871 const OpenGl_Vec4i& theValue)
873 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
875 return Standard_False;
878 theCtx->core20->glUniform4iv (theLocation, 1, theValue);
879 return Standard_True;
882 // =======================================================================
883 // function : SetUniform
884 // purpose : Specifies the value of the floating-point uniform 2D vector
885 // =======================================================================
886 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
887 const GLchar* theName,
888 const OpenGl_Vec2& theValue)
890 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
893 // =======================================================================
894 // function : SetUniform
895 // purpose : Specifies the value of the floating-point uniform 2D vector
896 // =======================================================================
897 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
899 const OpenGl_Vec2& theValue)
901 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
903 return Standard_False;
906 theCtx->core20->glUniform2fv (theLocation, 1, theValue);
907 return Standard_True;
910 // =======================================================================
911 // function : SetUniform
912 // purpose : Specifies the value of the floating-point uniform 3D vector
913 // =======================================================================
914 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
915 const GLchar* theName,
916 const OpenGl_Vec3& theValue)
918 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
921 // =======================================================================
922 // function : SetUniform
923 // purpose : Specifies the value of the floating-point uniform 3D vector
924 // =======================================================================
925 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
927 const OpenGl_Vec3& theValue)
929 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
931 return Standard_False;
934 theCtx->core20->glUniform3fv (theLocation, 1, theValue);
935 return Standard_True;
938 // =======================================================================
939 // function : SetUniform
940 // purpose : Specifies the value of the floating-point uniform 4D vector
941 // =======================================================================
942 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
943 const GLchar* theName,
944 const OpenGl_Vec4& theValue)
946 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
949 // =======================================================================
950 // function : SetUniform
951 // purpose : Specifies the value of the floating-point uniform 4D vector
952 // =======================================================================
953 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
955 const OpenGl_Vec4& theValue)
957 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
959 return Standard_False;
962 theCtx->core20->glUniform4fv (theLocation, 1, theValue);
963 return Standard_True;
966 // =======================================================================
967 // function : SetUniform
968 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
969 // =======================================================================
970 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
971 const GLchar* theName,
972 const OpenGl_Matrix& theValue,
973 GLboolean theTranspose)
975 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
978 // =======================================================================
979 // function : SetUniform
980 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
981 // =======================================================================
982 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
984 const OpenGl_Matrix& theValue,
985 GLboolean theTranspose)
987 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
989 return Standard_False;
992 theCtx->core20->glUniformMatrix4fv (theLocation, 1, theTranspose, *theValue.mat);
993 return Standard_True;
996 // =======================================================================
997 // function : SetUniform
998 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
999 // =======================================================================
1000 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1001 const GLchar* theName,
1002 const Tmatrix3& theValue,
1003 GLboolean theTranspose)
1005 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1008 // =======================================================================
1009 // function : SetUniform
1010 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1011 // =======================================================================
1012 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1014 const Tmatrix3& theValue,
1015 GLboolean theTranspose)
1017 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1019 return Standard_False;
1022 theCtx->core20->glUniformMatrix4fv (theLocation, 1, theTranspose, *theValue);
1023 return Standard_True;
1026 // =======================================================================
1027 // function : SetUniform
1028 // purpose : Specifies the value of the float uniform array
1029 // =======================================================================
1030 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1033 const Standard_ShortReal* theData)
1035 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1037 return Standard_False;
1040 theCtx->core20->glUniform1fv (theLocation, theCount, theData);
1041 return Standard_True;
1044 // =======================================================================
1045 // function : SetUniform
1046 // purpose : Specifies the value of the float2 uniform array
1047 // =======================================================================
1048 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1051 const OpenGl_Vec2* theData)
1053 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1055 return Standard_False;
1058 theCtx->core20->glUniform2fv (theLocation, theCount, theData[0].GetData());
1059 return Standard_True;
1062 // =======================================================================
1063 // function : SetUniform
1064 // purpose : Specifies the value of the float3 uniform array
1065 // =======================================================================
1066 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1069 const OpenGl_Vec3* theData)
1071 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1073 return Standard_False;
1076 theCtx->core20->glUniform3fv (theLocation, theCount, theData[0].GetData());
1077 return Standard_True;
1080 // =======================================================================
1081 // function : SetUniform
1082 // purpose : Specifies the value of the float4 uniform array
1083 // =======================================================================
1084 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1087 const OpenGl_Vec4* theData)
1089 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1091 return Standard_False;
1094 theCtx->core20->glUniform4fv (theLocation, theCount, theData[0].GetData());
1095 return Standard_True;
1098 // =======================================================================
1099 // function : SetUniform
1100 // purpose : Specifies the value of the integer uniform array
1101 // =======================================================================
1102 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1105 const Standard_Integer* theData)
1107 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1109 return Standard_False;
1112 theCtx->core20->glUniform1iv (theLocation, theCount, theData);
1113 return Standard_True;
1116 // =======================================================================
1117 // function : SetUniform
1118 // purpose : Specifies the value of the int2 uniform array
1119 // =======================================================================
1120 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1123 const OpenGl_Vec2i* theData)
1125 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1127 return Standard_False;
1130 theCtx->core20->glUniform2iv (theLocation, theCount, theData[0].GetData());
1131 return Standard_True;
1134 // =======================================================================
1135 // function : SetUniform
1136 // purpose : Specifies the value of the int3 uniform array
1137 // =======================================================================
1138 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1141 const OpenGl_Vec3i* theData)
1143 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1145 return Standard_False;
1148 theCtx->core20->glUniform3iv (theLocation, theCount, theData[0].GetData());
1149 return Standard_True;
1152 // =======================================================================
1153 // function : SetUniform
1154 // purpose : Specifies the value of the int4 uniform array
1155 // =======================================================================
1156 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1159 const OpenGl_Vec4i* theData)
1161 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1163 return Standard_False;
1166 theCtx->core20->glUniform4iv (theLocation, theCount, theData[0].GetData());
1167 return Standard_True;
1170 // =======================================================================
1171 // function : SetSampler
1172 // purpose : Specifies the value of the sampler uniform variable
1173 // =======================================================================
1174 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1175 const GLchar* theName,
1176 const GLenum theTextureUnit)
1178 return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit);
1181 // =======================================================================
1182 // function : SetSampler
1183 // purpose : Specifies the value of the sampler uniform variable
1184 // =======================================================================
1185 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1187 const GLenum theTextureUnit)
1189 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1191 return Standard_False;
1194 theCtx->core20->glUniform1i (theLocation, theTextureUnit);
1195 return Standard_True;
1198 // =======================================================================
1199 // function : Create
1200 // purpose : Creates new empty shader program of specified type
1201 // =======================================================================
1202 Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx)
1204 if (myProgramID == NO_PROGRAM
1205 && theCtx->core20 != NULL)
1207 myProgramID = theCtx->core20->glCreateProgram();
1210 return myProgramID != NO_PROGRAM;
1213 // =======================================================================
1214 // function : Release
1215 // purpose : Destroys shader program
1216 // =======================================================================
1217 void OpenGl_ShaderProgram::Release (OpenGl_Context* theCtx)
1219 if (myProgramID == NO_PROGRAM)
1224 Standard_ASSERT_RETURN (theCtx != NULL,
1225 "OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...",);
1227 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
1229 if (!anIter.Value().IsNull())
1231 anIter.ChangeValue()->Release (theCtx);
1232 anIter.ChangeValue().Nullify();
1236 if (theCtx->core20 != NULL
1237 && theCtx->IsValid())
1239 theCtx->core20->glDeleteProgram (myProgramID);
1242 myProgramID = NO_PROGRAM;