1 // Created on: 2013-09-19
2 // Created by: Denis BOGOLEPOV
3 // Copyright (c) 2013-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <OSD_File.hxx>
17 #include <OSD_Protection.hxx>
19 #include <Graphic3d_Buffer.hxx>
20 #include <Standard_Assert.hxx>
21 #include <Standard_Atomic.hxx>
22 #include <TCollection_ExtendedString.hxx>
24 #include <OpenGl_Context.hxx>
25 #include <OpenGl_ShaderProgram.hxx>
26 #include <OpenGl_ShaderManager.hxx>
27 #include <OpenGl_ArbTexBindless.hxx>
29 #include <OpenGl_GlCore32.hxx>
31 #include "../Shaders/Shaders_DeclarationsImpl_glsl.pxx"
32 #include "../Shaders/Shaders_Declarations_glsl.pxx"
35 #include <malloc.h> // for alloca()
38 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderProgram, OpenGl_NamedResource)
40 OpenGl_VariableSetterSelector OpenGl_ShaderProgram::mySetterSelector = OpenGl_VariableSetterSelector();
42 // Declare OCCT-specific OpenGL/GLSL shader variables
43 Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] =
45 "occModelWorldMatrix", // OpenGl_OCC_MODEL_WORLD_MATRIX
46 "occWorldViewMatrix", // OpenGl_OCC_WORLD_VIEW_MATRIX
47 "occProjectionMatrix", // OpenGl_OCC_PROJECTION_MATRIX
48 "occModelWorldMatrixInverse", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE
49 "occWorldViewMatrixInverse", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE
50 "occProjectionMatrixInverse", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE
51 "occModelWorldMatrixTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE
52 "occWorldViewMatrixTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE
53 "occProjectionMatrixTranspose", // OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE
54 "occModelWorldMatrixInverseTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE
55 "occWorldViewMatrixInverseTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE
56 "occProjectionMatrixInverseTranspose", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE
58 "occClipPlaneEquations", // OpenGl_OCC_CLIP_PLANE_EQUATIONS
59 "occClipPlaneCount", // OpenGl_OCC_CLIP_PLANE_COUNT
61 "occLightSourcesCount", // OpenGl_OCC_LIGHT_SOURCE_COUNT
62 "occLightSourcesTypes", // OpenGl_OCC_LIGHT_SOURCE_TYPES
63 "occLightSources", // OpenGl_OCC_LIGHT_SOURCE_PARAMS
64 "occLightAmbient", // OpenGl_OCC_LIGHT_AMBIENT
66 "occTextureEnable", // OpenGl_OCCT_TEXTURE_ENABLE
67 "occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE
68 "occFrontMaterial", // OpenGl_OCCT_FRONT_MATERIAL
69 "occBackMaterial", // OpenGl_OCCT_BACK_MATERIAL
70 "occAlphaCutoff", // OpenGl_OCCT_ALPHA_CUTOFF
71 "occColor", // OpenGl_OCCT_COLOR
73 "occOitOutput", // OpenGl_OCCT_OIT_OUTPUT
74 "occOitDepthFactor", // OpenGl_OCCT_OIT_DEPTH_FACTOR
76 "occTexTrsf2d", // OpenGl_OCCT_TEXTURE_TRSF2D
77 "occPointSize" // OpenGl_OCCT_POINT_SIZE
82 //! Convert Graphic3d_TypeOfShaderObject enumeration into OpenGL enumeration.
83 static GLenum shaderTypeToGl (Graphic3d_TypeOfShaderObject theType)
87 case Graphic3d_TOS_VERTEX: return GL_VERTEX_SHADER;
88 case Graphic3d_TOS_FRAGMENT: return GL_FRAGMENT_SHADER;
89 case Graphic3d_TOS_GEOMETRY: return GL_GEOMETRY_SHADER;
90 case Graphic3d_TOS_TESS_CONTROL: return GL_TESS_CONTROL_SHADER;
91 case Graphic3d_TOS_TESS_EVALUATION: return GL_TESS_EVALUATION_SHADER;
92 case Graphic3d_TOS_COMPUTE: return GL_COMPUTE_SHADER;
98 // =======================================================================
99 // function : OpenGl_VariableSetterSelector
100 // purpose : Creates new variable setter selector
101 // =======================================================================
102 OpenGl_VariableSetterSelector::OpenGl_VariableSetterSelector()
104 // Note: Add new variable setters here
105 mySetterList = OpenGl_HashMapInitializer::CreateListOf<size_t, OpenGl_SetterInterface*>
106 (Graphic3d_UniformValueTypeID<int>::ID, new OpenGl_VariableSetter<int>())
107 (Graphic3d_UniformValueTypeID<float>::ID, new OpenGl_VariableSetter<float>())
108 (Graphic3d_UniformValueTypeID<OpenGl_Vec2>::ID, new OpenGl_VariableSetter<OpenGl_Vec2>())
109 (Graphic3d_UniformValueTypeID<OpenGl_Vec3>::ID, new OpenGl_VariableSetter<OpenGl_Vec3>())
110 (Graphic3d_UniformValueTypeID<OpenGl_Vec4>::ID, new OpenGl_VariableSetter<OpenGl_Vec4>())
111 (Graphic3d_UniformValueTypeID<OpenGl_Vec2i>::ID, new OpenGl_VariableSetter<OpenGl_Vec2i>())
112 (Graphic3d_UniformValueTypeID<OpenGl_Vec3i>::ID, new OpenGl_VariableSetter<OpenGl_Vec3i>())
113 (Graphic3d_UniformValueTypeID<OpenGl_Vec4i>::ID, new OpenGl_VariableSetter<OpenGl_Vec4i>());
116 // =======================================================================
117 // function : ~OpenGl_VariableSetterSelector
118 // purpose : Releases memory resources of variable setter selector
119 // =======================================================================
120 OpenGl_VariableSetterSelector::~OpenGl_VariableSetterSelector()
122 for (OpenGl_SetterList::Iterator anIt (mySetterList); anIt.More(); anIt.Next())
127 mySetterList.Clear();
130 // =======================================================================
132 // purpose : Sets generic variable to specified shader program
133 // =======================================================================
134 void OpenGl_VariableSetterSelector::Set (const Handle(OpenGl_Context)& theCtx,
135 const Handle(Graphic3d_ShaderVariable)& theVariable,
136 OpenGl_ShaderProgram* theProgram) const
138 Standard_ASSERT_RETURN (mySetterList.IsBound (theVariable->Value()->TypeID()),
139 "The type of user-defined uniform variable is not supported...", );
141 mySetterList.Find (theVariable->Value()->TypeID())->Set (theCtx, theVariable, theProgram);
144 // =======================================================================
145 // function : OpenGl_ShaderProgram
146 // purpose : Creates uninitialized shader program
147 // =======================================================================
148 OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy)
149 : OpenGl_NamedResource (!theProxy.IsNull() ? theProxy->GetId() : ""),
150 myProgramID (NO_PROGRAM),
154 myNbClipPlanesMax (0),
156 myHasAlphaTest (false),
157 myHasWeightOitOutput (false),
158 myHasTessShader (false)
160 memset (myCurrentState, 0, sizeof (myCurrentState));
161 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
163 myStateLocations[aVar] = INVALID_LOCATION;
167 // =======================================================================
168 // function : Initialize
169 // purpose : Initializes program object with the list of shader objects
170 // =======================================================================
171 Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& theCtx,
172 const Graphic3d_ShaderObjectList& theShaders)
174 myHasTessShader = false;
175 if (theCtx.IsNull() || !Create (theCtx))
177 return Standard_False;
180 TCollection_AsciiString aHeaderVer = !myProxy.IsNull() ? myProxy->Header() : TCollection_AsciiString();
182 for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders); anIter.More(); anIter.Next())
184 aShaderMask |= anIter.Value()->Type();
186 myHasTessShader = (aShaderMask & (Graphic3d_TOS_TESS_CONTROL | Graphic3d_TOS_TESS_EVALUATION)) != 0;
187 myNbFragOutputs = !myProxy.IsNull() ? myProxy->NbFragmentOutputs() : 1;
188 myHasAlphaTest = !myProxy.IsNull() && myProxy->HasAlphaTest();
189 myHasWeightOitOutput = !myProxy.IsNull() ? myProxy->HasWeightOitOutput() && myNbFragOutputs >= 2 : 1;
191 // detect the minimum GLSL version required for defined Shader Objects
192 #if defined(GL_ES_VERSION_2_0)
194 || (aShaderMask & Graphic3d_TOS_GEOMETRY) != 0)
196 if (!theCtx->IsGlGreaterEqual (3, 2))
198 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
199 "Error! Geometry and Tessellation shaders require OpenGL ES 3.2+");
202 else if (aHeaderVer.IsEmpty())
204 aHeaderVer = "#version 320 es";
207 else if ((aShaderMask & Graphic3d_TOS_COMPUTE) != 0)
209 if (!theCtx->IsGlGreaterEqual (3, 1))
211 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
212 "Error! Compute shaders require OpenGL ES 3.1+");
215 else if (aHeaderVer.IsEmpty())
217 aHeaderVer = "#version 310 es";
221 if ((aShaderMask & Graphic3d_TOS_COMPUTE) != 0)
223 if (!theCtx->IsGlGreaterEqual (4, 3))
225 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
226 "Error! Compute shaders require OpenGL 4.3+");
229 else if (aHeaderVer.IsEmpty())
231 aHeaderVer = "#version 430";
234 else if (myHasTessShader)
236 if (!theCtx->IsGlGreaterEqual (4, 0))
238 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
239 "Error! Tessellation shaders require OpenGL 4.0+");
242 else if (aHeaderVer.IsEmpty())
244 aHeaderVer = "#version 400";
247 else if ((aShaderMask & Graphic3d_TOS_GEOMETRY) != 0)
249 if (!theCtx->IsGlGreaterEqual (3, 2))
251 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
252 "Error! Geometry shaders require OpenGL 3.2+");
255 else if (aHeaderVer.IsEmpty())
257 aHeaderVer = "#version 150";
262 for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders); anIter.More(); anIter.Next())
264 if (!anIter.Value()->IsDone())
266 const TCollection_ExtendedString aMsg = "Error! Failed to get shader source";
267 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
268 return Standard_False;
271 const GLenum aShaderType = shaderTypeToGl (anIter.Value()->Type());
272 if (aShaderType == 0)
274 return Standard_False;
277 Handle(OpenGl_ShaderObject) aShader = new OpenGl_ShaderObject (aShaderType);
278 if (!aShader->Create (theCtx))
280 aShader->Release (theCtx.operator->());
281 return Standard_False;
284 TCollection_AsciiString anExtensions = "// Enable extensions used in OCCT GLSL programs\n";
285 if (myNbFragOutputs > 1)
287 if (theCtx->hasDrawBuffers)
289 anExtensions += "#define OCC_ENABLE_draw_buffers\n";
290 if (myHasWeightOitOutput)
292 anExtensions += "#define OCC_WRITE_WEIGHT_OIT_COVERAGE\n";
297 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
298 "Error! Multiple draw buffers required by the program, but aren't supported by OpenGL");
299 return Standard_False;
302 if (theCtx->hasDrawBuffers == OpenGl_FeatureInExtensions)
304 if (theCtx->arbDrawBuffers)
306 anExtensions += "#extension GL_ARB_draw_buffers : enable\n";
308 else if (theCtx->extDrawBuffers)
310 anExtensions += "#extension GL_EXT_draw_buffers : enable\n";
316 anExtensions += "#define OCC_ALPHA_TEST\n";
319 if (theCtx->hasSampleVariables == OpenGl_FeatureInExtensions)
321 #if defined(GL_ES_VERSION_2_0)
322 if (theCtx->oesSampleVariables)
324 anExtensions += "#extension GL_OES_sample_variables : enable\n";
327 if (theCtx->arbSampleShading)
329 anExtensions += "#extension GL_ARB_sample_shading : enable\n";
334 TCollection_AsciiString aPrecisionHeader;
335 if (anIter.Value()->Type() == Graphic3d_TOS_FRAGMENT)
337 #if defined(GL_ES_VERSION_2_0)
338 aPrecisionHeader = theCtx->hasHighp
339 ? "precision highp float;\n"
340 "precision highp int;\n"
341 : "precision mediump float;\n"
342 "precision mediump int;\n";
346 TCollection_AsciiString aHeaderType;
347 switch (anIter.Value()->Type())
349 case Graphic3d_TOS_COMPUTE: { aHeaderType = "#define COMPUTE_SHADER\n"; break; }
350 case Graphic3d_TOS_VERTEX: { aHeaderType = "#define VERTEX_SHADER\n"; break; }
351 case Graphic3d_TOS_TESS_CONTROL: { aHeaderType = "#define TESS_CONTROL_SHADER\n"; break; }
352 case Graphic3d_TOS_TESS_EVALUATION: { aHeaderType = "#define TESS_EVALUATION_SHADER\n"; break; }
353 case Graphic3d_TOS_GEOMETRY: { aHeaderType = "#define GEOMETRY_SHADER\n"; break; }
354 case Graphic3d_TOS_FRAGMENT: { aHeaderType = "#define FRAGMENT_SHADER\n"; break; }
357 TCollection_AsciiString aHeaderConstants;
358 myNbLightsMax = !myProxy.IsNull() ? myProxy->NbLightsMax() : 0;
359 myNbClipPlanesMax = !myProxy.IsNull() ? myProxy->NbClipPlanesMax() : 0;
360 aHeaderConstants += TCollection_AsciiString("#define THE_MAX_LIGHTS ") + myNbLightsMax + "\n";
361 aHeaderConstants += TCollection_AsciiString("#define THE_MAX_CLIP_PLANES ") + myNbClipPlanesMax + "\n";
362 aHeaderConstants += TCollection_AsciiString("#define THE_NB_FRAG_OUTPUTS ") + myNbFragOutputs + "\n";
364 const TCollection_AsciiString aSource = aHeaderVer // #version - header defining GLSL version, should be first
365 + (!aHeaderVer.IsEmpty() ? "\n" : "")
366 + anExtensions // #extension - list of enabled extensions, should be second
367 + aPrecisionHeader // precision - default precision qualifiers, should be before any code
368 + aHeaderType // auxiliary macros defining a shader stage (type)
370 + Shaders_Declarations_glsl // common declarations (global constants and Vertex Shader inputs)
371 + Shaders_DeclarationsImpl_glsl
372 + anIter.Value()->Source(); // the source code itself (defining main() function)
373 if (!aShader->LoadSource (theCtx, aSource))
375 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aSource);
376 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, "Error! Failed to set shader source");
377 aShader->Release (theCtx.operator->());
378 return Standard_False;
381 if (!aShader->Compile (theCtx))
383 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aSource);
384 TCollection_AsciiString aLog;
385 aShader->FetchInfoLog (theCtx, aLog);
388 aLog = "Compilation log is empty.";
390 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
391 TCollection_ExtendedString ("Failed to compile shader object. Compilation log:\n") + aLog);
392 aShader->Release (theCtx.operator->());
393 return Standard_False;
395 else if (theCtx->caps->glslWarnings)
397 TCollection_AsciiString aLog;
398 aShader->FetchInfoLog (theCtx, aLog);
400 && !aLog.IsEqual ("No errors.\n"))
402 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_LOW,
403 TCollection_ExtendedString ("Shader compilation log:\n") + aLog);
407 if (!AttachShader (theCtx, aShader))
409 aShader->Release (theCtx.operator->());
410 return Standard_False;
414 // bind locations for pre-defined Vertex Attributes
415 SetAttributeName (theCtx, Graphic3d_TOA_POS, "occVertex");
416 SetAttributeName (theCtx, Graphic3d_TOA_NORM, "occNormal");
417 SetAttributeName (theCtx, Graphic3d_TOA_UV, "occTexCoord");
418 SetAttributeName (theCtx, Graphic3d_TOA_COLOR, "occVertColor");
420 // bind custom Vertex Attributes
421 if (!myProxy.IsNull())
423 for (Graphic3d_ShaderAttributeList::Iterator anAttribIter (myProxy->VertexAttributes());
424 anAttribIter.More(); anAttribIter.Next())
426 SetAttributeName (theCtx, anAttribIter.Value()->Location(), anAttribIter.Value()->Name().ToCString());
432 TCollection_AsciiString aLog;
433 FetchInfoLog (theCtx, aLog);
436 aLog = "Linker log is empty.";
438 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
439 TCollection_ExtendedString ("Failed to link program object! Linker log:\n") + aLog);
440 return Standard_False;
442 else if (theCtx->caps->glslWarnings)
444 TCollection_AsciiString aLog;
445 FetchInfoLog (theCtx, aLog);
447 && !aLog.IsEqual ("No errors.\n"))
449 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_LOW,
450 TCollection_ExtendedString ("GLSL linker log:\n") + aLog);
454 // set uniform defaults
455 const Handle(OpenGl_ShaderProgram)& anOldProgram = theCtx->ActiveProgram();
456 theCtx->core20fwd->glUseProgram (myProgramID);
458 const GLint aLocTexEnable = GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE);
459 if (aLocTexEnable != INVALID_LOCATION)
461 SetUniform (theCtx, aLocTexEnable, 0); // Off
465 const GLint aLocSampler = GetUniformLocation (theCtx, "occActiveSampler");
466 if (aLocSampler != INVALID_LOCATION)
468 SetUniform (theCtx, aLocSampler, GLint(Graphic3d_TextureUnit_0));
472 const TCollection_AsciiString aSamplerNamePrefix ("occSampler");
473 const Standard_Integer aNbUnitsMax = Max (theCtx->MaxCombinedTextureUnits(), Graphic3d_TextureUnit_NB);
474 for (GLint aUnitIter = 0; aUnitIter < aNbUnitsMax; ++aUnitIter)
476 const TCollection_AsciiString aName = aSamplerNamePrefix + aUnitIter;
477 const GLint aLocSampler = GetUniformLocation (theCtx, aName.ToCString());
478 if (aLocSampler != INVALID_LOCATION)
480 SetUniform (theCtx, aLocSampler, aUnitIter);
484 theCtx->core20fwd->glUseProgram (!anOldProgram.IsNull() ? anOldProgram->ProgramId() : OpenGl_ShaderProgram::NO_PROGRAM);
485 return Standard_True;
488 // =======================================================================
489 // function : ~OpenGl_ShaderProgram
490 // purpose : Releases resources of shader program
491 // =======================================================================
492 OpenGl_ShaderProgram::~OpenGl_ShaderProgram()
497 // =======================================================================
498 // function : AttachShader
499 // purpose : Attaches shader object to the program object
500 // =======================================================================
501 Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context)& theCtx,
502 const Handle(OpenGl_ShaderObject)& theShader)
504 if (myProgramID == NO_PROGRAM || theShader.IsNull())
506 return Standard_False;
509 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
511 if (theShader == anIter.Value())
513 return Standard_False;
517 myShaderObjects.Append (theShader);
518 theCtx->core20fwd->glAttachShader (myProgramID, theShader->myShaderID);
519 return Standard_True;
522 // =======================================================================
523 // function : DetachShader
524 // purpose : Detaches shader object to the program object
525 // =======================================================================
526 Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context)& theCtx,
527 const Handle(OpenGl_ShaderObject)& theShader)
529 if (myProgramID == NO_PROGRAM
530 || theShader.IsNull())
532 return Standard_False;
535 OpenGl_ShaderList::Iterator anIter (myShaderObjects);
536 while (anIter.More())
538 if (theShader == anIter.Value())
540 myShaderObjects.Remove (anIter);
549 return Standard_False;
552 theCtx->core20fwd->glDetachShader (myProgramID, theShader->myShaderID);
553 return Standard_True;
556 // =======================================================================
558 // purpose : Links the program object
559 // =======================================================================
560 Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx)
562 if (myProgramID == NO_PROGRAM)
564 return Standard_False;
567 GLint aStatus = GL_FALSE;
568 theCtx->core20fwd->glLinkProgram (myProgramID);
569 theCtx->core20fwd->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
570 if (aStatus == GL_FALSE)
572 return Standard_False;
575 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
577 myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]);
579 return Standard_True;
582 // =======================================================================
583 // function : FetchInfoLog
584 // purpose : Fetches information log of the last link operation
585 // =======================================================================
586 Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
587 TCollection_AsciiString& theOutput)
589 if (myProgramID == NO_PROGRAM)
591 return Standard_False;
595 theCtx->core20fwd->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
598 GLchar* aLog = (GLchar*) alloca (aLength);
599 memset (aLog, 0, aLength);
600 theCtx->core20fwd->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
603 return Standard_True;
606 // =======================================================================
607 // function : ApplyVariables
608 // purpose : Fetches uniform variables from proxy shader program
609 // =======================================================================
610 Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Context)& theCtx)
612 if (myProxy.IsNull() || myProxy->Variables().IsEmpty())
614 return Standard_False;
617 for (Graphic3d_ShaderVariableList::Iterator anIter (myProxy->Variables()); anIter.More(); anIter.Next())
619 mySetterSelector.Set (theCtx, anIter.Value(), this);
622 myProxy->ClearVariables();
623 return Standard_True;
626 // =======================================================================
627 // function : GetUniformLocation
628 // purpose : Returns location (index) of the specific uniform variable
629 // =======================================================================
630 GLint OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& theCtx,
631 const GLchar* theName) const
633 return myProgramID != NO_PROGRAM
634 ? theCtx->core20fwd->glGetUniformLocation (myProgramID, theName)
638 // =======================================================================
639 // function : GetAttributeLocation
640 // purpose : Returns location (index) of the generic vertex attribute
641 // =======================================================================
642 GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)& theCtx,
643 const GLchar* theName) const
645 return myProgramID != NO_PROGRAM
646 ? theCtx->core20fwd->glGetAttribLocation (myProgramID, theName)
650 // =======================================================================
651 // function : GetStateLocation
652 // purpose : Returns location of the OCCT state uniform variable
653 // =======================================================================
654 GLint OpenGl_ShaderProgram::GetStateLocation (const GLuint theVariable) const
656 if (theVariable < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES)
658 return myStateLocations[theVariable];
660 return INVALID_LOCATION;
663 // =======================================================================
664 // function : GetUniform
665 // purpose : Returns the value of the integer uniform variable
666 // =======================================================================
667 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
668 const GLchar* theName,
669 OpenGl_Vec4i& theValue) const
671 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
674 // =======================================================================
675 // function : GetUniform
676 // purpose : Returns the value of the integer uniform variable
677 // =======================================================================
678 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
680 OpenGl_Vec4i& theValue) const
682 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
684 return Standard_False;
687 theCtx->core20fwd->glGetUniformiv (myProgramID, theLocation, theValue);
688 return Standard_True;
691 // =======================================================================
692 // function : GetUniform
693 // purpose : Returns the value of the floating-point uniform variable
694 // =======================================================================
695 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
696 const GLchar* theName,
697 OpenGl_Vec4& theValue) const
699 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
702 // =======================================================================
703 // function : GetUniform
704 // purpose : Returns the value of the floating-point uniform variable
705 // =======================================================================
706 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
708 OpenGl_Vec4& theValue) const
710 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
712 return Standard_False;
715 theCtx->core20fwd->glGetUniformfv (myProgramID, theLocation, theValue);
716 return Standard_True;
719 // =======================================================================
720 // function : GetAttribute
721 // purpose : Returns the integer vertex attribute
722 // =======================================================================
723 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
724 const GLchar* theName,
725 OpenGl_Vec4i& theValue) const
727 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
730 // =======================================================================
731 // function : GetAttribute
732 // purpose : Returns the integer vertex attribute
733 // =======================================================================
734 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
736 OpenGl_Vec4i& theValue) const
738 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
740 return Standard_False;
743 theCtx->core20fwd->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
744 return Standard_True;
747 // =======================================================================
748 // function : GetAttribute
749 // purpose : Returns the floating-point vertex attribute
750 // =======================================================================
751 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
752 const GLchar* theName,
753 OpenGl_Vec4& theValue) const
755 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
758 // =======================================================================
759 // function : GetAttribute
760 // purpose : Returns the floating-point vertex attribute
761 // =======================================================================
762 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
764 OpenGl_Vec4& theValue) const
766 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
768 return Standard_False;
771 theCtx->core20fwd->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
772 return Standard_True;
775 // =======================================================================
776 // function : SetAttributeName
778 // =======================================================================
779 Standard_Boolean OpenGl_ShaderProgram::SetAttributeName (const Handle(OpenGl_Context)& theCtx,
781 const GLchar* theName)
783 theCtx->core20fwd->glBindAttribLocation (myProgramID, theIndex, theName);
784 return Standard_True;
787 // =======================================================================
788 // function : SetAttribute
790 // =======================================================================
791 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
792 const GLchar* theName,
795 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
798 // =======================================================================
799 // function : SetAttribute
801 // =======================================================================
802 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
806 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
808 return Standard_False;
811 theCtx->core20fwd->glVertexAttrib1f (theIndex, theValue);
812 return Standard_True;
815 // =======================================================================
816 // function : SetAttribute
818 // =======================================================================
819 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
820 const GLchar* theName,
821 const OpenGl_Vec2& theValue)
823 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
826 // =======================================================================
827 // function : SetAttribute
829 // =======================================================================
830 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
832 const OpenGl_Vec2& theValue)
834 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
836 return Standard_False;
839 theCtx->core20fwd->glVertexAttrib2fv (theIndex, theValue);
840 return Standard_True;
843 // =======================================================================
844 // function : SetAttribute
846 // =======================================================================
847 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
848 const GLchar* theName,
849 const OpenGl_Vec3& theValue)
851 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
854 // =======================================================================
855 // function : SetAttribute
857 // =======================================================================
858 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
860 const OpenGl_Vec3& theValue)
862 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
864 return Standard_False;
867 theCtx->core20fwd->glVertexAttrib3fv (theIndex, theValue);
868 return Standard_True;
871 // =======================================================================
872 // function : SetAttribute
874 // =======================================================================
875 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
876 const GLchar* theName,
877 const OpenGl_Vec4& theValue)
879 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
882 // =======================================================================
883 // function : SetAttribute
885 // =======================================================================
886 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
888 const OpenGl_Vec4& theValue)
890 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
892 return Standard_False;
895 theCtx->core20fwd->glVertexAttrib4fv (theIndex, theValue);
896 return Standard_True;
899 // =======================================================================
900 // function : SetUniform
901 // purpose : Specifies the value of the integer uniform variable
902 // =======================================================================
903 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
904 const GLchar* theName,
907 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
910 // =======================================================================
911 // function : SetUniform
912 // purpose : Specifies the value of the integer uniform variable
913 // =======================================================================
914 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
918 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
920 return Standard_False;
923 theCtx->core20fwd->glUniform1i (theLocation, theValue);
924 return Standard_True;
927 // =======================================================================
928 // function : SetUniform
930 // =======================================================================
931 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
932 const GLchar* theName,
933 const OpenGl_Vec2u& theValue)
935 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
938 // =======================================================================
939 // function : SetUniform
941 // =======================================================================
942 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
944 const OpenGl_Vec2u& theValue)
946 if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
948 return Standard_False;
951 #if !defined(GL_ES_VERSION_2_0)
952 theCtx->core32->glUniform2uiv (theLocation, 1, theValue.GetData());
953 return Standard_True;
956 return Standard_False;
960 // =======================================================================
961 // function : SetUniform
963 // =======================================================================
964 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
965 const GLchar* theName,
966 const GLsizei theCount,
967 const OpenGl_Vec2u* theValue)
969 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theCount, theValue);
972 // =======================================================================
973 // function : SetUniform
975 // =======================================================================
976 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
978 const GLsizei theCount,
979 const OpenGl_Vec2u* theValue)
981 if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
983 return Standard_False;
986 #if !defined(GL_ES_VERSION_2_0)
987 theCtx->core32->glUniform2uiv (theLocation, theCount, theValue->GetData());
988 return Standard_True;
992 return Standard_False;
996 // =======================================================================
997 // function : SetUniform
998 // purpose : Specifies the value of the floating-point uniform variable
999 // =======================================================================
1000 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1001 const GLchar* theName,
1004 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1007 // =======================================================================
1008 // function : SetUniform
1009 // purpose : Specifies the value of the floating-point uniform variable
1010 // =======================================================================
1011 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1015 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1017 return Standard_False;
1020 theCtx->core20fwd->glUniform1f (theLocation, theValue);
1021 return Standard_True;
1024 // =======================================================================
1025 // function : SetUniform
1026 // purpose : Specifies the value of the integer uniform 2D vector
1027 // =======================================================================
1028 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1029 const GLchar* theName,
1030 const OpenGl_Vec2i& theValue)
1032 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1035 // =======================================================================
1036 // function : SetUniform
1037 // purpose : Specifies the value of the integer uniform 2D vector
1038 // =======================================================================
1039 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1041 const OpenGl_Vec2i& theValue)
1043 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1045 return Standard_False;
1048 theCtx->core20fwd->glUniform2iv (theLocation, 1, theValue);
1049 return Standard_True;
1052 // =======================================================================
1053 // function : SetUniform
1054 // purpose : Specifies the value of the integer uniform 3D vector
1055 // =======================================================================
1056 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1057 const GLchar* theName,
1058 const OpenGl_Vec3i& theValue)
1060 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1063 // =======================================================================
1064 // function : SetUniform
1065 // purpose : Specifies the value of the integer uniform 3D vector
1066 // =======================================================================
1067 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1069 const OpenGl_Vec3i& theValue)
1071 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1073 return Standard_False;
1076 theCtx->core20fwd->glUniform3iv (theLocation, 1, theValue);
1077 return Standard_True;
1080 // =======================================================================
1081 // function : SetUniform
1082 // purpose : Specifies the value of the integer uniform 4D vector
1083 // =======================================================================
1084 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1085 const GLchar* theName,
1086 const OpenGl_Vec4i& theValue)
1088 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1091 // =======================================================================
1092 // function : SetUniform
1093 // purpose : Specifies the value of the integer uniform 4D vector
1094 // =======================================================================
1095 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1097 const OpenGl_Vec4i& theValue)
1099 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1101 return Standard_False;
1104 theCtx->core20fwd->glUniform4iv (theLocation, 1, theValue);
1105 return Standard_True;
1108 // =======================================================================
1109 // function : SetUniform
1110 // purpose : Specifies the value of the floating-point uniform 2D vector
1111 // =======================================================================
1112 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1113 const GLchar* theName,
1114 const OpenGl_Vec2& theValue)
1116 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1119 // =======================================================================
1120 // function : SetUniform
1121 // purpose : Specifies the value of the floating-point uniform 2D vector
1122 // =======================================================================
1123 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1125 const OpenGl_Vec2& theValue)
1127 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1129 return Standard_False;
1132 theCtx->core20fwd->glUniform2fv (theLocation, 1, theValue);
1133 return Standard_True;
1136 // =======================================================================
1137 // function : SetUniform
1138 // purpose : Specifies the value of the floating-point uniform 3D vector
1139 // =======================================================================
1140 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1141 const GLchar* theName,
1142 const OpenGl_Vec3& theValue)
1144 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1147 // =======================================================================
1148 // function : SetUniform
1149 // purpose : Specifies the value of the floating-point uniform 3D vector
1150 // =======================================================================
1151 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1153 const OpenGl_Vec3& theValue)
1155 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1157 return Standard_False;
1160 theCtx->core20fwd->glUniform3fv (theLocation, 1, theValue);
1161 return Standard_True;
1164 // =======================================================================
1165 // function : SetUniform
1166 // purpose : Specifies the value of the floating-point uniform 4D vector
1167 // =======================================================================
1168 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1169 const GLchar* theName,
1170 const OpenGl_Vec4& theValue)
1172 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1175 // =======================================================================
1176 // function : SetUniform
1177 // purpose : Specifies the value of the floating-point uniform 4D vector
1178 // =======================================================================
1179 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1181 const OpenGl_Vec4& theValue)
1183 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1185 return Standard_False;
1188 theCtx->core20fwd->glUniform4fv (theLocation, 1, theValue);
1189 return Standard_True;
1192 // =======================================================================
1193 // function : SetUniform
1194 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1195 // =======================================================================
1196 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1197 const GLchar* theName,
1198 const OpenGl_Mat4& theValue,
1199 GLboolean theTranspose)
1201 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1204 // =======================================================================
1205 // function : SetUniform
1206 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1207 // =======================================================================
1208 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1210 const OpenGl_Mat4& theValue,
1211 GLboolean theTranspose)
1213 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1215 return Standard_False;
1218 theCtx->core20fwd->glUniformMatrix4fv (theLocation, 1, GL_FALSE, theTranspose ? theValue.Transposed() : theValue);
1219 return Standard_True;
1222 // =======================================================================
1223 // function : SetUniform
1224 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1225 // =======================================================================
1226 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1227 const GLchar* theName,
1228 const OpenGl_Matrix& theValue,
1229 GLboolean theTranspose)
1231 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1234 // =======================================================================
1235 // function : SetUniform
1236 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1237 // =======================================================================
1238 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1240 const OpenGl_Matrix& theValue,
1241 GLboolean theTranspose)
1243 return SetUniform (theCtx, theLocation, OpenGl_Mat4::Map (*theValue.mat), theTranspose);
1246 // =======================================================================
1247 // function : SetUniform
1248 // purpose : Specifies the value of the float uniform array
1249 // =======================================================================
1250 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1253 const Standard_ShortReal* theData)
1255 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1257 return Standard_False;
1260 theCtx->core20fwd->glUniform1fv (theLocation, theCount, theData);
1261 return Standard_True;
1264 // =======================================================================
1265 // function : SetUniform
1266 // purpose : Specifies the value of the float2 uniform array
1267 // =======================================================================
1268 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1271 const OpenGl_Vec2* theData)
1273 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1275 return Standard_False;
1278 theCtx->core20fwd->glUniform2fv (theLocation, theCount, theData[0].GetData());
1279 return Standard_True;
1282 // =======================================================================
1283 // function : SetUniform
1284 // purpose : Specifies the value of the float3 uniform array
1285 // =======================================================================
1286 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1289 const OpenGl_Vec3* theData)
1291 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1293 return Standard_False;
1296 theCtx->core20fwd->glUniform3fv (theLocation, theCount, theData[0].GetData());
1297 return Standard_True;
1300 // =======================================================================
1301 // function : SetUniform
1302 // purpose : Specifies the value of the float4 uniform array
1303 // =======================================================================
1304 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1307 const OpenGl_Vec4* theData)
1309 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1311 return Standard_False;
1314 theCtx->core20fwd->glUniform4fv (theLocation, theCount, theData[0].GetData());
1315 return Standard_True;
1318 // =======================================================================
1319 // function : SetUniform
1320 // purpose : Specifies the value of the integer uniform array
1321 // =======================================================================
1322 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1325 const Standard_Integer* theData)
1327 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1329 return Standard_False;
1332 theCtx->core20fwd->glUniform1iv (theLocation, theCount, theData);
1333 return Standard_True;
1336 // =======================================================================
1337 // function : SetUniform
1338 // purpose : Specifies the value of the int2 uniform array
1339 // =======================================================================
1340 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1343 const OpenGl_Vec2i* theData)
1345 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1347 return Standard_False;
1350 theCtx->core20fwd->glUniform2iv (theLocation, theCount, theData[0].GetData());
1351 return Standard_True;
1354 // =======================================================================
1355 // function : SetUniform
1356 // purpose : Specifies the value of the int3 uniform array
1357 // =======================================================================
1358 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1361 const OpenGl_Vec3i* theData)
1363 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1365 return Standard_False;
1368 theCtx->core20fwd->glUniform3iv (theLocation, theCount, theData[0].GetData());
1369 return Standard_True;
1372 // =======================================================================
1373 // function : SetUniform
1374 // purpose : Specifies the value of the int4 uniform array
1375 // =======================================================================
1376 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1379 const OpenGl_Vec4i* theData)
1381 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1383 return Standard_False;
1386 theCtx->core20fwd->glUniform4iv (theLocation, theCount, theData[0].GetData());
1387 return Standard_True;
1390 // =======================================================================
1391 // function : SetSampler
1392 // purpose : Specifies the value of the sampler uniform variable
1393 // =======================================================================
1394 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1395 const GLchar* theName,
1396 const Graphic3d_TextureUnit theTextureUnit)
1398 return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit);
1401 // =======================================================================
1402 // function : SetSampler
1403 // purpose : Specifies the value of the sampler uniform variable
1404 // =======================================================================
1405 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1407 const Graphic3d_TextureUnit theTextureUnit)
1409 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1411 return Standard_False;
1414 theCtx->core20fwd->glUniform1i (theLocation, theTextureUnit);
1415 return Standard_True;
1418 // =======================================================================
1419 // function : Create
1420 // purpose : Creates new empty shader program of specified type
1421 // =======================================================================
1422 Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx)
1424 if (myProgramID == NO_PROGRAM
1425 && theCtx->core20fwd != NULL)
1427 myProgramID = theCtx->core20fwd->glCreateProgram();
1430 return myProgramID != NO_PROGRAM;
1433 // =======================================================================
1434 // function : Release
1435 // purpose : Destroys shader program
1436 // =======================================================================
1437 void OpenGl_ShaderProgram::Release (OpenGl_Context* theCtx)
1439 if (myProgramID == NO_PROGRAM)
1444 Standard_ASSERT_RETURN (theCtx != NULL,
1445 "OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...",);
1447 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
1449 if (!anIter.Value().IsNull())
1451 anIter.ChangeValue()->Release (theCtx);
1452 anIter.ChangeValue().Nullify();
1456 if (theCtx->core20fwd != NULL
1457 && theCtx->IsValid())
1459 theCtx->core20fwd->glDeleteProgram (myProgramID);
1462 myProgramID = NO_PROGRAM;