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 GLint aStatus = GL_FALSE;
378 theCtx->core20->glLinkProgram (myProgramID);
379 theCtx->core20->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
380 if (aStatus == GL_FALSE)
382 return Standard_False;
385 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
387 myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]);
389 return Standard_True;
392 // =======================================================================
393 // function : FetchInfoLog
394 // purpose : Fetches information log of the last link operation
395 // =======================================================================
396 Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
397 TCollection_AsciiString& theOutput)
399 if (myProgramID == NO_PROGRAM)
401 return Standard_False;
405 theCtx->core20->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
408 GLchar* aLog = (GLchar*) alloca (aLength);
409 memset (aLog, 0, aLength);
410 theCtx->core20->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
413 return Standard_True;
416 // =======================================================================
418 // purpose : Sets the program object as part of current rendering state
419 // =======================================================================
420 void OpenGl_ShaderProgram::Bind (const Handle(OpenGl_Context)& theCtx) const
422 if (myProgramID == NO_PROGRAM)
427 theCtx->core20->glUseProgram (myProgramID);
428 theCtx->ShaderManager()->myIsPP = Standard_True;
431 // =======================================================================
432 // function : ApplyVariables
433 // purpose : Fetches uniform variables from proxy shader program
434 // =======================================================================
435 Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Context)& theCtx)
437 if (myProxy.IsNull() || myProxy->Variables().IsEmpty())
439 return Standard_False;
442 for (Graphic3d_ShaderVariableList::Iterator anIter (myProxy->Variables()); anIter.More(); anIter.Next())
444 mySetterSelector.Set (theCtx, anIter.Value(), this);
447 myProxy->ClearVariables();
448 return Standard_True;
451 // =======================================================================
452 // function : BindWithVariables
453 // purpose : Binds the program object and applies variables
454 // =======================================================================
455 Standard_Boolean OpenGl_ShaderProgram::BindWithVariables (const Handle(OpenGl_Context)& theCtx)
458 return ApplyVariables (theCtx);
461 // =======================================================================
463 // purpose : Reverts to fixed-function graphics pipeline (FFP)
464 // =======================================================================
465 void OpenGl_ShaderProgram::Unbind (const Handle(OpenGl_Context)& theCtx)
467 if (theCtx->ShaderManager()->myIsPP)
469 theCtx->core20->glUseProgram (NO_PROGRAM);
470 theCtx->ShaderManager()->myIsPP = Standard_False;
474 // =======================================================================
475 // function : ActiveState
476 // purpose : Returns index of last modification for specified state type
477 // =======================================================================
478 Standard_Size OpenGl_ShaderProgram::ActiveState (const OpenGl_UniformStateType theType) const
480 if (theType < MaxStateTypes)
482 return myCurrentState[theType];
487 // =======================================================================
488 // function : UpdateState
489 // purpose : Updates index of last modification for specified state type
490 // =======================================================================
491 void OpenGl_ShaderProgram::UpdateState (const OpenGl_UniformStateType theType,
492 const Standard_Size theIndex)
494 if (theType < MaxStateTypes)
496 myCurrentState[theType] = theIndex;
500 // =======================================================================
501 // function : GetUniformLocation
502 // purpose : Returns location (index) of the specific uniform variable
503 // =======================================================================
504 GLint OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& theCtx,
505 const GLchar* theName) const
507 return myProgramID != NO_PROGRAM
508 ? theCtx->core20->glGetUniformLocation (myProgramID, theName)
512 // =======================================================================
513 // function : GetAttributeLocation
514 // purpose : Returns location (index) of the generic vertex attribute
515 // =======================================================================
516 GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)& theCtx,
517 const GLchar* theName) const
519 return myProgramID != NO_PROGRAM
520 ? theCtx->core20->glGetAttribLocation (myProgramID, theName)
524 // =======================================================================
525 // function : GetStateLocation
526 // purpose : Returns location of the OCCT state uniform variable
527 // =======================================================================
528 GLint OpenGl_ShaderProgram::GetStateLocation (const GLuint theVariable) const
530 if (theVariable < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES)
532 return myStateLocations[theVariable];
534 return INVALID_LOCATION;
537 // =======================================================================
538 // function : GetUniform
539 // purpose : Returns the value of the integer uniform variable
540 // =======================================================================
541 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
542 const GLchar* theName,
543 OpenGl_Vec4i& theValue) const
545 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
548 // =======================================================================
549 // function : GetUniform
550 // purpose : Returns the value of the integer uniform variable
551 // =======================================================================
552 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
554 OpenGl_Vec4i& theValue) const
556 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
558 return Standard_False;
561 theCtx->core20->glGetUniformiv (myProgramID, theLocation, theValue);
562 return Standard_True;
565 // =======================================================================
566 // function : GetUniform
567 // purpose : Returns the value of the floating-point uniform variable
568 // =======================================================================
569 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
570 const GLchar* theName,
571 OpenGl_Vec4& theValue) const
573 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
576 // =======================================================================
577 // function : GetUniform
578 // purpose : Returns the value of the floating-point uniform variable
579 // =======================================================================
580 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
582 OpenGl_Vec4& theValue) const
584 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
586 return Standard_False;
589 theCtx->core20->glGetUniformfv (myProgramID, theLocation, theValue);
590 return Standard_True;
593 // =======================================================================
594 // function : GetAttribute
595 // purpose : Returns the integer vertex attribute
596 // =======================================================================
597 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
598 const GLchar* theName,
599 OpenGl_Vec4i& theValue) const
601 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
604 // =======================================================================
605 // function : GetAttribute
606 // purpose : Returns the integer vertex attribute
607 // =======================================================================
608 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
610 OpenGl_Vec4i& theValue) const
612 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
614 return Standard_False;
617 theCtx->core20->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
618 return Standard_True;
621 // =======================================================================
622 // function : GetAttribute
623 // purpose : Returns the floating-point vertex attribute
624 // =======================================================================
625 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
626 const GLchar* theName,
627 OpenGl_Vec4& theValue) const
629 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
632 // =======================================================================
633 // function : GetAttribute
634 // purpose : Returns the floating-point vertex attribute
635 // =======================================================================
636 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
638 OpenGl_Vec4& theValue) const
640 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
642 return Standard_False;
645 theCtx->core20->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
646 return Standard_True;
649 // =======================================================================
650 // function : SetAttributeName
652 // =======================================================================
653 Standard_Boolean OpenGl_ShaderProgram::SetAttributeName (const Handle(OpenGl_Context)& theCtx,
655 const GLchar* theName)
657 theCtx->core20fwd->glBindAttribLocation (myProgramID, theIndex, theName);
658 return Standard_True;
661 // =======================================================================
662 // function : SetAttribute
664 // =======================================================================
665 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
666 const GLchar* theName,
669 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
672 // =======================================================================
673 // function : SetAttribute
675 // =======================================================================
676 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
680 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
682 return Standard_False;
685 theCtx->core20fwd->glVertexAttrib1f (theIndex, theValue);
686 return Standard_True;
689 // =======================================================================
690 // function : SetAttribute
692 // =======================================================================
693 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
694 const GLchar* theName,
695 const OpenGl_Vec2& theValue)
697 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
700 // =======================================================================
701 // function : SetAttribute
703 // =======================================================================
704 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
706 const OpenGl_Vec2& theValue)
708 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
710 return Standard_False;
713 theCtx->core20fwd->glVertexAttrib2fv (theIndex, theValue);
714 return Standard_True;
717 // =======================================================================
718 // function : SetAttribute
720 // =======================================================================
721 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
722 const GLchar* theName,
723 const OpenGl_Vec3& theValue)
725 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
728 // =======================================================================
729 // function : SetAttribute
731 // =======================================================================
732 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
734 const OpenGl_Vec3& theValue)
736 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
738 return Standard_False;
741 theCtx->core20fwd->glVertexAttrib3fv (theIndex, theValue);
742 return Standard_True;
745 // =======================================================================
746 // function : SetAttribute
748 // =======================================================================
749 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
750 const GLchar* theName,
751 const OpenGl_Vec4& theValue)
753 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
756 // =======================================================================
757 // function : SetAttribute
759 // =======================================================================
760 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
762 const OpenGl_Vec4& theValue)
764 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
766 return Standard_False;
769 theCtx->core20fwd->glVertexAttrib4fv (theIndex, theValue);
770 return Standard_True;
773 // =======================================================================
774 // function : SetUniform
775 // purpose : Specifies the value of the integer uniform variable
776 // =======================================================================
777 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
778 const GLchar* theName,
781 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
784 // =======================================================================
785 // function : SetUniform
786 // purpose : Specifies the value of the integer uniform variable
787 // =======================================================================
788 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
792 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
794 return Standard_False;
797 theCtx->core20->glUniform1i (theLocation, theValue);
798 return Standard_True;
801 // =======================================================================
802 // function : SetUniform
803 // purpose : Specifies the value of the floating-point uniform variable
804 // =======================================================================
805 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
806 const GLchar* theName,
809 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
812 // =======================================================================
813 // function : SetUniform
814 // purpose : Specifies the value of the floating-point uniform variable
815 // =======================================================================
816 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
820 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
822 return Standard_False;
825 theCtx->core20->glUniform1f (theLocation, theValue);
826 return Standard_True;
829 // =======================================================================
830 // function : SetUniform
831 // purpose : Specifies the value of the integer uniform 2D vector
832 // =======================================================================
833 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
834 const GLchar* theName,
835 const OpenGl_Vec2i& theValue)
837 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
840 // =======================================================================
841 // function : SetUniform
842 // purpose : Specifies the value of the integer uniform 2D vector
843 // =======================================================================
844 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
846 const OpenGl_Vec2i& theValue)
848 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
850 return Standard_False;
853 theCtx->core20->glUniform2iv (theLocation, 1, theValue);
854 return Standard_True;
857 // =======================================================================
858 // function : SetUniform
859 // purpose : Specifies the value of the integer uniform 3D vector
860 // =======================================================================
861 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
862 const GLchar* theName,
863 const OpenGl_Vec3i& theValue)
865 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
868 // =======================================================================
869 // function : SetUniform
870 // purpose : Specifies the value of the integer uniform 3D vector
871 // =======================================================================
872 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
874 const OpenGl_Vec3i& theValue)
876 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
878 return Standard_False;
881 theCtx->core20->glUniform3iv (theLocation, 1, theValue);
882 return Standard_True;
885 // =======================================================================
886 // function : SetUniform
887 // purpose : Specifies the value of the integer uniform 4D vector
888 // =======================================================================
889 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
890 const GLchar* theName,
891 const OpenGl_Vec4i& theValue)
893 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
896 // =======================================================================
897 // function : SetUniform
898 // purpose : Specifies the value of the integer uniform 4D vector
899 // =======================================================================
900 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
902 const OpenGl_Vec4i& theValue)
904 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
906 return Standard_False;
909 theCtx->core20->glUniform4iv (theLocation, 1, theValue);
910 return Standard_True;
913 // =======================================================================
914 // function : SetUniform
915 // purpose : Specifies the value of the floating-point uniform 2D vector
916 // =======================================================================
917 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
918 const GLchar* theName,
919 const OpenGl_Vec2& theValue)
921 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
924 // =======================================================================
925 // function : SetUniform
926 // purpose : Specifies the value of the floating-point uniform 2D vector
927 // =======================================================================
928 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
930 const OpenGl_Vec2& theValue)
932 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
934 return Standard_False;
937 theCtx->core20->glUniform2fv (theLocation, 1, theValue);
938 return Standard_True;
941 // =======================================================================
942 // function : SetUniform
943 // purpose : Specifies the value of the floating-point uniform 3D vector
944 // =======================================================================
945 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
946 const GLchar* theName,
947 const OpenGl_Vec3& theValue)
949 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
952 // =======================================================================
953 // function : SetUniform
954 // purpose : Specifies the value of the floating-point uniform 3D vector
955 // =======================================================================
956 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
958 const OpenGl_Vec3& theValue)
960 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
962 return Standard_False;
965 theCtx->core20->glUniform3fv (theLocation, 1, theValue);
966 return Standard_True;
969 // =======================================================================
970 // function : SetUniform
971 // purpose : Specifies the value of the floating-point uniform 4D vector
972 // =======================================================================
973 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
974 const GLchar* theName,
975 const OpenGl_Vec4& theValue)
977 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
980 // =======================================================================
981 // function : SetUniform
982 // purpose : Specifies the value of the floating-point uniform 4D vector
983 // =======================================================================
984 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
986 const OpenGl_Vec4& theValue)
988 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
990 return Standard_False;
993 theCtx->core20->glUniform4fv (theLocation, 1, theValue);
994 return Standard_True;
997 // =======================================================================
998 // function : SetUniform
999 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1000 // =======================================================================
1001 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1002 const GLchar* theName,
1003 const OpenGl_Matrix& theValue,
1004 GLboolean theTranspose)
1006 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1009 // =======================================================================
1010 // function : SetUniform
1011 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1012 // =======================================================================
1013 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1015 const OpenGl_Matrix& theValue,
1016 GLboolean theTranspose)
1018 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1020 return Standard_False;
1023 theCtx->core20->glUniformMatrix4fv (theLocation, 1, theTranspose, *theValue.mat);
1024 return Standard_True;
1027 // =======================================================================
1028 // function : SetUniform
1029 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1030 // =======================================================================
1031 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1032 const GLchar* theName,
1033 const Tmatrix3& theValue,
1034 GLboolean theTranspose)
1036 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1039 // =======================================================================
1040 // function : SetUniform
1041 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1042 // =======================================================================
1043 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1045 const Tmatrix3& theValue,
1046 GLboolean theTranspose)
1048 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1050 return Standard_False;
1053 theCtx->core20->glUniformMatrix4fv (theLocation, 1, theTranspose, *theValue);
1054 return Standard_True;
1057 // =======================================================================
1058 // function : SetUniform
1059 // purpose : Specifies the value of the float uniform array
1060 // =======================================================================
1061 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1064 const Standard_ShortReal* theData)
1066 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1068 return Standard_False;
1071 theCtx->core20->glUniform1fv (theLocation, theCount, theData);
1072 return Standard_True;
1075 // =======================================================================
1076 // function : SetUniform
1077 // purpose : Specifies the value of the float2 uniform array
1078 // =======================================================================
1079 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1082 const OpenGl_Vec2* theData)
1084 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1086 return Standard_False;
1089 theCtx->core20->glUniform2fv (theLocation, theCount, theData[0].GetData());
1090 return Standard_True;
1093 // =======================================================================
1094 // function : SetUniform
1095 // purpose : Specifies the value of the float3 uniform array
1096 // =======================================================================
1097 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1100 const OpenGl_Vec3* theData)
1102 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1104 return Standard_False;
1107 theCtx->core20->glUniform3fv (theLocation, theCount, theData[0].GetData());
1108 return Standard_True;
1111 // =======================================================================
1112 // function : SetUniform
1113 // purpose : Specifies the value of the float4 uniform array
1114 // =======================================================================
1115 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1118 const OpenGl_Vec4* theData)
1120 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1122 return Standard_False;
1125 theCtx->core20->glUniform4fv (theLocation, theCount, theData[0].GetData());
1126 return Standard_True;
1129 // =======================================================================
1130 // function : SetUniform
1131 // purpose : Specifies the value of the integer uniform array
1132 // =======================================================================
1133 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1136 const Standard_Integer* theData)
1138 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1140 return Standard_False;
1143 theCtx->core20->glUniform1iv (theLocation, theCount, theData);
1144 return Standard_True;
1147 // =======================================================================
1148 // function : SetUniform
1149 // purpose : Specifies the value of the int2 uniform array
1150 // =======================================================================
1151 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1154 const OpenGl_Vec2i* theData)
1156 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1158 return Standard_False;
1161 theCtx->core20->glUniform2iv (theLocation, theCount, theData[0].GetData());
1162 return Standard_True;
1165 // =======================================================================
1166 // function : SetUniform
1167 // purpose : Specifies the value of the int3 uniform array
1168 // =======================================================================
1169 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1172 const OpenGl_Vec3i* theData)
1174 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1176 return Standard_False;
1179 theCtx->core20->glUniform3iv (theLocation, theCount, theData[0].GetData());
1180 return Standard_True;
1183 // =======================================================================
1184 // function : SetUniform
1185 // purpose : Specifies the value of the int4 uniform array
1186 // =======================================================================
1187 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1190 const OpenGl_Vec4i* theData)
1192 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1194 return Standard_False;
1197 theCtx->core20->glUniform4iv (theLocation, theCount, theData[0].GetData());
1198 return Standard_True;
1201 // =======================================================================
1202 // function : SetSampler
1203 // purpose : Specifies the value of the sampler uniform variable
1204 // =======================================================================
1205 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1206 const GLchar* theName,
1207 const GLenum theTextureUnit)
1209 return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit);
1212 // =======================================================================
1213 // function : SetSampler
1214 // purpose : Specifies the value of the sampler uniform variable
1215 // =======================================================================
1216 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1218 const GLenum theTextureUnit)
1220 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1222 return Standard_False;
1225 theCtx->core20->glUniform1i (theLocation, theTextureUnit);
1226 return Standard_True;
1229 // =======================================================================
1230 // function : Create
1231 // purpose : Creates new empty shader program of specified type
1232 // =======================================================================
1233 Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx)
1235 if (myProgramID == NO_PROGRAM
1236 && theCtx->core20 != NULL)
1238 myProgramID = theCtx->core20->glCreateProgram();
1241 return myProgramID != NO_PROGRAM;
1244 // =======================================================================
1245 // function : Release
1246 // purpose : Destroys shader program
1247 // =======================================================================
1248 void OpenGl_ShaderProgram::Release (OpenGl_Context* theCtx)
1250 if (myProgramID == NO_PROGRAM)
1255 Standard_ASSERT_RETURN (theCtx != NULL,
1256 "OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...",);
1258 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
1260 if (!anIter.Value().IsNull())
1262 anIter.ChangeValue()->Release (theCtx);
1263 anIter.ChangeValue().Nullify();
1267 if (theCtx->core20 != NULL
1268 && theCtx->IsValid())
1270 theCtx->core20->glDeleteProgram (myProgramID);
1273 myProgramID = NO_PROGRAM;