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_Environment.hxx>
18 #include <OSD_Protection.hxx>
20 #include <Graphic3d_Buffer.hxx>
21 #include <Standard_Assert.hxx>
22 #include <Standard_Atomic.hxx>
23 #include <TCollection_ExtendedString.hxx>
25 #include <OpenGl_Context.hxx>
26 #include <OpenGl_ShaderProgram.hxx>
27 #include <OpenGl_ShaderManager.hxx>
28 #include <OpenGl_ArbTexBindless.hxx>
30 #include <OpenGl_GlCore32.hxx>
32 #include "../Shaders/Shaders_DeclarationsImpl_glsl.pxx"
33 #include "../Shaders/Shaders_Declarations_glsl.pxx"
36 #include <malloc.h> // for alloca()
39 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderProgram, OpenGl_NamedResource)
41 OpenGl_VariableSetterSelector OpenGl_ShaderProgram::mySetterSelector = OpenGl_VariableSetterSelector();
43 // Declare OCCT-specific OpenGL/GLSL shader variables
44 Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] =
46 "occModelWorldMatrix", // OpenGl_OCC_MODEL_WORLD_MATRIX
47 "occWorldViewMatrix", // OpenGl_OCC_WORLD_VIEW_MATRIX
48 "occProjectionMatrix", // OpenGl_OCC_PROJECTION_MATRIX
49 "occModelWorldMatrixInverse", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE
50 "occWorldViewMatrixInverse", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE
51 "occProjectionMatrixInverse", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE
52 "occModelWorldMatrixTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE
53 "occWorldViewMatrixTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE
54 "occProjectionMatrixTranspose", // OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE
55 "occModelWorldMatrixInverseTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE
56 "occWorldViewMatrixInverseTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE
57 "occProjectionMatrixInverseTranspose", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE
59 "occClipPlaneEquations", // OpenGl_OCC_CLIP_PLANE_EQUATIONS
60 "occClipPlaneChains", // OpenGl_OCC_CLIP_PLANE_CHAINS
61 "occClipPlaneCount", // OpenGl_OCC_CLIP_PLANE_COUNT
63 "occLightSourcesCount", // OpenGl_OCC_LIGHT_SOURCE_COUNT
64 "occLightSourcesTypes", // OpenGl_OCC_LIGHT_SOURCE_TYPES
65 "occLightSources", // OpenGl_OCC_LIGHT_SOURCE_PARAMS
66 "occLightAmbient", // OpenGl_OCC_LIGHT_AMBIENT
68 "occTextureEnable", // OpenGl_OCCT_TEXTURE_ENABLE
69 "occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE
70 "occFrontMaterial", // OpenGl_OCCT_FRONT_MATERIAL
71 "occBackMaterial", // OpenGl_OCCT_BACK_MATERIAL
72 "occAlphaCutoff", // OpenGl_OCCT_ALPHA_CUTOFF
73 "occColor", // OpenGl_OCCT_COLOR
75 "occOitOutput", // OpenGl_OCCT_OIT_OUTPUT
76 "occOitDepthFactor", // OpenGl_OCCT_OIT_DEPTH_FACTOR
78 "occTexTrsf2d", // OpenGl_OCCT_TEXTURE_TRSF2D
79 "occPointSize", // OpenGl_OCCT_POINT_SIZE
81 "occViewport", // OpenGl_OCCT_VIEWPORT
82 "occLineWidth", // OpenGl_OCCT_LINE_WIDTH
83 "occLineFeather", // OpenGl_OCCT_LINE_FEATHER
84 "occStipplePattern", // OpenGl_OCCT_LINE_STIPPLE_PATTERN
85 "occStippleFactor", // OpenGl_OCCT_LINE_STIPPLE_FACTOR
86 "occWireframeColor", // OpenGl_OCCT_WIREFRAME_COLOR
87 "occIsQuadMode", // OpenGl_OCCT_QUAD_MODE_STATE
89 "occOrthoScale", // OpenGl_OCCT_ORTHO_SCALE
90 "occSilhouetteThickness" // OpenGl_OCCT_SILHOUETTE_THICKNESS
95 //! Convert Graphic3d_TypeOfShaderObject enumeration into OpenGL enumeration.
96 static GLenum shaderTypeToGl (Graphic3d_TypeOfShaderObject theType)
100 case Graphic3d_TOS_VERTEX: return GL_VERTEX_SHADER;
101 case Graphic3d_TOS_FRAGMENT: return GL_FRAGMENT_SHADER;
102 case Graphic3d_TOS_GEOMETRY: return GL_GEOMETRY_SHADER;
103 case Graphic3d_TOS_TESS_CONTROL: return GL_TESS_CONTROL_SHADER;
104 case Graphic3d_TOS_TESS_EVALUATION: return GL_TESS_EVALUATION_SHADER;
105 case Graphic3d_TOS_COMPUTE: return GL_COMPUTE_SHADER;
111 // =======================================================================
112 // function : OpenGl_VariableSetterSelector
113 // purpose : Creates new variable setter selector
114 // =======================================================================
115 OpenGl_VariableSetterSelector::OpenGl_VariableSetterSelector()
117 // Note: Add new variable setters here
118 mySetterList = OpenGl_HashMapInitializer::CreateListOf<size_t, OpenGl_SetterInterface*>
119 (Graphic3d_UniformValueTypeID<int>::ID, new OpenGl_VariableSetter<int>())
120 (Graphic3d_UniformValueTypeID<float>::ID, new OpenGl_VariableSetter<float>())
121 (Graphic3d_UniformValueTypeID<OpenGl_Vec2>::ID, new OpenGl_VariableSetter<OpenGl_Vec2>())
122 (Graphic3d_UniformValueTypeID<OpenGl_Vec3>::ID, new OpenGl_VariableSetter<OpenGl_Vec3>())
123 (Graphic3d_UniformValueTypeID<OpenGl_Vec4>::ID, new OpenGl_VariableSetter<OpenGl_Vec4>())
124 (Graphic3d_UniformValueTypeID<OpenGl_Vec2i>::ID, new OpenGl_VariableSetter<OpenGl_Vec2i>())
125 (Graphic3d_UniformValueTypeID<OpenGl_Vec3i>::ID, new OpenGl_VariableSetter<OpenGl_Vec3i>())
126 (Graphic3d_UniformValueTypeID<OpenGl_Vec4i>::ID, new OpenGl_VariableSetter<OpenGl_Vec4i>());
129 // =======================================================================
130 // function : ~OpenGl_VariableSetterSelector
131 // purpose : Releases memory resources of variable setter selector
132 // =======================================================================
133 OpenGl_VariableSetterSelector::~OpenGl_VariableSetterSelector()
135 for (OpenGl_SetterList::Iterator anIt (mySetterList); anIt.More(); anIt.Next())
140 mySetterList.Clear();
143 // =======================================================================
145 // purpose : Sets generic variable to specified shader program
146 // =======================================================================
147 void OpenGl_VariableSetterSelector::Set (const Handle(OpenGl_Context)& theCtx,
148 const Handle(Graphic3d_ShaderVariable)& theVariable,
149 OpenGl_ShaderProgram* theProgram) const
151 Standard_ASSERT_RETURN (mySetterList.IsBound (theVariable->Value()->TypeID()),
152 "The type of user-defined uniform variable is not supported...", );
154 mySetterList.Find (theVariable->Value()->TypeID())->Set (theCtx, theVariable, theProgram);
157 // =======================================================================
158 // function : OpenGl_ShaderProgram
159 // purpose : Creates uninitialized shader program
160 // =======================================================================
161 OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy,
162 const TCollection_AsciiString& theId)
163 : OpenGl_NamedResource (!theProxy.IsNull() ? theProxy->GetId() : theId),
164 myProgramID (NO_PROGRAM),
168 myNbClipPlanesMax (0),
170 myHasAlphaTest (false),
171 myHasWeightOitOutput (false),
172 myHasTessShader (false)
174 memset (myCurrentState, 0, sizeof (myCurrentState));
177 // =======================================================================
178 // function : Initialize
179 // purpose : Initializes program object with the list of shader objects
180 // =======================================================================
181 Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& theCtx,
182 const Graphic3d_ShaderObjectList& theShaders)
184 myHasTessShader = false;
185 if (theCtx.IsNull() || !Create (theCtx))
187 return Standard_False;
190 TCollection_AsciiString aHeaderVer = !myProxy.IsNull() ? myProxy->Header() : TCollection_AsciiString();
192 for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders); anIter.More(); anIter.Next())
194 aShaderMask |= anIter.Value()->Type();
196 myHasTessShader = (aShaderMask & (Graphic3d_TOS_TESS_CONTROL | Graphic3d_TOS_TESS_EVALUATION)) != 0;
197 myNbFragOutputs = !myProxy.IsNull() ? myProxy->NbFragmentOutputs() : 1;
198 myHasAlphaTest = !myProxy.IsNull() && myProxy->HasAlphaTest();
199 myHasWeightOitOutput = !myProxy.IsNull() ? myProxy->HasWeightOitOutput() && myNbFragOutputs >= 2 : 1;
201 // detect the minimum GLSL version required for defined Shader Objects
202 #if defined(GL_ES_VERSION_2_0)
205 if (!theCtx->IsGlGreaterEqual (3, 2))
207 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
208 "Error! Tessellation shader requires OpenGL ES 3.2+");
211 else if (aHeaderVer.IsEmpty())
213 aHeaderVer = "#version 320 es";
216 else if ((aShaderMask & Graphic3d_TOS_GEOMETRY) != 0)
218 switch (theCtx->hasGeometryStage)
220 case OpenGl_FeatureNotAvailable:
222 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
223 "Error! Geometry shader requires OpenGL ES 3.2+ or GL_EXT_geometry_shader");
226 case OpenGl_FeatureInExtensions:
228 if (aHeaderVer.IsEmpty())
230 aHeaderVer = "#version 310 es";
234 case OpenGl_FeatureInCore:
236 if (aHeaderVer.IsEmpty())
238 aHeaderVer = "#version 320 es";
244 else if ((aShaderMask & Graphic3d_TOS_COMPUTE) != 0)
246 if (!theCtx->IsGlGreaterEqual (3, 1))
248 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
249 "Error! Compute shaders require OpenGL ES 3.1+");
252 else if (aHeaderVer.IsEmpty())
254 aHeaderVer = "#version 310 es";
258 if ((aShaderMask & Graphic3d_TOS_COMPUTE) != 0)
260 if (!theCtx->IsGlGreaterEqual (4, 3))
262 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
263 "Error! Compute shaders require OpenGL 4.3+");
266 else if (aHeaderVer.IsEmpty())
268 aHeaderVer = "#version 430";
271 else if (myHasTessShader)
273 if (!theCtx->IsGlGreaterEqual (4, 0))
275 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
276 "Error! Tessellation shaders require OpenGL 4.0+");
279 else if (aHeaderVer.IsEmpty())
281 aHeaderVer = "#version 400";
284 else if ((aShaderMask & Graphic3d_TOS_GEOMETRY) != 0)
286 if (!theCtx->IsGlGreaterEqual (3, 2))
288 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
289 "Error! Geometry shaders require OpenGL 3.2+");
292 else if (aHeaderVer.IsEmpty())
294 aHeaderVer = "#version 150";
299 for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders); anIter.More(); anIter.Next())
301 if (!anIter.Value()->IsDone())
303 const TCollection_ExtendedString aMsg = "Error! Failed to get shader source";
304 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
305 return Standard_False;
308 const GLenum aShaderType = shaderTypeToGl (anIter.Value()->Type());
309 if (aShaderType == 0)
311 return Standard_False;
314 Handle(OpenGl_ShaderObject) aShader = new OpenGl_ShaderObject (aShaderType);
315 if (!aShader->Create (theCtx))
317 aShader->Release (theCtx.operator->());
318 return Standard_False;
321 TCollection_AsciiString anExtensions = "// Enable extensions used in OCCT GLSL programs\n";
322 if (myNbFragOutputs > 1)
324 if (theCtx->hasDrawBuffers)
326 anExtensions += "#define OCC_ENABLE_draw_buffers\n";
327 if (myHasWeightOitOutput)
329 anExtensions += "#define OCC_WRITE_WEIGHT_OIT_COVERAGE\n";
334 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
335 "Error! Multiple draw buffers required by the program, but aren't supported by OpenGL");
336 return Standard_False;
339 if (theCtx->hasDrawBuffers == OpenGl_FeatureInExtensions)
341 if (theCtx->arbDrawBuffers)
343 anExtensions += "#extension GL_ARB_draw_buffers : enable\n";
345 else if (theCtx->extDrawBuffers)
347 anExtensions += "#extension GL_EXT_draw_buffers : enable\n";
353 anExtensions += "#define OCC_ALPHA_TEST\n";
356 if (theCtx->hasSampleVariables == OpenGl_FeatureInExtensions)
358 #if defined(GL_ES_VERSION_2_0)
359 if (theCtx->oesSampleVariables)
361 anExtensions += "#extension GL_OES_sample_variables : enable\n";
364 if (theCtx->arbSampleShading)
366 anExtensions += "#extension GL_ARB_sample_shading : enable\n";
370 #if defined(GL_ES_VERSION_2_0)
371 if (theCtx->hasGeometryStage == OpenGl_FeatureInExtensions)
373 anExtensions += "#extension GL_EXT_geometry_shader : enable\n"
374 "#extension GL_EXT_shader_io_blocks : enable\n";
378 TCollection_AsciiString aPrecisionHeader;
379 if (anIter.Value()->Type() == Graphic3d_TOS_FRAGMENT)
381 #if defined(GL_ES_VERSION_2_0)
382 aPrecisionHeader = theCtx->hasHighp
383 ? "precision highp float;\n"
384 "precision highp int;\n"
385 : "precision mediump float;\n"
386 "precision mediump int;\n";
390 TCollection_AsciiString aHeaderType;
391 switch (anIter.Value()->Type())
393 case Graphic3d_TOS_COMPUTE: { aHeaderType = "#define COMPUTE_SHADER\n"; break; }
394 case Graphic3d_TOS_VERTEX: { aHeaderType = "#define VERTEX_SHADER\n"; break; }
395 case Graphic3d_TOS_TESS_CONTROL: { aHeaderType = "#define TESS_CONTROL_SHADER\n"; break; }
396 case Graphic3d_TOS_TESS_EVALUATION: { aHeaderType = "#define TESS_EVALUATION_SHADER\n"; break; }
397 case Graphic3d_TOS_GEOMETRY: { aHeaderType = "#define GEOMETRY_SHADER\n"; break; }
398 case Graphic3d_TOS_FRAGMENT: { aHeaderType = "#define FRAGMENT_SHADER\n"; break; }
401 TCollection_AsciiString aHeaderConstants;
402 myNbLightsMax = !myProxy.IsNull() ? myProxy->NbLightsMax() : 0;
403 myNbClipPlanesMax = !myProxy.IsNull() ? myProxy->NbClipPlanesMax() : 0;
404 aHeaderConstants += TCollection_AsciiString("#define THE_MAX_LIGHTS ") + myNbLightsMax + "\n";
405 aHeaderConstants += TCollection_AsciiString("#define THE_MAX_CLIP_PLANES ") + myNbClipPlanesMax + "\n";
406 aHeaderConstants += TCollection_AsciiString("#define THE_NB_FRAG_OUTPUTS ") + myNbFragOutputs + "\n";
407 if (!myProxy.IsNull()
408 && myProxy->HasDefaultSampler())
410 aHeaderConstants += "#define THE_HAS_DEFAULT_SAMPLER\n";
413 const TCollection_AsciiString aSource = aHeaderVer // #version - header defining GLSL version, should be first
414 + (!aHeaderVer.IsEmpty() ? "\n" : "")
415 + anExtensions // #extension - list of enabled extensions, should be second
416 + aPrecisionHeader // precision - default precision qualifiers, should be before any code
417 + aHeaderType // auxiliary macros defining a shader stage (type)
419 + Shaders_Declarations_glsl // common declarations (global constants and Vertex Shader inputs)
420 + Shaders_DeclarationsImpl_glsl
421 + anIter.Value()->Source(); // the source code itself (defining main() function)
422 if (!aShader->LoadAndCompile (theCtx, myResourceId, aSource))
424 aShader->Release (theCtx.operator->());
425 return Standard_False;
428 if (theCtx->caps->glslDumpLevel)
430 TCollection_AsciiString anOutputSource = aSource;
431 if (theCtx->caps->glslDumpLevel == OpenGl_ShaderProgramDumpLevel_Short)
433 anOutputSource = aHeaderVer
434 + (!aHeaderVer.IsEmpty() ? "\n" : "")
439 + anIter.Value()->Source();
441 aShader->DumpSourceCode (theCtx, myResourceId, anOutputSource);
444 if (!AttachShader (theCtx, aShader))
446 aShader->Release (theCtx.operator->());
447 return Standard_False;
451 // bind locations for pre-defined Vertex Attributes
452 SetAttributeName (theCtx, Graphic3d_TOA_POS, "occVertex");
453 SetAttributeName (theCtx, Graphic3d_TOA_NORM, "occNormal");
454 SetAttributeName (theCtx, Graphic3d_TOA_UV, "occTexCoord");
455 SetAttributeName (theCtx, Graphic3d_TOA_COLOR, "occVertColor");
457 // bind custom Vertex Attributes
458 if (!myProxy.IsNull())
460 for (Graphic3d_ShaderAttributeList::Iterator anAttribIter (myProxy->VertexAttributes());
461 anAttribIter.More(); anAttribIter.Next())
463 SetAttributeName (theCtx, anAttribIter.Value()->Location(), anAttribIter.Value()->Name().ToCString());
469 return Standard_False;
472 // set uniform defaults
473 const Handle(OpenGl_ShaderProgram)& anOldProgram = theCtx->ActiveProgram();
474 theCtx->core20fwd->glUseProgram (myProgramID);
475 if (const OpenGl_ShaderUniformLocation aLocTexEnable = GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE))
477 SetUniform (theCtx, aLocTexEnable, 0); // Off
479 if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occActiveSampler"))
481 SetUniform (theCtx, aLocSampler, GLint(Graphic3d_TextureUnit_0));
483 if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occSamplerBaseColor"))
485 SetUniform (theCtx, aLocSampler, GLint(Graphic3d_TextureUnit_BaseColor));
487 if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occSamplerPointSprite"))
489 SetUniform (theCtx, aLocSampler, GLint(theCtx->SpriteTextureUnit()));
492 const TCollection_AsciiString aSamplerNamePrefix ("occSampler");
493 const Standard_Integer aNbUnitsMax = Max (theCtx->MaxCombinedTextureUnits(), Graphic3d_TextureUnit_NB);
494 for (GLint aUnitIter = 0; aUnitIter < aNbUnitsMax; ++aUnitIter)
496 const TCollection_AsciiString aName = aSamplerNamePrefix + aUnitIter;
497 if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, aName.ToCString()))
499 SetUniform (theCtx, aLocSampler, aUnitIter);
503 theCtx->core20fwd->glUseProgram (!anOldProgram.IsNull() ? anOldProgram->ProgramId() : OpenGl_ShaderProgram::NO_PROGRAM);
504 return Standard_True;
507 // =======================================================================
508 // function : ~OpenGl_ShaderProgram
509 // purpose : Releases resources of shader program
510 // =======================================================================
511 OpenGl_ShaderProgram::~OpenGl_ShaderProgram()
516 // =======================================================================
517 // function : AttachShader
518 // purpose : Attaches shader object to the program object
519 // =======================================================================
520 Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context)& theCtx,
521 const Handle(OpenGl_ShaderObject)& theShader)
523 if (myProgramID == NO_PROGRAM || theShader.IsNull())
525 return Standard_False;
528 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
530 if (theShader == anIter.Value())
532 return Standard_False;
536 myShaderObjects.Append (theShader);
537 theCtx->core20fwd->glAttachShader (myProgramID, theShader->myShaderID);
538 return Standard_True;
541 // =======================================================================
542 // function : DetachShader
543 // purpose : Detaches shader object to the program object
544 // =======================================================================
545 Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context)& theCtx,
546 const Handle(OpenGl_ShaderObject)& theShader)
548 if (myProgramID == NO_PROGRAM
549 || theShader.IsNull())
551 return Standard_False;
554 OpenGl_ShaderList::Iterator anIter (myShaderObjects);
555 while (anIter.More())
557 if (theShader == anIter.Value())
559 myShaderObjects.Remove (anIter);
568 return Standard_False;
571 theCtx->core20fwd->glDetachShader (myProgramID, theShader->myShaderID);
572 return Standard_True;
575 // =======================================================================
577 // purpose : Links the program object
578 // =======================================================================
579 Standard_Boolean OpenGl_ShaderProgram::link (const Handle(OpenGl_Context)& theCtx)
581 if (myProgramID == NO_PROGRAM)
583 return Standard_False;
586 GLint aStatus = GL_FALSE;
587 theCtx->core20fwd->glLinkProgram (myProgramID);
588 theCtx->core20fwd->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
589 if (aStatus == GL_FALSE)
591 return Standard_False;
594 memset (myCurrentState, 0, sizeof (myCurrentState));
595 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
597 myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]);
599 return Standard_True;
602 // =======================================================================
605 // =======================================================================
606 Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx,
611 return link (theCtx);
616 TCollection_AsciiString aLog;
617 FetchInfoLog (theCtx, aLog);
620 aLog = "Linker log is empty.";
622 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
623 TCollection_AsciiString ("Failed to link program object [") + myResourceId + "]! Linker log:\n" + aLog);
626 else if (theCtx->caps->glslWarnings)
628 TCollection_AsciiString aLog;
629 FetchInfoLog (theCtx, aLog);
631 && !aLog.IsEqual ("No errors.\n"))
633 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_LOW,
634 TCollection_AsciiString ("GLSL linker log [") + myResourceId +"]:\n" + aLog);
640 // =======================================================================
641 // function : FetchInfoLog
642 // purpose : Fetches information log of the last link operation
643 // =======================================================================
644 Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
645 TCollection_AsciiString& theOutput)
647 if (myProgramID == NO_PROGRAM)
649 return Standard_False;
653 theCtx->core20fwd->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
656 GLchar* aLog = (GLchar*) alloca (aLength);
657 memset (aLog, 0, aLength);
658 theCtx->core20fwd->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
661 return Standard_True;
664 // =======================================================================
665 // function : ApplyVariables
666 // purpose : Fetches uniform variables from proxy shader program
667 // =======================================================================
668 Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Context)& theCtx)
670 if (myProxy.IsNull() || myProxy->Variables().IsEmpty())
672 return Standard_False;
675 for (Graphic3d_ShaderVariableList::Iterator anIter (myProxy->Variables()); anIter.More(); anIter.Next())
677 mySetterSelector.Set (theCtx, anIter.Value(), this);
680 myProxy->ClearVariables();
681 return Standard_True;
684 // =======================================================================
685 // function : GetUniformLocation
686 // purpose : Returns location (index) of the specific uniform variable
687 // =======================================================================
688 OpenGl_ShaderUniformLocation OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& theCtx,
689 const GLchar* theName) const
691 return OpenGl_ShaderUniformLocation (myProgramID != NO_PROGRAM
692 ? theCtx->core20fwd->glGetUniformLocation (myProgramID, theName)
696 // =======================================================================
697 // function : GetAttributeLocation
698 // purpose : Returns location (index) of the generic vertex attribute
699 // =======================================================================
700 GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)& theCtx,
701 const GLchar* theName) const
703 return myProgramID != NO_PROGRAM
704 ? theCtx->core20fwd->glGetAttribLocation (myProgramID, theName)
708 // =======================================================================
709 // function : GetUniform
710 // purpose : Returns the value of the integer uniform variable
711 // =======================================================================
712 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
713 const GLchar* theName,
714 OpenGl_Vec4i& theValue) const
716 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
719 // =======================================================================
720 // function : GetUniform
721 // purpose : Returns the value of the integer uniform variable
722 // =======================================================================
723 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
725 OpenGl_Vec4i& theValue) const
727 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
729 return Standard_False;
732 theCtx->core20fwd->glGetUniformiv (myProgramID, theLocation, theValue);
733 return Standard_True;
736 // =======================================================================
737 // function : GetUniform
738 // purpose : Returns the value of the floating-point uniform variable
739 // =======================================================================
740 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
741 const GLchar* theName,
742 OpenGl_Vec4& theValue) const
744 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
747 // =======================================================================
748 // function : GetUniform
749 // purpose : Returns the value of the floating-point uniform variable
750 // =======================================================================
751 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
753 OpenGl_Vec4& theValue) const
755 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
757 return Standard_False;
760 theCtx->core20fwd->glGetUniformfv (myProgramID, theLocation, theValue);
761 return Standard_True;
764 // =======================================================================
765 // function : GetAttribute
766 // purpose : Returns the integer vertex attribute
767 // =======================================================================
768 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
769 const GLchar* theName,
770 OpenGl_Vec4i& theValue) const
772 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
775 // =======================================================================
776 // function : GetAttribute
777 // purpose : Returns the integer vertex attribute
778 // =======================================================================
779 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
781 OpenGl_Vec4i& theValue) const
783 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
785 return Standard_False;
788 theCtx->core20fwd->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
789 return Standard_True;
792 // =======================================================================
793 // function : GetAttribute
794 // purpose : Returns the floating-point vertex attribute
795 // =======================================================================
796 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
797 const GLchar* theName,
798 OpenGl_Vec4& theValue) const
800 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
803 // =======================================================================
804 // function : GetAttribute
805 // purpose : Returns the floating-point vertex attribute
806 // =======================================================================
807 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
809 OpenGl_Vec4& theValue) const
811 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
813 return Standard_False;
816 theCtx->core20fwd->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
817 return Standard_True;
820 // =======================================================================
821 // function : SetAttributeName
823 // =======================================================================
824 Standard_Boolean OpenGl_ShaderProgram::SetAttributeName (const Handle(OpenGl_Context)& theCtx,
826 const GLchar* theName)
828 theCtx->core20fwd->glBindAttribLocation (myProgramID, theIndex, theName);
829 return Standard_True;
832 // =======================================================================
833 // function : SetAttribute
835 // =======================================================================
836 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
837 const GLchar* theName,
840 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
843 // =======================================================================
844 // function : SetAttribute
846 // =======================================================================
847 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
851 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
853 return Standard_False;
856 theCtx->core20fwd->glVertexAttrib1f (theIndex, theValue);
857 return Standard_True;
860 // =======================================================================
861 // function : SetAttribute
863 // =======================================================================
864 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
865 const GLchar* theName,
866 const OpenGl_Vec2& theValue)
868 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
871 // =======================================================================
872 // function : SetAttribute
874 // =======================================================================
875 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
877 const OpenGl_Vec2& theValue)
879 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
881 return Standard_False;
884 theCtx->core20fwd->glVertexAttrib2fv (theIndex, theValue);
885 return Standard_True;
888 // =======================================================================
889 // function : SetAttribute
891 // =======================================================================
892 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
893 const GLchar* theName,
894 const OpenGl_Vec3& theValue)
896 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
899 // =======================================================================
900 // function : SetAttribute
902 // =======================================================================
903 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
905 const OpenGl_Vec3& theValue)
907 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
909 return Standard_False;
912 theCtx->core20fwd->glVertexAttrib3fv (theIndex, theValue);
913 return Standard_True;
916 // =======================================================================
917 // function : SetAttribute
919 // =======================================================================
920 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
921 const GLchar* theName,
922 const OpenGl_Vec4& theValue)
924 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
927 // =======================================================================
928 // function : SetAttribute
930 // =======================================================================
931 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
933 const OpenGl_Vec4& theValue)
935 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
937 return Standard_False;
940 theCtx->core20fwd->glVertexAttrib4fv (theIndex, theValue);
941 return Standard_True;
944 // =======================================================================
945 // function : SetUniform
946 // purpose : Specifies the value of the integer uniform variable
947 // =======================================================================
948 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
949 const GLchar* theName,
952 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
955 // =======================================================================
956 // function : SetUniform
957 // purpose : Specifies the value of the integer uniform variable
958 // =======================================================================
959 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
963 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
965 return Standard_False;
968 theCtx->core20fwd->glUniform1i (theLocation, theValue);
969 return Standard_True;
972 // =======================================================================
973 // function : SetUniform
975 // =======================================================================
976 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
977 const GLchar* theName,
978 const OpenGl_Vec2u& theValue)
980 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
983 // =======================================================================
984 // function : SetUniform
986 // =======================================================================
987 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
989 const OpenGl_Vec2u& theValue)
991 if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
993 return Standard_False;
996 #if !defined(GL_ES_VERSION_2_0)
997 theCtx->core32->glUniform2uiv (theLocation, 1, theValue.GetData());
998 return Standard_True;
1001 return Standard_False;
1005 // =======================================================================
1006 // function : SetUniform
1008 // =======================================================================
1009 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1010 const GLchar* theName,
1011 const GLsizei theCount,
1012 const OpenGl_Vec2u* theValue)
1014 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theCount, theValue);
1017 // =======================================================================
1018 // function : SetUniform
1020 // =======================================================================
1021 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1023 const GLsizei theCount,
1024 const OpenGl_Vec2u* theValue)
1026 if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1028 return Standard_False;
1031 #if !defined(GL_ES_VERSION_2_0)
1032 theCtx->core32->glUniform2uiv (theLocation, theCount, theValue->GetData());
1033 return Standard_True;
1037 return Standard_False;
1041 // =======================================================================
1042 // function : SetUniform
1043 // purpose : Specifies the value of the floating-point uniform variable
1044 // =======================================================================
1045 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1046 const GLchar* theName,
1049 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1052 // =======================================================================
1053 // function : SetUniform
1054 // purpose : Specifies the value of the floating-point uniform variable
1055 // =======================================================================
1056 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1060 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1062 return Standard_False;
1065 theCtx->core20fwd->glUniform1f (theLocation, theValue);
1066 return Standard_True;
1069 // =======================================================================
1070 // function : SetUniform
1071 // purpose : Specifies the value of the integer uniform 2D vector
1072 // =======================================================================
1073 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1074 const GLchar* theName,
1075 const OpenGl_Vec2i& theValue)
1077 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1080 // =======================================================================
1081 // function : SetUniform
1082 // purpose : Specifies the value of the integer uniform 2D vector
1083 // =======================================================================
1084 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1086 const OpenGl_Vec2i& theValue)
1088 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1090 return Standard_False;
1093 theCtx->core20fwd->glUniform2iv (theLocation, 1, theValue);
1094 return Standard_True;
1097 // =======================================================================
1098 // function : SetUniform
1099 // purpose : Specifies the value of the integer uniform 3D vector
1100 // =======================================================================
1101 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1102 const GLchar* theName,
1103 const OpenGl_Vec3i& theValue)
1105 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1108 // =======================================================================
1109 // function : SetUniform
1110 // purpose : Specifies the value of the integer uniform 3D vector
1111 // =======================================================================
1112 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1114 const OpenGl_Vec3i& theValue)
1116 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1118 return Standard_False;
1121 theCtx->core20fwd->glUniform3iv (theLocation, 1, theValue);
1122 return Standard_True;
1125 // =======================================================================
1126 // function : SetUniform
1127 // purpose : Specifies the value of the integer uniform 4D vector
1128 // =======================================================================
1129 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1130 const GLchar* theName,
1131 const OpenGl_Vec4i& theValue)
1133 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1136 // =======================================================================
1137 // function : SetUniform
1138 // purpose : Specifies the value of the integer uniform 4D vector
1139 // =======================================================================
1140 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1142 const OpenGl_Vec4i& theValue)
1144 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1146 return Standard_False;
1149 theCtx->core20fwd->glUniform4iv (theLocation, 1, theValue);
1150 return Standard_True;
1153 // =======================================================================
1154 // function : SetUniform
1155 // purpose : Specifies the value of the floating-point uniform 2D vector
1156 // =======================================================================
1157 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1158 const GLchar* theName,
1159 const OpenGl_Vec2& theValue)
1161 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1164 // =======================================================================
1165 // function : SetUniform
1166 // purpose : Specifies the value of the floating-point uniform 2D vector
1167 // =======================================================================
1168 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1170 const OpenGl_Vec2& theValue)
1172 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1174 return Standard_False;
1177 theCtx->core20fwd->glUniform2fv (theLocation, 1, theValue);
1178 return Standard_True;
1181 // =======================================================================
1182 // function : SetUniform
1183 // purpose : Specifies the value of the floating-point uniform 3D vector
1184 // =======================================================================
1185 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1186 const GLchar* theName,
1187 const OpenGl_Vec3& theValue)
1189 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1192 // =======================================================================
1193 // function : SetUniform
1194 // purpose : Specifies the value of the floating-point uniform 3D vector
1195 // =======================================================================
1196 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1198 const OpenGl_Vec3& theValue)
1200 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1202 return Standard_False;
1205 theCtx->core20fwd->glUniform3fv (theLocation, 1, theValue);
1206 return Standard_True;
1209 // =======================================================================
1210 // function : SetUniform
1211 // purpose : Specifies the value of the floating-point uniform 4D vector
1212 // =======================================================================
1213 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1214 const GLchar* theName,
1215 const OpenGl_Vec4& theValue)
1217 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1220 // =======================================================================
1221 // function : SetUniform
1222 // purpose : Specifies the value of the floating-point uniform 4D vector
1223 // =======================================================================
1224 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1226 const OpenGl_Vec4& theValue)
1228 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1230 return Standard_False;
1233 theCtx->core20fwd->glUniform4fv (theLocation, 1, theValue);
1234 return Standard_True;
1237 // =======================================================================
1238 // function : SetUniform
1239 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1240 // =======================================================================
1241 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1242 const GLchar* theName,
1243 const OpenGl_Mat4& theValue,
1244 GLboolean theTranspose)
1246 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1249 // =======================================================================
1250 // function : SetUniform
1251 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1252 // =======================================================================
1253 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1255 const OpenGl_Mat4& theValue,
1256 GLboolean theTranspose)
1258 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1260 return Standard_False;
1263 theCtx->core20fwd->glUniformMatrix4fv (theLocation, 1, GL_FALSE, theTranspose ? theValue.Transposed() : theValue);
1264 return Standard_True;
1267 // =======================================================================
1268 // function : SetUniform
1269 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1270 // =======================================================================
1271 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1272 const GLchar* theName,
1273 const OpenGl_Matrix& theValue,
1274 GLboolean theTranspose)
1276 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1279 // =======================================================================
1280 // function : SetUniform
1281 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1282 // =======================================================================
1283 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1285 const OpenGl_Matrix& theValue,
1286 GLboolean theTranspose)
1288 return SetUniform (theCtx, theLocation, OpenGl_Mat4::Map (*theValue.mat), theTranspose);
1291 // =======================================================================
1292 // function : SetUniform
1293 // purpose : Specifies the value of the float uniform array
1294 // =======================================================================
1295 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1298 const Standard_ShortReal* theData)
1300 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1302 return Standard_False;
1305 theCtx->core20fwd->glUniform1fv (theLocation, theCount, theData);
1306 return Standard_True;
1309 // =======================================================================
1310 // function : SetUniform
1311 // purpose : Specifies the value of the float2 uniform array
1312 // =======================================================================
1313 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1316 const OpenGl_Vec2* theData)
1318 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1320 return Standard_False;
1323 theCtx->core20fwd->glUniform2fv (theLocation, theCount, theData[0].GetData());
1324 return Standard_True;
1327 // =======================================================================
1328 // function : SetUniform
1329 // purpose : Specifies the value of the float3 uniform array
1330 // =======================================================================
1331 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1334 const OpenGl_Vec3* theData)
1336 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1338 return Standard_False;
1341 theCtx->core20fwd->glUniform3fv (theLocation, theCount, theData[0].GetData());
1342 return Standard_True;
1345 // =======================================================================
1346 // function : SetUniform
1347 // purpose : Specifies the value of the float4 uniform array
1348 // =======================================================================
1349 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1352 const OpenGl_Vec4* theData)
1354 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1356 return Standard_False;
1359 theCtx->core20fwd->glUniform4fv (theLocation, theCount, theData[0].GetData());
1360 return Standard_True;
1363 // =======================================================================
1364 // function : SetUniform
1365 // purpose : Specifies the value of the integer uniform array
1366 // =======================================================================
1367 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1370 const Standard_Integer* theData)
1372 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1374 return Standard_False;
1377 theCtx->core20fwd->glUniform1iv (theLocation, theCount, theData);
1378 return Standard_True;
1381 // =======================================================================
1382 // function : SetUniform
1383 // purpose : Specifies the value of the int2 uniform array
1384 // =======================================================================
1385 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1388 const OpenGl_Vec2i* theData)
1390 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1392 return Standard_False;
1395 theCtx->core20fwd->glUniform2iv (theLocation, theCount, theData[0].GetData());
1396 return Standard_True;
1399 // =======================================================================
1400 // function : SetUniform
1401 // purpose : Specifies the value of the int3 uniform array
1402 // =======================================================================
1403 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1406 const OpenGl_Vec3i* theData)
1408 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1410 return Standard_False;
1413 theCtx->core20fwd->glUniform3iv (theLocation, theCount, theData[0].GetData());
1414 return Standard_True;
1417 // =======================================================================
1418 // function : SetUniform
1419 // purpose : Specifies the value of the int4 uniform array
1420 // =======================================================================
1421 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1424 const OpenGl_Vec4i* theData)
1426 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1428 return Standard_False;
1431 theCtx->core20fwd->glUniform4iv (theLocation, theCount, theData[0].GetData());
1432 return Standard_True;
1435 // =======================================================================
1436 // function : SetSampler
1437 // purpose : Specifies the value of the sampler uniform variable
1438 // =======================================================================
1439 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1440 const GLchar* theName,
1441 const Graphic3d_TextureUnit theTextureUnit)
1443 return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit);
1446 // =======================================================================
1447 // function : SetSampler
1448 // purpose : Specifies the value of the sampler uniform variable
1449 // =======================================================================
1450 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1452 const Graphic3d_TextureUnit theTextureUnit)
1454 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1456 return Standard_False;
1459 theCtx->core20fwd->glUniform1i (theLocation, theTextureUnit);
1460 return Standard_True;
1463 // =======================================================================
1464 // function : Create
1465 // purpose : Creates new empty shader program of specified type
1466 // =======================================================================
1467 Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx)
1469 if (myProgramID == NO_PROGRAM
1470 && theCtx->core20fwd != NULL)
1472 myProgramID = theCtx->core20fwd->glCreateProgram();
1475 return myProgramID != NO_PROGRAM;
1478 // =======================================================================
1479 // function : Release
1480 // purpose : Destroys shader program
1481 // =======================================================================
1482 void OpenGl_ShaderProgram::Release (OpenGl_Context* theCtx)
1484 if (myProgramID == NO_PROGRAM)
1489 Standard_ASSERT_RETURN (theCtx != NULL,
1490 "OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...",);
1492 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
1494 if (!anIter.Value().IsNull())
1496 anIter.ChangeValue()->Release (theCtx);
1497 anIter.ChangeValue().Nullify();
1501 if (theCtx->core20fwd != NULL
1502 && theCtx->IsValid())
1504 theCtx->core20fwd->glDeleteProgram (myProgramID);
1507 myProgramID = NO_PROGRAM;
1510 // =======================================================================
1511 // function : UpdateDebugDump
1513 // =======================================================================
1514 Standard_Boolean OpenGl_ShaderProgram::UpdateDebugDump (const Handle(OpenGl_Context)& theCtx,
1515 const TCollection_AsciiString& theFolder,
1516 Standard_Boolean theToBeautify,
1517 Standard_Boolean theToReset)
1519 if (myProgramID == NO_PROGRAM)
1521 return Standard_False;
1524 TCollection_AsciiString aFolder = theFolder;
1525 if (aFolder.IsEmpty())
1527 OSD_Environment aShaderVar ("CSF_ShadersDirectoryDump");
1528 aFolder = aShaderVar.Value();
1529 if (aFolder.IsEmpty())
1535 bool hasUpdates = false;
1536 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
1538 if (!anIter.Value().IsNull())
1540 // desktop OpenGL (but not OpenGL ES) allows multiple shaders of the same stage to be attached,
1541 // but here we expect only single source per stage
1542 hasUpdates = anIter.ChangeValue()->updateDebugDump (theCtx, myResourceId, aFolder, theToBeautify, theToReset) || hasUpdates;
1547 return Link (theCtx);
1549 return Standard_False;