1 // Created on: 2013-09-19
2 // Created by: Denis BOGOLEPOV
3 // Copyright (c) 2013 OPEN CASCADE SAS
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
20 #include <OSD_File.hxx>
21 #include <OSD_Protection.hxx>
23 #include <Standard_Assert.hxx>
24 #include <Standard_Atomic.hxx>
25 #include <TCollection_ExtendedString.hxx>
27 #include <OpenGl_Context.hxx>
28 #include <OpenGl_ShaderProgram.hxx>
29 #include <OpenGl_ShaderManager.hxx>
31 IMPLEMENT_STANDARD_HANDLE (OpenGl_ShaderProgram, OpenGl_Resource)
32 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderProgram, OpenGl_Resource)
34 OpenGl_VariableSetterSelector OpenGl_ShaderProgram::mySetterSelector = OpenGl_VariableSetterSelector();
36 // Declare OCCT-specific OpenGL/GLSL shader variables
37 Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] =
39 "occModelWorldMatrix", // OpenGl_OCC_MODEL_WORLD_MATRIX
40 "occWorldViewMatrix", // OpenGl_OCC_WORLD_VIEW_MATRIX
41 "occProjectionMatrix", // OpenGl_OCC_PROJECTION_MATRIX
42 "occModelWorldMatrixInverse", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE
43 "occWorldViewMatrixInverse", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE
44 "occProjectionMatrixInverse", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE
45 "occModelWorldMatrixTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE
46 "occWorldViewMatrixTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE
47 "occProjectionMatrixTranspose", // OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE
48 "occModelWorldMatrixInverseTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE
49 "occWorldViewMatrixInverseTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE
50 "occProjectionMatrixInverseTranspose", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE
52 "occClipPlaneEquations", // OpenGl_OCC_CLIP_PLANE_EQUATIONS
53 "occClipPlaneSpaces", // OpenGl_OCC_CLIP_PLANE_SPACES
55 "occLightSourcesCount", // OpenGl_OCC_LIGHT_SOURCE_COUNT
56 "occLightSourcesTypes", // OpenGl_OCC_LIGHT_SOURCE_TYPES
57 "occLightSources", // OpenGl_OCC_LIGHT_SOURCE_PARAMS
58 "occLightAmbient", // OpenGl_OCC_LIGHT_AMBIENT
60 "occActiveSampler", // OpenGl_OCCT_ACTIVE_SAMPLER
61 "occTextureEnable", // OpenGl_OCCT_TEXTURE_ENABLE
62 "occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE
63 "occFrontMaterial", // OpenGl_OCCT_FRONT_MATERIAL
64 "occBackMaterial" // OpenGl_OCCT_BACK_MATERIAL
68 // =======================================================================
69 // function : OpenGl_VariableSetterSelector
70 // purpose : Creates new variable setter selector
71 // =======================================================================
72 OpenGl_VariableSetterSelector::OpenGl_VariableSetterSelector()
74 // Note: Add new variable setters here
75 mySetterList = OpenGl_HashMapInitializer::CreateListOf<size_t, OpenGl_SetterInterface*>
76 (Graphic3d_UniformValueTypeID<int>::ID, new OpenGl_VariableSetter<int>())
77 (Graphic3d_UniformValueTypeID<float>::ID, new OpenGl_VariableSetter<float>())
78 (Graphic3d_UniformValueTypeID<OpenGl_Vec2>::ID, new OpenGl_VariableSetter<OpenGl_Vec2>())
79 (Graphic3d_UniformValueTypeID<OpenGl_Vec3>::ID, new OpenGl_VariableSetter<OpenGl_Vec3>())
80 (Graphic3d_UniformValueTypeID<OpenGl_Vec4>::ID, new OpenGl_VariableSetter<OpenGl_Vec4>())
81 (Graphic3d_UniformValueTypeID<OpenGl_Vec2i>::ID, new OpenGl_VariableSetter<OpenGl_Vec2i>())
82 (Graphic3d_UniformValueTypeID<OpenGl_Vec3i>::ID, new OpenGl_VariableSetter<OpenGl_Vec3i>())
83 (Graphic3d_UniformValueTypeID<OpenGl_Vec4i>::ID, new OpenGl_VariableSetter<OpenGl_Vec4i>());
86 // =======================================================================
87 // function : ~OpenGl_VariableSetterSelector
88 // purpose : Releases memory resources of variable setter selector
89 // =======================================================================
90 OpenGl_VariableSetterSelector::~OpenGl_VariableSetterSelector()
92 for (OpenGl_SetterList::Iterator anIt (mySetterList); anIt.More(); anIt.Next())
100 // =======================================================================
102 // purpose : Sets generic variable to specified shader program
103 // =======================================================================
104 void OpenGl_VariableSetterSelector::Set (const Handle(OpenGl_Context)& theCtx,
105 const Handle(Graphic3d_ShaderVariable)& theVariable,
106 OpenGl_ShaderProgram* theProgram) const
108 Standard_ASSERT_RETURN (mySetterList.IsBound (theVariable->Value()->TypeID()),
109 "The type of user-defined uniform variable is not supported...", );
111 mySetterList.Find (theVariable->Value()->TypeID())->Set (theCtx, theVariable, theProgram);
114 // =======================================================================
115 // function : OpenGl_ShaderProgram
116 // purpose : Creates uninitialized shader program
117 // =======================================================================
118 OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy)
119 : myProgramID (NO_PROGRAM),
123 memset (myCurrentState, 0, sizeof (myCurrentState));
124 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
126 myStateLocations[aVar] = INVALID_LOCATION;
130 // =======================================================================
131 // function : Initialize
132 // purpose : Initializes program object with the list of shader objects
133 // =======================================================================
134 Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& theCtx,
135 const Graphic3d_ShaderObjectList& theShaders)
137 if (theCtx.IsNull() || !Create (theCtx))
139 return Standard_False;
142 OSD_File aDeclFile (Graphic3d_ShaderProgram::ShadersFolder() + "/Declarations.glsl");
143 OSD_File aDeclImplFile (Graphic3d_ShaderProgram::ShadersFolder() + "/DeclarationsImpl.glsl");
144 if (!aDeclFile.Exists()
145 || !aDeclImplFile.Exists())
147 const TCollection_ExtendedString aMsg = "Error! Failed to load OCCT shader declarations file";
148 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
149 GL_DEBUG_TYPE_ERROR_ARB,
151 GL_DEBUG_SEVERITY_HIGH_ARB,
153 return Standard_False;
156 TCollection_AsciiString aDeclarations;
157 aDeclFile.Open (OSD_ReadOnly, OSD_Protection());
158 aDeclFile.Read (aDeclarations, (int)aDeclFile.Size());
161 TCollection_AsciiString aDeclImpl;
162 aDeclImplFile.Open (OSD_ReadOnly, OSD_Protection());
163 aDeclImplFile.Read (aDeclImpl, (int)aDeclImplFile.Size());
164 aDeclImplFile.Close();
165 aDeclarations += aDeclImpl;
167 for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders);
168 anIter.More(); anIter.Next())
170 if (!anIter.Value()->IsDone())
172 const TCollection_ExtendedString aMsg = "Error! Failed to get shader source";
173 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
174 GL_DEBUG_TYPE_ERROR_ARB,
176 GL_DEBUG_SEVERITY_HIGH_ARB,
178 return Standard_False;
181 Handle(OpenGl_ShaderObject) aShader;
183 // Note: Add support of other shader types here
184 switch (anIter.Value()->Type())
186 case Graphic3d_TOS_VERTEX:
187 aShader = new OpenGl_ShaderObject (GL_VERTEX_SHADER);
189 case Graphic3d_TOS_FRAGMENT:
190 aShader = new OpenGl_ShaderObject (GL_FRAGMENT_SHADER);
194 // Is unsupported shader type?
195 if (aShader.IsNull())
197 TCollection_ExtendedString aMsg = "Error! Unsupported shader type";
198 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
199 GL_DEBUG_TYPE_ERROR_ARB,
201 GL_DEBUG_SEVERITY_HIGH_ARB,
203 return Standard_False;
206 if (!aShader->Create (theCtx))
208 aShader->Release (theCtx.operator->());
209 return Standard_False;
212 TCollection_AsciiString aSource = aDeclarations + anIter.Value()->Source();
213 if (anIter.Value()->Type() == Graphic3d_TOS_VERTEX)
215 aSource = TCollection_AsciiString ("#define VERTEX_SHADER\n") + aSource;
218 if (!aShader->LoadSource (theCtx, aSource))
220 const TCollection_ExtendedString aMsg = "Error! Failed to set shader source";
221 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
222 GL_DEBUG_TYPE_ERROR_ARB,
224 GL_DEBUG_SEVERITY_HIGH_ARB,
226 aShader->Release (theCtx.operator->());
227 return Standard_False;
230 if (!aShader->Compile (theCtx))
232 TCollection_AsciiString aLog;
233 aShader->FetchInfoLog (theCtx, aLog);
236 aLog = "Compilation log is empty.";
238 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
239 GL_DEBUG_TYPE_ERROR_ARB,
241 GL_DEBUG_SEVERITY_HIGH_ARB,
242 TCollection_ExtendedString ("Failed to compile shader object. Compilation log:\n") + aLog);
243 aShader->Release (theCtx.operator->());
244 return Standard_False;
246 else if (theCtx->caps->glslWarnings)
248 TCollection_AsciiString aLog;
249 aShader->FetchInfoLog (theCtx, aLog);
251 && !aLog.IsEqual ("No errors.\n"))
253 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
254 GL_DEBUG_TYPE_PORTABILITY_ARB,
256 GL_DEBUG_SEVERITY_LOW_ARB,
257 TCollection_ExtendedString ("Shader compilation log:\n") + aLog);
261 if (!AttachShader (theCtx, aShader))
263 aShader->Release (theCtx.operator->());
264 return Standard_False;
270 TCollection_AsciiString aLog;
271 FetchInfoLog (theCtx, aLog);
274 aLog = "Linker log is empty.";
276 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
277 GL_DEBUG_TYPE_ERROR_ARB,
279 GL_DEBUG_SEVERITY_HIGH_ARB,
280 TCollection_ExtendedString ("Failed to link program object! Linker log:\n") + aLog);
281 return Standard_False;
283 else if (theCtx->caps->glslWarnings)
285 TCollection_AsciiString aLog;
286 FetchInfoLog (theCtx, aLog);
288 && !aLog.IsEqual ("No errors.\n"))
290 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
291 GL_DEBUG_TYPE_PORTABILITY_ARB,
293 GL_DEBUG_SEVERITY_LOW_ARB,
294 TCollection_ExtendedString ("GLSL linker log:\n") + aLog);
298 return Standard_True;
301 // =======================================================================
302 // function : ~OpenGl_ShaderProgram
303 // purpose : Releases resources of shader program
304 // =======================================================================
305 OpenGl_ShaderProgram::~OpenGl_ShaderProgram()
310 // =======================================================================
311 // function : AttachShader
312 // purpose : Attaches shader object to the program object
313 // =======================================================================
314 Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context)& theCtx,
315 const Handle(OpenGl_ShaderObject)& theShader)
317 if (myProgramID == NO_PROGRAM || theShader.IsNull())
319 return Standard_False;
322 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
324 if (theShader == anIter.Value())
326 return Standard_False;
330 myShaderObjects.Append (theShader);
331 theCtx->core20->glAttachShader (myProgramID, theShader->myShaderID);
332 return Standard_True;
335 // =======================================================================
336 // function : DetachShader
337 // purpose : Detaches shader object to the program object
338 // =======================================================================
339 Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context)& theCtx,
340 const Handle(OpenGl_ShaderObject)& theShader)
342 if (myProgramID == NO_PROGRAM
343 || theShader.IsNull())
345 return Standard_False;
348 OpenGl_ShaderList::Iterator anIter (myShaderObjects);
349 while (anIter.More())
351 if (theShader == anIter.Value())
353 myShaderObjects.Remove (anIter);
362 return Standard_False;
365 theCtx->core20->glDetachShader (myProgramID, theShader->myShaderID);
366 return Standard_True;
369 // =======================================================================
371 // purpose : Links the program object
372 // =======================================================================
373 Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx)
375 if (myProgramID == NO_PROGRAM)
377 return Standard_False;
380 theCtx->core20->glLinkProgram (myProgramID);
382 GLint aStatus = GL_FALSE;
383 theCtx->core20->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
385 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
387 myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]);
390 return aStatus != GL_FALSE;
393 // =======================================================================
394 // function : FetchInfoLog
395 // purpose : Fetches information log of the last link operation
396 // =======================================================================
397 Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
398 TCollection_AsciiString& theOutput)
400 if (myProgramID == NO_PROGRAM)
402 return Standard_False;
406 theCtx->core20->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
409 GLchar* aLog = (GLchar*) alloca (aLength);
410 memset (aLog, 0, aLength);
411 theCtx->core20->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
414 return Standard_True;
417 // =======================================================================
419 // purpose : Sets the program object as part of current rendering state
420 // =======================================================================
421 void OpenGl_ShaderProgram::Bind (const Handle(OpenGl_Context)& theCtx) const
423 if (myProgramID == NO_PROGRAM)
428 theCtx->core20->glUseProgram (myProgramID);
429 theCtx->ShaderManager()->myIsPP = Standard_True;
432 // =======================================================================
433 // function : ApplyVariables
434 // purpose : Fetches uniform variables from proxy shader program
435 // =======================================================================
436 Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Context)& theCtx)
438 if (myProxy.IsNull() || myProxy->Variables().IsEmpty())
440 return Standard_False;
443 for (Graphic3d_ShaderVariableList::Iterator anIter (myProxy->Variables()); anIter.More(); anIter.Next())
445 mySetterSelector.Set (theCtx, anIter.Value(), this);
448 myProxy->ClearVariables();
449 return Standard_True;
452 // =======================================================================
453 // function : BindWithVariables
454 // purpose : Binds the program object and applies variables
455 // =======================================================================
456 Standard_Boolean OpenGl_ShaderProgram::BindWithVariables (const Handle(OpenGl_Context)& theCtx)
459 return ApplyVariables (theCtx);
462 // =======================================================================
464 // purpose : Reverts to fixed-function graphics pipeline (FFP)
465 // =======================================================================
466 void OpenGl_ShaderProgram::Unbind (const Handle(OpenGl_Context)& theCtx)
468 if (theCtx->ShaderManager()->myIsPP)
470 theCtx->core20->glUseProgram (NO_PROGRAM);
471 theCtx->ShaderManager()->myIsPP = Standard_False;
475 // =======================================================================
476 // function : ActiveState
477 // purpose : Returns index of last modification for specified state type
478 // =======================================================================
479 Standard_Size OpenGl_ShaderProgram::ActiveState (const OpenGl_UniformStateType theType) const
481 if (theType < MaxStateTypes)
483 return myCurrentState[theType];
488 // =======================================================================
489 // function : UpdateState
490 // purpose : Updates index of last modification for specified state type
491 // =======================================================================
492 void OpenGl_ShaderProgram::UpdateState (const OpenGl_UniformStateType theType,
493 const Standard_Size theIndex)
495 if (theType < MaxStateTypes)
497 myCurrentState[theType] = theIndex;
501 // =======================================================================
502 // function : GetUniformLocation
503 // purpose : Returns location (index) of the specific uniform variable
504 // =======================================================================
505 GLint OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& theCtx,
506 const GLchar* theName) const
508 return myProgramID != NO_PROGRAM
509 ? theCtx->core20->glGetUniformLocation (myProgramID, theName)
513 // =======================================================================
514 // function : GetAttributeLocation
515 // purpose : Returns location (index) of the generic vertex attribute
516 // =======================================================================
517 GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)& theCtx,
518 const GLchar* theName) const
520 return myProgramID != NO_PROGRAM
521 ? theCtx->core20->glGetAttribLocation (myProgramID, theName)
525 // =======================================================================
526 // function : GetStateLocation
527 // purpose : Returns location of the OCCT state uniform variable
528 // =======================================================================
529 GLint OpenGl_ShaderProgram::GetStateLocation (const GLuint theVariable) const
531 if (theVariable < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES)
533 return myStateLocations[theVariable];
535 return INVALID_LOCATION;
538 // =======================================================================
539 // function : GetUniform
540 // purpose : Returns the value of the integer uniform variable
541 // =======================================================================
542 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
543 const GLchar* theName,
544 OpenGl_Vec4i& theValue) const
546 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
549 // =======================================================================
550 // function : GetUniform
551 // purpose : Returns the value of the integer uniform variable
552 // =======================================================================
553 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
555 OpenGl_Vec4i& theValue) const
557 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
559 return Standard_False;
562 theCtx->core20->glGetUniformiv (myProgramID, theLocation, theValue);
563 return Standard_True;
566 // =======================================================================
567 // function : GetUniform
568 // purpose : Returns the value of the floating-point uniform variable
569 // =======================================================================
570 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
571 const GLchar* theName,
572 OpenGl_Vec4& theValue) const
574 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
577 // =======================================================================
578 // function : GetUniform
579 // purpose : Returns the value of the floating-point uniform variable
580 // =======================================================================
581 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
583 OpenGl_Vec4& theValue) const
585 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
587 return Standard_False;
590 theCtx->core20->glGetUniformfv (myProgramID, theLocation, theValue);
591 return Standard_True;
594 // =======================================================================
595 // function : GetAttribute
596 // purpose : Returns the integer vertex attribute
597 // =======================================================================
598 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
599 const GLchar* theName,
600 OpenGl_Vec4i& theValue) const
602 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
605 // =======================================================================
606 // function : GetAttribute
607 // purpose : Returns the integer vertex attribute
608 // =======================================================================
609 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
611 OpenGl_Vec4i& theValue) const
613 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
615 return Standard_False;
618 theCtx->core20->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
619 return Standard_True;
622 // =======================================================================
623 // function : GetAttribute
624 // purpose : Returns the floating-point vertex attribute
625 // =======================================================================
626 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
627 const GLchar* theName,
628 OpenGl_Vec4& theValue) const
630 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
633 // =======================================================================
634 // function : GetAttribute
635 // purpose : Returns the floating-point vertex attribute
636 // =======================================================================
637 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
639 OpenGl_Vec4& theValue) const
641 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
643 return Standard_False;
646 theCtx->core20->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
647 return Standard_True;
650 // =======================================================================
651 // function : SetUniform
652 // purpose : Specifies the value of the integer uniform variable
653 // =======================================================================
654 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
655 const GLchar* theName,
658 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
661 // =======================================================================
662 // function : SetUniform
663 // purpose : Specifies the value of the integer uniform variable
664 // =======================================================================
665 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
669 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
671 return Standard_False;
674 theCtx->core20->glUniform1i (theLocation, theValue);
675 return Standard_True;
678 // =======================================================================
679 // function : SetUniform
680 // purpose : Specifies the value of the floating-point uniform variable
681 // =======================================================================
682 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
683 const GLchar* theName,
686 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
689 // =======================================================================
690 // function : SetUniform
691 // purpose : Specifies the value of the floating-point uniform variable
692 // =======================================================================
693 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
697 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
699 return Standard_False;
702 theCtx->core20->glUniform1f (theLocation, theValue);
703 return Standard_True;
706 // =======================================================================
707 // function : SetUniform
708 // purpose : Specifies the value of the integer uniform 2D vector
709 // =======================================================================
710 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
711 const GLchar* theName,
712 const OpenGl_Vec2i& theValue)
714 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
717 // =======================================================================
718 // function : SetUniform
719 // purpose : Specifies the value of the integer uniform 2D vector
720 // =======================================================================
721 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
723 const OpenGl_Vec2i& theValue)
725 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
727 return Standard_False;
730 theCtx->core20->glUniform2iv (theLocation, 1, theValue);
731 return Standard_True;
734 // =======================================================================
735 // function : SetUniform
736 // purpose : Specifies the value of the integer uniform 3D vector
737 // =======================================================================
738 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
739 const GLchar* theName,
740 const OpenGl_Vec3i& theValue)
742 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
745 // =======================================================================
746 // function : SetUniform
747 // purpose : Specifies the value of the integer uniform 3D vector
748 // =======================================================================
749 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
751 const OpenGl_Vec3i& theValue)
753 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
755 return Standard_False;
758 theCtx->core20->glUniform3iv (theLocation, 1, theValue);
759 return Standard_True;
762 // =======================================================================
763 // function : SetUniform
764 // purpose : Specifies the value of the integer uniform 4D vector
765 // =======================================================================
766 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
767 const GLchar* theName,
768 const OpenGl_Vec4i& theValue)
770 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
773 // =======================================================================
774 // function : SetUniform
775 // purpose : Specifies the value of the integer uniform 4D vector
776 // =======================================================================
777 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
779 const OpenGl_Vec4i& theValue)
781 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
783 return Standard_False;
786 theCtx->core20->glUniform4iv (theLocation, 1, theValue);
787 return Standard_True;
790 // =======================================================================
791 // function : SetUniform
792 // purpose : Specifies the value of the floating-point uniform 2D vector
793 // =======================================================================
794 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
795 const GLchar* theName,
796 const OpenGl_Vec2& theValue)
798 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
801 // =======================================================================
802 // function : SetUniform
803 // purpose : Specifies the value of the floating-point uniform 2D vector
804 // =======================================================================
805 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
807 const OpenGl_Vec2& theValue)
809 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
811 return Standard_False;
814 theCtx->core20->glUniform2fv (theLocation, 1, theValue);
815 return Standard_True;
818 // =======================================================================
819 // function : SetUniform
820 // purpose : Specifies the value of the floating-point uniform 3D vector
821 // =======================================================================
822 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
823 const GLchar* theName,
824 const OpenGl_Vec3& theValue)
826 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
829 // =======================================================================
830 // function : SetUniform
831 // purpose : Specifies the value of the floating-point uniform 3D vector
832 // =======================================================================
833 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
835 const OpenGl_Vec3& theValue)
837 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
839 return Standard_False;
842 theCtx->core20->glUniform3fv (theLocation, 1, theValue);
843 return Standard_True;
846 // =======================================================================
847 // function : SetUniform
848 // purpose : Specifies the value of the floating-point uniform 4D vector
849 // =======================================================================
850 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
851 const GLchar* theName,
852 const OpenGl_Vec4& theValue)
854 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
857 // =======================================================================
858 // function : SetUniform
859 // purpose : Specifies the value of the floating-point uniform 4D vector
860 // =======================================================================
861 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
863 const OpenGl_Vec4& theValue)
865 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
867 return Standard_False;
870 theCtx->core20->glUniform4fv (theLocation, 1, theValue);
871 return Standard_True;
874 // =======================================================================
875 // function : SetUniform
876 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
877 // =======================================================================
878 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
879 const GLchar* theName,
880 const OpenGl_Matrix& theValue,
881 GLboolean theTranspose)
883 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
886 // =======================================================================
887 // function : SetUniform
888 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
889 // =======================================================================
890 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
892 const OpenGl_Matrix& theValue,
893 GLboolean theTranspose)
895 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
897 return Standard_False;
900 theCtx->core20->glUniformMatrix4fv (theLocation, 1, theTranspose, *theValue.mat);
901 return Standard_True;
904 // =======================================================================
905 // function : SetUniform
906 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
907 // =======================================================================
908 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
909 const GLchar* theName,
910 const Tmatrix3& theValue,
911 GLboolean theTranspose)
913 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
916 // =======================================================================
917 // function : SetUniform
918 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
919 // =======================================================================
920 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
922 const Tmatrix3& theValue,
923 GLboolean theTranspose)
925 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
927 return Standard_False;
930 theCtx->core20->glUniformMatrix4fv (theLocation, 1, theTranspose, *theValue);
931 return Standard_True;
934 // =======================================================================
935 // function : SetSampler
936 // purpose : Specifies the value of the sampler uniform variable
937 // =======================================================================
938 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
939 const GLchar* theName,
940 const GLenum theTextureUnit)
942 return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit);
945 // =======================================================================
946 // function : SetSampler
947 // purpose : Specifies the value of the sampler uniform variable
948 // =======================================================================
949 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
951 const GLenum theTextureUnit)
953 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
955 return Standard_False;
958 theCtx->core20->glUniform1i (theLocation, theTextureUnit);
959 return Standard_True;
962 // =======================================================================
964 // purpose : Creates new empty shader program of specified type
965 // =======================================================================
966 Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx)
968 if (myProgramID == NO_PROGRAM
969 && theCtx->core20 != NULL)
971 myProgramID = theCtx->core20->glCreateProgram();
974 return myProgramID != NO_PROGRAM;
977 // =======================================================================
978 // function : Release
979 // purpose : Destroys shader program
980 // =======================================================================
981 void OpenGl_ShaderProgram::Release (const OpenGl_Context* theCtx)
983 if (myProgramID == NO_PROGRAM)
988 Standard_ASSERT_RETURN (theCtx != NULL,
989 "OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...",);
991 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
993 anIter.ChangeValue()->Release (theCtx);
994 anIter.ChangeValue().Nullify();
997 if (theCtx->core20 != NULL
998 && theCtx->IsValid())
1000 theCtx->core20->glDeleteProgram (myProgramID);
1003 myProgramID = NO_PROGRAM;