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 <Standard_Assert.hxx>
20 #include <Standard_Atomic.hxx>
21 #include <TCollection_ExtendedString.hxx>
23 #include <OpenGl_Context.hxx>
24 #include <OpenGl_ShaderProgram.hxx>
25 #include <OpenGl_ShaderManager.hxx>
27 IMPLEMENT_STANDARD_HANDLE (OpenGl_ShaderProgram, OpenGl_Resource)
28 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderProgram, OpenGl_Resource)
30 OpenGl_VariableSetterSelector OpenGl_ShaderProgram::mySetterSelector = OpenGl_VariableSetterSelector();
32 // Declare OCCT-specific OpenGL/GLSL shader variables
33 Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] =
35 "occModelWorldMatrix", // OpenGl_OCC_MODEL_WORLD_MATRIX
36 "occWorldViewMatrix", // OpenGl_OCC_WORLD_VIEW_MATRIX
37 "occProjectionMatrix", // OpenGl_OCC_PROJECTION_MATRIX
38 "occModelWorldMatrixInverse", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE
39 "occWorldViewMatrixInverse", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE
40 "occProjectionMatrixInverse", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE
41 "occModelWorldMatrixTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE
42 "occWorldViewMatrixTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE
43 "occProjectionMatrixTranspose", // OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE
44 "occModelWorldMatrixInverseTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE
45 "occWorldViewMatrixInverseTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE
46 "occProjectionMatrixInverseTranspose", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE
48 "occClipPlaneEquations", // OpenGl_OCC_CLIP_PLANE_EQUATIONS
49 "occClipPlaneSpaces", // OpenGl_OCC_CLIP_PLANE_SPACES
50 "occClipPlaneCount", // OpenGl_OCC_CLIP_PLANE_COUNT
52 "occLightSourcesCount", // OpenGl_OCC_LIGHT_SOURCE_COUNT
53 "occLightSourcesTypes", // OpenGl_OCC_LIGHT_SOURCE_TYPES
54 "occLightSources", // OpenGl_OCC_LIGHT_SOURCE_PARAMS
55 "occLightAmbient", // OpenGl_OCC_LIGHT_AMBIENT
57 "occActiveSampler", // OpenGl_OCCT_ACTIVE_SAMPLER
58 "occTextureEnable", // OpenGl_OCCT_TEXTURE_ENABLE
59 "occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE
60 "occFrontMaterial", // OpenGl_OCCT_FRONT_MATERIAL
61 "occBackMaterial" // OpenGl_OCCT_BACK_MATERIAL
65 // =======================================================================
66 // function : OpenGl_VariableSetterSelector
67 // purpose : Creates new variable setter selector
68 // =======================================================================
69 OpenGl_VariableSetterSelector::OpenGl_VariableSetterSelector()
71 // Note: Add new variable setters here
72 mySetterList = OpenGl_HashMapInitializer::CreateListOf<size_t, OpenGl_SetterInterface*>
73 (Graphic3d_UniformValueTypeID<int>::ID, new OpenGl_VariableSetter<int>())
74 (Graphic3d_UniformValueTypeID<float>::ID, new OpenGl_VariableSetter<float>())
75 (Graphic3d_UniformValueTypeID<OpenGl_Vec2>::ID, new OpenGl_VariableSetter<OpenGl_Vec2>())
76 (Graphic3d_UniformValueTypeID<OpenGl_Vec3>::ID, new OpenGl_VariableSetter<OpenGl_Vec3>())
77 (Graphic3d_UniformValueTypeID<OpenGl_Vec4>::ID, new OpenGl_VariableSetter<OpenGl_Vec4>())
78 (Graphic3d_UniformValueTypeID<OpenGl_Vec2i>::ID, new OpenGl_VariableSetter<OpenGl_Vec2i>())
79 (Graphic3d_UniformValueTypeID<OpenGl_Vec3i>::ID, new OpenGl_VariableSetter<OpenGl_Vec3i>())
80 (Graphic3d_UniformValueTypeID<OpenGl_Vec4i>::ID, new OpenGl_VariableSetter<OpenGl_Vec4i>());
83 // =======================================================================
84 // function : ~OpenGl_VariableSetterSelector
85 // purpose : Releases memory resources of variable setter selector
86 // =======================================================================
87 OpenGl_VariableSetterSelector::~OpenGl_VariableSetterSelector()
89 for (OpenGl_SetterList::Iterator anIt (mySetterList); anIt.More(); anIt.Next())
97 // =======================================================================
99 // purpose : Sets generic variable to specified shader program
100 // =======================================================================
101 void OpenGl_VariableSetterSelector::Set (const Handle(OpenGl_Context)& theCtx,
102 const Handle(Graphic3d_ShaderVariable)& theVariable,
103 OpenGl_ShaderProgram* theProgram) const
105 Standard_ASSERT_RETURN (mySetterList.IsBound (theVariable->Value()->TypeID()),
106 "The type of user-defined uniform variable is not supported...", );
108 mySetterList.Find (theVariable->Value()->TypeID())->Set (theCtx, theVariable, theProgram);
111 // =======================================================================
112 // function : OpenGl_ShaderProgram
113 // purpose : Creates uninitialized shader program
114 // =======================================================================
115 OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy)
116 : myProgramID (NO_PROGRAM),
120 memset (myCurrentState, 0, sizeof (myCurrentState));
121 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
123 myStateLocations[aVar] = INVALID_LOCATION;
127 // =======================================================================
128 // function : Initialize
129 // purpose : Initializes program object with the list of shader objects
130 // =======================================================================
131 Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& theCtx,
132 const Graphic3d_ShaderObjectList& theShaders)
134 if (theCtx.IsNull() || !Create (theCtx))
136 return Standard_False;
139 OSD_File aDeclFile (Graphic3d_ShaderProgram::ShadersFolder() + "/Declarations.glsl");
140 OSD_File aDeclImplFile (Graphic3d_ShaderProgram::ShadersFolder() + "/DeclarationsImpl.glsl");
141 if (!aDeclFile.Exists()
142 || !aDeclImplFile.Exists())
144 const TCollection_ExtendedString aMsg = "Error! Failed to load OCCT shader declarations file";
145 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
146 GL_DEBUG_TYPE_ERROR_ARB,
148 GL_DEBUG_SEVERITY_HIGH_ARB,
150 return Standard_False;
153 TCollection_AsciiString aDeclarations;
154 aDeclFile.Open (OSD_ReadOnly, OSD_Protection());
155 aDeclFile.Read (aDeclarations, (int)aDeclFile.Size());
158 TCollection_AsciiString aDeclImpl;
159 aDeclImplFile.Open (OSD_ReadOnly, OSD_Protection());
160 aDeclImplFile.Read (aDeclImpl, (int)aDeclImplFile.Size());
161 aDeclImplFile.Close();
162 aDeclarations += aDeclImpl;
164 for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders);
165 anIter.More(); anIter.Next())
167 if (!anIter.Value()->IsDone())
169 const TCollection_ExtendedString aMsg = "Error! Failed to get shader source";
170 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
171 GL_DEBUG_TYPE_ERROR_ARB,
173 GL_DEBUG_SEVERITY_HIGH_ARB,
175 return Standard_False;
178 Handle(OpenGl_ShaderObject) aShader;
180 // Note: Add support of other shader types here
181 switch (anIter.Value()->Type())
183 case Graphic3d_TOS_VERTEX:
184 aShader = new OpenGl_ShaderObject (GL_VERTEX_SHADER);
186 case Graphic3d_TOS_FRAGMENT:
187 aShader = new OpenGl_ShaderObject (GL_FRAGMENT_SHADER);
191 // Is unsupported shader type?
192 if (aShader.IsNull())
194 TCollection_ExtendedString aMsg = "Error! Unsupported shader type";
195 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
196 GL_DEBUG_TYPE_ERROR_ARB,
198 GL_DEBUG_SEVERITY_HIGH_ARB,
200 return Standard_False;
203 if (!aShader->Create (theCtx))
205 aShader->Release (theCtx.operator->());
206 return Standard_False;
209 TCollection_AsciiString aSource = aDeclarations + anIter.Value()->Source();
210 if (anIter.Value()->Type() == Graphic3d_TOS_VERTEX)
212 aSource = TCollection_AsciiString ("#define VERTEX_SHADER\n") + aSource;
215 if (!aShader->LoadSource (theCtx, aSource))
217 const TCollection_ExtendedString aMsg = "Error! Failed to set shader source";
218 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
219 GL_DEBUG_TYPE_ERROR_ARB,
221 GL_DEBUG_SEVERITY_HIGH_ARB,
223 aShader->Release (theCtx.operator->());
224 return Standard_False;
227 if (!aShader->Compile (theCtx))
229 TCollection_AsciiString aLog;
230 aShader->FetchInfoLog (theCtx, aLog);
233 aLog = "Compilation log is empty.";
235 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
236 GL_DEBUG_TYPE_ERROR_ARB,
238 GL_DEBUG_SEVERITY_HIGH_ARB,
239 TCollection_ExtendedString ("Failed to compile shader object. Compilation log:\n") + aLog);
240 aShader->Release (theCtx.operator->());
241 return Standard_False;
243 else if (theCtx->caps->glslWarnings)
245 TCollection_AsciiString aLog;
246 aShader->FetchInfoLog (theCtx, aLog);
248 && !aLog.IsEqual ("No errors.\n"))
250 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
251 GL_DEBUG_TYPE_PORTABILITY_ARB,
253 GL_DEBUG_SEVERITY_LOW_ARB,
254 TCollection_ExtendedString ("Shader compilation log:\n") + aLog);
258 if (!AttachShader (theCtx, aShader))
260 aShader->Release (theCtx.operator->());
261 return Standard_False;
267 TCollection_AsciiString aLog;
268 FetchInfoLog (theCtx, aLog);
271 aLog = "Linker log is empty.";
273 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
274 GL_DEBUG_TYPE_ERROR_ARB,
276 GL_DEBUG_SEVERITY_HIGH_ARB,
277 TCollection_ExtendedString ("Failed to link program object! Linker log:\n") + aLog);
278 return Standard_False;
280 else if (theCtx->caps->glslWarnings)
282 TCollection_AsciiString aLog;
283 FetchInfoLog (theCtx, aLog);
285 && !aLog.IsEqual ("No errors.\n"))
287 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
288 GL_DEBUG_TYPE_PORTABILITY_ARB,
290 GL_DEBUG_SEVERITY_LOW_ARB,
291 TCollection_ExtendedString ("GLSL linker log:\n") + aLog);
295 return Standard_True;
298 // =======================================================================
299 // function : ~OpenGl_ShaderProgram
300 // purpose : Releases resources of shader program
301 // =======================================================================
302 OpenGl_ShaderProgram::~OpenGl_ShaderProgram()
307 // =======================================================================
308 // function : AttachShader
309 // purpose : Attaches shader object to the program object
310 // =======================================================================
311 Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context)& theCtx,
312 const Handle(OpenGl_ShaderObject)& theShader)
314 if (myProgramID == NO_PROGRAM || theShader.IsNull())
316 return Standard_False;
319 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
321 if (theShader == anIter.Value())
323 return Standard_False;
327 myShaderObjects.Append (theShader);
328 theCtx->core20->glAttachShader (myProgramID, theShader->myShaderID);
329 return Standard_True;
332 // =======================================================================
333 // function : DetachShader
334 // purpose : Detaches shader object to the program object
335 // =======================================================================
336 Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context)& theCtx,
337 const Handle(OpenGl_ShaderObject)& theShader)
339 if (myProgramID == NO_PROGRAM
340 || theShader.IsNull())
342 return Standard_False;
345 OpenGl_ShaderList::Iterator anIter (myShaderObjects);
346 while (anIter.More())
348 if (theShader == anIter.Value())
350 myShaderObjects.Remove (anIter);
359 return Standard_False;
362 theCtx->core20->glDetachShader (myProgramID, theShader->myShaderID);
363 return Standard_True;
366 // =======================================================================
368 // purpose : Links the program object
369 // =======================================================================
370 Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx)
372 if (myProgramID == NO_PROGRAM)
374 return Standard_False;
377 theCtx->core20->glLinkProgram (myProgramID);
379 GLint aStatus = GL_FALSE;
380 theCtx->core20->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
382 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
384 myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]);
387 return aStatus != GL_FALSE;
390 // =======================================================================
391 // function : FetchInfoLog
392 // purpose : Fetches information log of the last link operation
393 // =======================================================================
394 Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
395 TCollection_AsciiString& theOutput)
397 if (myProgramID == NO_PROGRAM)
399 return Standard_False;
403 theCtx->core20->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
406 GLchar* aLog = (GLchar*) alloca (aLength);
407 memset (aLog, 0, aLength);
408 theCtx->core20->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
411 return Standard_True;
414 // =======================================================================
416 // purpose : Sets the program object as part of current rendering state
417 // =======================================================================
418 void OpenGl_ShaderProgram::Bind (const Handle(OpenGl_Context)& theCtx) const
420 if (myProgramID == NO_PROGRAM)
425 theCtx->core20->glUseProgram (myProgramID);
426 theCtx->ShaderManager()->myIsPP = Standard_True;
429 // =======================================================================
430 // function : ApplyVariables
431 // purpose : Fetches uniform variables from proxy shader program
432 // =======================================================================
433 Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Context)& theCtx)
435 if (myProxy.IsNull() || myProxy->Variables().IsEmpty())
437 return Standard_False;
440 for (Graphic3d_ShaderVariableList::Iterator anIter (myProxy->Variables()); anIter.More(); anIter.Next())
442 mySetterSelector.Set (theCtx, anIter.Value(), this);
445 myProxy->ClearVariables();
446 return Standard_True;
449 // =======================================================================
450 // function : BindWithVariables
451 // purpose : Binds the program object and applies variables
452 // =======================================================================
453 Standard_Boolean OpenGl_ShaderProgram::BindWithVariables (const Handle(OpenGl_Context)& theCtx)
456 return ApplyVariables (theCtx);
459 // =======================================================================
461 // purpose : Reverts to fixed-function graphics pipeline (FFP)
462 // =======================================================================
463 void OpenGl_ShaderProgram::Unbind (const Handle(OpenGl_Context)& theCtx)
465 if (theCtx->ShaderManager()->myIsPP)
467 theCtx->core20->glUseProgram (NO_PROGRAM);
468 theCtx->ShaderManager()->myIsPP = Standard_False;
472 // =======================================================================
473 // function : ActiveState
474 // purpose : Returns index of last modification for specified state type
475 // =======================================================================
476 Standard_Size OpenGl_ShaderProgram::ActiveState (const OpenGl_UniformStateType theType) const
478 if (theType < MaxStateTypes)
480 return myCurrentState[theType];
485 // =======================================================================
486 // function : UpdateState
487 // purpose : Updates index of last modification for specified state type
488 // =======================================================================
489 void OpenGl_ShaderProgram::UpdateState (const OpenGl_UniformStateType theType,
490 const Standard_Size theIndex)
492 if (theType < MaxStateTypes)
494 myCurrentState[theType] = theIndex;
498 // =======================================================================
499 // function : GetUniformLocation
500 // purpose : Returns location (index) of the specific uniform variable
501 // =======================================================================
502 GLint OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& theCtx,
503 const GLchar* theName) const
505 return myProgramID != NO_PROGRAM
506 ? theCtx->core20->glGetUniformLocation (myProgramID, theName)
510 // =======================================================================
511 // function : GetAttributeLocation
512 // purpose : Returns location (index) of the generic vertex attribute
513 // =======================================================================
514 GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)& theCtx,
515 const GLchar* theName) const
517 return myProgramID != NO_PROGRAM
518 ? theCtx->core20->glGetAttribLocation (myProgramID, theName)
522 // =======================================================================
523 // function : GetStateLocation
524 // purpose : Returns location of the OCCT state uniform variable
525 // =======================================================================
526 GLint OpenGl_ShaderProgram::GetStateLocation (const GLuint theVariable) const
528 if (theVariable < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES)
530 return myStateLocations[theVariable];
532 return INVALID_LOCATION;
535 // =======================================================================
536 // function : GetUniform
537 // purpose : Returns the value of the integer uniform variable
538 // =======================================================================
539 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
540 const GLchar* theName,
541 OpenGl_Vec4i& theValue) const
543 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
546 // =======================================================================
547 // function : GetUniform
548 // purpose : Returns the value of the integer uniform variable
549 // =======================================================================
550 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
552 OpenGl_Vec4i& theValue) const
554 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
556 return Standard_False;
559 theCtx->core20->glGetUniformiv (myProgramID, theLocation, theValue);
560 return Standard_True;
563 // =======================================================================
564 // function : GetUniform
565 // purpose : Returns the value of the floating-point uniform variable
566 // =======================================================================
567 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
568 const GLchar* theName,
569 OpenGl_Vec4& theValue) const
571 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
574 // =======================================================================
575 // function : GetUniform
576 // purpose : Returns the value of the floating-point uniform variable
577 // =======================================================================
578 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
580 OpenGl_Vec4& theValue) const
582 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
584 return Standard_False;
587 theCtx->core20->glGetUniformfv (myProgramID, theLocation, theValue);
588 return Standard_True;
591 // =======================================================================
592 // function : GetAttribute
593 // purpose : Returns the integer vertex attribute
594 // =======================================================================
595 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
596 const GLchar* theName,
597 OpenGl_Vec4i& theValue) const
599 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
602 // =======================================================================
603 // function : GetAttribute
604 // purpose : Returns the integer vertex attribute
605 // =======================================================================
606 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
608 OpenGl_Vec4i& theValue) const
610 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
612 return Standard_False;
615 theCtx->core20->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
616 return Standard_True;
619 // =======================================================================
620 // function : GetAttribute
621 // purpose : Returns the floating-point vertex attribute
622 // =======================================================================
623 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
624 const GLchar* theName,
625 OpenGl_Vec4& theValue) const
627 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
630 // =======================================================================
631 // function : GetAttribute
632 // purpose : Returns the floating-point vertex attribute
633 // =======================================================================
634 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
636 OpenGl_Vec4& theValue) const
638 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
640 return Standard_False;
643 theCtx->core20->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
644 return Standard_True;
647 // =======================================================================
648 // function : SetUniform
649 // purpose : Specifies the value of the integer uniform variable
650 // =======================================================================
651 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
652 const GLchar* theName,
655 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
658 // =======================================================================
659 // function : SetUniform
660 // purpose : Specifies the value of the integer uniform variable
661 // =======================================================================
662 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
666 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
668 return Standard_False;
671 theCtx->core20->glUniform1i (theLocation, theValue);
672 return Standard_True;
675 // =======================================================================
676 // function : SetUniform
677 // purpose : Specifies the value of the floating-point uniform variable
678 // =======================================================================
679 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
680 const GLchar* theName,
683 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
686 // =======================================================================
687 // function : SetUniform
688 // purpose : Specifies the value of the floating-point uniform variable
689 // =======================================================================
690 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
694 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
696 return Standard_False;
699 theCtx->core20->glUniform1f (theLocation, theValue);
700 return Standard_True;
703 // =======================================================================
704 // function : SetUniform
705 // purpose : Specifies the value of the integer uniform 2D vector
706 // =======================================================================
707 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
708 const GLchar* theName,
709 const OpenGl_Vec2i& theValue)
711 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
714 // =======================================================================
715 // function : SetUniform
716 // purpose : Specifies the value of the integer uniform 2D vector
717 // =======================================================================
718 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
720 const OpenGl_Vec2i& theValue)
722 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
724 return Standard_False;
727 theCtx->core20->glUniform2iv (theLocation, 1, theValue);
728 return Standard_True;
731 // =======================================================================
732 // function : SetUniform
733 // purpose : Specifies the value of the integer uniform 3D vector
734 // =======================================================================
735 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
736 const GLchar* theName,
737 const OpenGl_Vec3i& theValue)
739 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
742 // =======================================================================
743 // function : SetUniform
744 // purpose : Specifies the value of the integer uniform 3D vector
745 // =======================================================================
746 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
748 const OpenGl_Vec3i& theValue)
750 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
752 return Standard_False;
755 theCtx->core20->glUniform3iv (theLocation, 1, theValue);
756 return Standard_True;
759 // =======================================================================
760 // function : SetUniform
761 // purpose : Specifies the value of the integer uniform 4D vector
762 // =======================================================================
763 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
764 const GLchar* theName,
765 const OpenGl_Vec4i& theValue)
767 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
770 // =======================================================================
771 // function : SetUniform
772 // purpose : Specifies the value of the integer uniform 4D vector
773 // =======================================================================
774 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
776 const OpenGl_Vec4i& theValue)
778 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
780 return Standard_False;
783 theCtx->core20->glUniform4iv (theLocation, 1, theValue);
784 return Standard_True;
787 // =======================================================================
788 // function : SetUniform
789 // purpose : Specifies the value of the floating-point uniform 2D vector
790 // =======================================================================
791 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
792 const GLchar* theName,
793 const OpenGl_Vec2& theValue)
795 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
798 // =======================================================================
799 // function : SetUniform
800 // purpose : Specifies the value of the floating-point uniform 2D vector
801 // =======================================================================
802 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
804 const OpenGl_Vec2& theValue)
806 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
808 return Standard_False;
811 theCtx->core20->glUniform2fv (theLocation, 1, theValue);
812 return Standard_True;
815 // =======================================================================
816 // function : SetUniform
817 // purpose : Specifies the value of the floating-point uniform 3D vector
818 // =======================================================================
819 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
820 const GLchar* theName,
821 const OpenGl_Vec3& theValue)
823 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
826 // =======================================================================
827 // function : SetUniform
828 // purpose : Specifies the value of the floating-point uniform 3D vector
829 // =======================================================================
830 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
832 const OpenGl_Vec3& theValue)
834 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
836 return Standard_False;
839 theCtx->core20->glUniform3fv (theLocation, 1, theValue);
840 return Standard_True;
843 // =======================================================================
844 // function : SetUniform
845 // purpose : Specifies the value of the floating-point uniform 4D vector
846 // =======================================================================
847 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
848 const GLchar* theName,
849 const OpenGl_Vec4& theValue)
851 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
854 // =======================================================================
855 // function : SetUniform
856 // purpose : Specifies the value of the floating-point uniform 4D vector
857 // =======================================================================
858 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
860 const OpenGl_Vec4& theValue)
862 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
864 return Standard_False;
867 theCtx->core20->glUniform4fv (theLocation, 1, theValue);
868 return Standard_True;
871 // =======================================================================
872 // function : SetUniform
873 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
874 // =======================================================================
875 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
876 const GLchar* theName,
877 const OpenGl_Matrix& theValue,
878 GLboolean theTranspose)
880 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
883 // =======================================================================
884 // function : SetUniform
885 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
886 // =======================================================================
887 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
889 const OpenGl_Matrix& theValue,
890 GLboolean theTranspose)
892 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
894 return Standard_False;
897 theCtx->core20->glUniformMatrix4fv (theLocation, 1, theTranspose, *theValue.mat);
898 return Standard_True;
901 // =======================================================================
902 // function : SetUniform
903 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
904 // =======================================================================
905 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
906 const GLchar* theName,
907 const Tmatrix3& theValue,
908 GLboolean theTranspose)
910 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
913 // =======================================================================
914 // function : SetUniform
915 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
916 // =======================================================================
917 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
919 const Tmatrix3& theValue,
920 GLboolean theTranspose)
922 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
924 return Standard_False;
927 theCtx->core20->glUniformMatrix4fv (theLocation, 1, theTranspose, *theValue);
928 return Standard_True;
931 // =======================================================================
932 // function : SetUniform
933 // purpose : Specifies the value of the float uniform array
934 // =======================================================================
935 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
938 const Standard_ShortReal* theData)
940 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
942 return Standard_False;
945 theCtx->core20->glUniform1fv (theLocation, theCount, theData);
946 return Standard_True;
949 // =======================================================================
950 // function : SetUniform
951 // purpose : Specifies the value of the float2 uniform array
952 // =======================================================================
953 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
956 const OpenGl_Vec2* theData)
958 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
960 return Standard_False;
963 theCtx->core20->glUniform2fv (theLocation, theCount, theData[0].GetData());
964 return Standard_True;
967 // =======================================================================
968 // function : SetUniform
969 // purpose : Specifies the value of the float3 uniform array
970 // =======================================================================
971 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
974 const OpenGl_Vec3* theData)
976 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
978 return Standard_False;
981 theCtx->core20->glUniform3fv (theLocation, theCount, theData[0].GetData());
982 return Standard_True;
985 // =======================================================================
986 // function : SetUniform
987 // purpose : Specifies the value of the float4 uniform array
988 // =======================================================================
989 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
992 const OpenGl_Vec4* theData)
994 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
996 return Standard_False;
999 theCtx->core20->glUniform4fv (theLocation, theCount, theData[0].GetData());
1000 return Standard_True;
1003 // =======================================================================
1004 // function : SetUniform
1005 // purpose : Specifies the value of the integer uniform array
1006 // =======================================================================
1007 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1010 const Standard_Integer* theData)
1012 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1014 return Standard_False;
1017 theCtx->core20->glUniform1iv (theLocation, theCount, theData);
1018 return Standard_True;
1021 // =======================================================================
1022 // function : SetUniform
1023 // purpose : Specifies the value of the int2 uniform array
1024 // =======================================================================
1025 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1028 const OpenGl_Vec2i* theData)
1030 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1032 return Standard_False;
1035 theCtx->core20->glUniform2iv (theLocation, theCount, theData[0].GetData());
1036 return Standard_True;
1039 // =======================================================================
1040 // function : SetUniform
1041 // purpose : Specifies the value of the int3 uniform array
1042 // =======================================================================
1043 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1046 const OpenGl_Vec3i* theData)
1048 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1050 return Standard_False;
1053 theCtx->core20->glUniform3iv (theLocation, theCount, theData[0].GetData());
1054 return Standard_True;
1057 // =======================================================================
1058 // function : SetUniform
1059 // purpose : Specifies the value of the int4 uniform array
1060 // =======================================================================
1061 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1064 const OpenGl_Vec4i* theData)
1066 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1068 return Standard_False;
1071 theCtx->core20->glUniform4iv (theLocation, theCount, theData[0].GetData());
1072 return Standard_True;
1075 // =======================================================================
1076 // function : SetSampler
1077 // purpose : Specifies the value of the sampler uniform variable
1078 // =======================================================================
1079 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1080 const GLchar* theName,
1081 const GLenum theTextureUnit)
1083 return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit);
1086 // =======================================================================
1087 // function : SetSampler
1088 // purpose : Specifies the value of the sampler uniform variable
1089 // =======================================================================
1090 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1092 const GLenum theTextureUnit)
1094 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1096 return Standard_False;
1099 theCtx->core20->glUniform1i (theLocation, theTextureUnit);
1100 return Standard_True;
1103 // =======================================================================
1104 // function : Create
1105 // purpose : Creates new empty shader program of specified type
1106 // =======================================================================
1107 Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx)
1109 if (myProgramID == NO_PROGRAM
1110 && theCtx->core20 != NULL)
1112 myProgramID = theCtx->core20->glCreateProgram();
1115 return myProgramID != NO_PROGRAM;
1118 // =======================================================================
1119 // function : Release
1120 // purpose : Destroys shader program
1121 // =======================================================================
1122 void OpenGl_ShaderProgram::Release (const OpenGl_Context* theCtx)
1124 if (myProgramID == NO_PROGRAM)
1129 Standard_ASSERT_RETURN (theCtx != NULL,
1130 "OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...",);
1132 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
1134 anIter.ChangeValue()->Release (theCtx);
1135 anIter.ChangeValue().Nullify();
1138 if (theCtx->core20 != NULL
1139 && theCtx->IsValid())
1141 theCtx->core20->glDeleteProgram (myProgramID);
1144 myProgramID = NO_PROGRAM;