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 "occWireframeColor", // OpenGl_OCCT_WIREFRAME_COLOR
85 "occIsQuadMode", // OpenGl_OCCT_QUAD_MODE_STATE
90 //! Convert Graphic3d_TypeOfShaderObject enumeration into OpenGL enumeration.
91 static GLenum shaderTypeToGl (Graphic3d_TypeOfShaderObject theType)
95 case Graphic3d_TOS_VERTEX: return GL_VERTEX_SHADER;
96 case Graphic3d_TOS_FRAGMENT: return GL_FRAGMENT_SHADER;
97 case Graphic3d_TOS_GEOMETRY: return GL_GEOMETRY_SHADER;
98 case Graphic3d_TOS_TESS_CONTROL: return GL_TESS_CONTROL_SHADER;
99 case Graphic3d_TOS_TESS_EVALUATION: return GL_TESS_EVALUATION_SHADER;
100 case Graphic3d_TOS_COMPUTE: return GL_COMPUTE_SHADER;
106 // =======================================================================
107 // function : OpenGl_VariableSetterSelector
108 // purpose : Creates new variable setter selector
109 // =======================================================================
110 OpenGl_VariableSetterSelector::OpenGl_VariableSetterSelector()
112 // Note: Add new variable setters here
113 mySetterList = OpenGl_HashMapInitializer::CreateListOf<size_t, OpenGl_SetterInterface*>
114 (Graphic3d_UniformValueTypeID<int>::ID, new OpenGl_VariableSetter<int>())
115 (Graphic3d_UniformValueTypeID<float>::ID, new OpenGl_VariableSetter<float>())
116 (Graphic3d_UniformValueTypeID<OpenGl_Vec2>::ID, new OpenGl_VariableSetter<OpenGl_Vec2>())
117 (Graphic3d_UniformValueTypeID<OpenGl_Vec3>::ID, new OpenGl_VariableSetter<OpenGl_Vec3>())
118 (Graphic3d_UniformValueTypeID<OpenGl_Vec4>::ID, new OpenGl_VariableSetter<OpenGl_Vec4>())
119 (Graphic3d_UniformValueTypeID<OpenGl_Vec2i>::ID, new OpenGl_VariableSetter<OpenGl_Vec2i>())
120 (Graphic3d_UniformValueTypeID<OpenGl_Vec3i>::ID, new OpenGl_VariableSetter<OpenGl_Vec3i>())
121 (Graphic3d_UniformValueTypeID<OpenGl_Vec4i>::ID, new OpenGl_VariableSetter<OpenGl_Vec4i>());
124 // =======================================================================
125 // function : ~OpenGl_VariableSetterSelector
126 // purpose : Releases memory resources of variable setter selector
127 // =======================================================================
128 OpenGl_VariableSetterSelector::~OpenGl_VariableSetterSelector()
130 for (OpenGl_SetterList::Iterator anIt (mySetterList); anIt.More(); anIt.Next())
135 mySetterList.Clear();
138 // =======================================================================
140 // purpose : Sets generic variable to specified shader program
141 // =======================================================================
142 void OpenGl_VariableSetterSelector::Set (const Handle(OpenGl_Context)& theCtx,
143 const Handle(Graphic3d_ShaderVariable)& theVariable,
144 OpenGl_ShaderProgram* theProgram) const
146 Standard_ASSERT_RETURN (mySetterList.IsBound (theVariable->Value()->TypeID()),
147 "The type of user-defined uniform variable is not supported...", );
149 mySetterList.Find (theVariable->Value()->TypeID())->Set (theCtx, theVariable, theProgram);
152 // =======================================================================
153 // function : OpenGl_ShaderProgram
154 // purpose : Creates uninitialized shader program
155 // =======================================================================
156 OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy,
157 const TCollection_AsciiString& theId)
158 : OpenGl_NamedResource (!theProxy.IsNull() ? theProxy->GetId() : theId),
159 myProgramID (NO_PROGRAM),
163 myNbClipPlanesMax (0),
165 myHasAlphaTest (false),
166 myHasWeightOitOutput (false),
167 myHasTessShader (false)
169 memset (myCurrentState, 0, sizeof (myCurrentState));
172 // =======================================================================
173 // function : Initialize
174 // purpose : Initializes program object with the list of shader objects
175 // =======================================================================
176 Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& theCtx,
177 const Graphic3d_ShaderObjectList& theShaders)
179 myHasTessShader = false;
180 if (theCtx.IsNull() || !Create (theCtx))
182 return Standard_False;
185 TCollection_AsciiString aHeaderVer = !myProxy.IsNull() ? myProxy->Header() : TCollection_AsciiString();
187 for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders); anIter.More(); anIter.Next())
189 aShaderMask |= anIter.Value()->Type();
191 myHasTessShader = (aShaderMask & (Graphic3d_TOS_TESS_CONTROL | Graphic3d_TOS_TESS_EVALUATION)) != 0;
192 myNbFragOutputs = !myProxy.IsNull() ? myProxy->NbFragmentOutputs() : 1;
193 myHasAlphaTest = !myProxy.IsNull() && myProxy->HasAlphaTest();
194 myHasWeightOitOutput = !myProxy.IsNull() ? myProxy->HasWeightOitOutput() && myNbFragOutputs >= 2 : 1;
196 // detect the minimum GLSL version required for defined Shader Objects
197 #if defined(GL_ES_VERSION_2_0)
200 if (!theCtx->IsGlGreaterEqual (3, 2))
202 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
203 "Error! Tessellation shader requires OpenGL ES 3.2+");
206 else if (aHeaderVer.IsEmpty())
208 aHeaderVer = "#version 320 es";
211 else if ((aShaderMask & Graphic3d_TOS_GEOMETRY) != 0)
213 switch (theCtx->hasGeometryStage)
215 case OpenGl_FeatureNotAvailable:
217 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
218 "Error! Geometry shader requires OpenGL ES 3.2+ or GL_EXT_geometry_shader");
221 case OpenGl_FeatureInExtensions:
223 if (aHeaderVer.IsEmpty())
225 aHeaderVer = "#version 310 es";
229 case OpenGl_FeatureInCore:
231 if (aHeaderVer.IsEmpty())
233 aHeaderVer = "#version 320 es";
239 else if ((aShaderMask & Graphic3d_TOS_COMPUTE) != 0)
241 if (!theCtx->IsGlGreaterEqual (3, 1))
243 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
244 "Error! Compute shaders require OpenGL ES 3.1+");
247 else if (aHeaderVer.IsEmpty())
249 aHeaderVer = "#version 310 es";
253 if ((aShaderMask & Graphic3d_TOS_COMPUTE) != 0)
255 if (!theCtx->IsGlGreaterEqual (4, 3))
257 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
258 "Error! Compute shaders require OpenGL 4.3+");
261 else if (aHeaderVer.IsEmpty())
263 aHeaderVer = "#version 430";
266 else if (myHasTessShader)
268 if (!theCtx->IsGlGreaterEqual (4, 0))
270 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
271 "Error! Tessellation shaders require OpenGL 4.0+");
274 else if (aHeaderVer.IsEmpty())
276 aHeaderVer = "#version 400";
279 else if ((aShaderMask & Graphic3d_TOS_GEOMETRY) != 0)
281 if (!theCtx->IsGlGreaterEqual (3, 2))
283 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
284 "Error! Geometry shaders require OpenGL 3.2+");
287 else if (aHeaderVer.IsEmpty())
289 aHeaderVer = "#version 150";
294 for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders); anIter.More(); anIter.Next())
296 if (!anIter.Value()->IsDone())
298 const TCollection_ExtendedString aMsg = "Error! Failed to get shader source";
299 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
300 return Standard_False;
303 const GLenum aShaderType = shaderTypeToGl (anIter.Value()->Type());
304 if (aShaderType == 0)
306 return Standard_False;
309 Handle(OpenGl_ShaderObject) aShader = new OpenGl_ShaderObject (aShaderType);
310 if (!aShader->Create (theCtx))
312 aShader->Release (theCtx.operator->());
313 return Standard_False;
316 TCollection_AsciiString anExtensions = "// Enable extensions used in OCCT GLSL programs\n";
317 if (myNbFragOutputs > 1)
319 if (theCtx->hasDrawBuffers)
321 anExtensions += "#define OCC_ENABLE_draw_buffers\n";
322 if (myHasWeightOitOutput)
324 anExtensions += "#define OCC_WRITE_WEIGHT_OIT_COVERAGE\n";
329 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
330 "Error! Multiple draw buffers required by the program, but aren't supported by OpenGL");
331 return Standard_False;
334 if (theCtx->hasDrawBuffers == OpenGl_FeatureInExtensions)
336 if (theCtx->arbDrawBuffers)
338 anExtensions += "#extension GL_ARB_draw_buffers : enable\n";
340 else if (theCtx->extDrawBuffers)
342 anExtensions += "#extension GL_EXT_draw_buffers : enable\n";
348 anExtensions += "#define OCC_ALPHA_TEST\n";
351 if (theCtx->hasSampleVariables == OpenGl_FeatureInExtensions)
353 #if defined(GL_ES_VERSION_2_0)
354 if (theCtx->oesSampleVariables)
356 anExtensions += "#extension GL_OES_sample_variables : enable\n";
359 if (theCtx->arbSampleShading)
361 anExtensions += "#extension GL_ARB_sample_shading : enable\n";
365 #if defined(GL_ES_VERSION_2_0)
366 if (theCtx->hasGeometryStage == OpenGl_FeatureInExtensions)
368 anExtensions += "#extension GL_EXT_geometry_shader : enable\n"
369 "#extension GL_EXT_shader_io_blocks : enable\n";
373 TCollection_AsciiString aPrecisionHeader;
374 if (anIter.Value()->Type() == Graphic3d_TOS_FRAGMENT)
376 #if defined(GL_ES_VERSION_2_0)
377 aPrecisionHeader = theCtx->hasHighp
378 ? "precision highp float;\n"
379 "precision highp int;\n"
380 : "precision mediump float;\n"
381 "precision mediump int;\n";
385 TCollection_AsciiString aHeaderType;
386 switch (anIter.Value()->Type())
388 case Graphic3d_TOS_COMPUTE: { aHeaderType = "#define COMPUTE_SHADER\n"; break; }
389 case Graphic3d_TOS_VERTEX: { aHeaderType = "#define VERTEX_SHADER\n"; break; }
390 case Graphic3d_TOS_TESS_CONTROL: { aHeaderType = "#define TESS_CONTROL_SHADER\n"; break; }
391 case Graphic3d_TOS_TESS_EVALUATION: { aHeaderType = "#define TESS_EVALUATION_SHADER\n"; break; }
392 case Graphic3d_TOS_GEOMETRY: { aHeaderType = "#define GEOMETRY_SHADER\n"; break; }
393 case Graphic3d_TOS_FRAGMENT: { aHeaderType = "#define FRAGMENT_SHADER\n"; break; }
396 TCollection_AsciiString aHeaderConstants;
397 myNbLightsMax = !myProxy.IsNull() ? myProxy->NbLightsMax() : 0;
398 myNbClipPlanesMax = !myProxy.IsNull() ? myProxy->NbClipPlanesMax() : 0;
399 aHeaderConstants += TCollection_AsciiString("#define THE_MAX_LIGHTS ") + myNbLightsMax + "\n";
400 aHeaderConstants += TCollection_AsciiString("#define THE_MAX_CLIP_PLANES ") + myNbClipPlanesMax + "\n";
401 aHeaderConstants += TCollection_AsciiString("#define THE_NB_FRAG_OUTPUTS ") + myNbFragOutputs + "\n";
403 const TCollection_AsciiString aSource = aHeaderVer // #version - header defining GLSL version, should be first
404 + (!aHeaderVer.IsEmpty() ? "\n" : "")
405 + anExtensions // #extension - list of enabled extensions, should be second
406 + aPrecisionHeader // precision - default precision qualifiers, should be before any code
407 + aHeaderType // auxiliary macros defining a shader stage (type)
409 + Shaders_Declarations_glsl // common declarations (global constants and Vertex Shader inputs)
410 + Shaders_DeclarationsImpl_glsl
411 + anIter.Value()->Source(); // the source code itself (defining main() function)
412 if (!aShader->LoadAndCompile (theCtx, aSource))
414 aShader->Release (theCtx.operator->());
415 return Standard_False;
418 if (theCtx->caps->glslDumpLevel)
420 TCollection_AsciiString aShaderTypeMsg;
421 switch (anIter.Value()->Type())
423 case Graphic3d_TOS_COMPUTE: { aShaderTypeMsg = "Compute shader source code:\n"; break; }
424 case Graphic3d_TOS_VERTEX: { aShaderTypeMsg = "Vertex shader source code:\n"; break; }
425 case Graphic3d_TOS_TESS_CONTROL: { aShaderTypeMsg = "Tesselation control shader source code:\n"; break; }
426 case Graphic3d_TOS_TESS_EVALUATION: { aShaderTypeMsg = "Tesselation evaluation shader source code:\n"; break; }
427 case Graphic3d_TOS_GEOMETRY: { aShaderTypeMsg = "Geometry shader source code:\n"; break; }
428 case Graphic3d_TOS_FRAGMENT: { aShaderTypeMsg = "Fragment shader source code:\n"; break; }
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 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 0, GL_DEBUG_SEVERITY_MEDIUM,
442 TCollection_ExtendedString (aShaderTypeMsg + anOutputSource));
445 if (!AttachShader (theCtx, aShader))
447 aShader->Release (theCtx.operator->());
448 return Standard_False;
452 // bind locations for pre-defined Vertex Attributes
453 SetAttributeName (theCtx, Graphic3d_TOA_POS, "occVertex");
454 SetAttributeName (theCtx, Graphic3d_TOA_NORM, "occNormal");
455 SetAttributeName (theCtx, Graphic3d_TOA_UV, "occTexCoord");
456 SetAttributeName (theCtx, Graphic3d_TOA_COLOR, "occVertColor");
458 // bind custom Vertex Attributes
459 if (!myProxy.IsNull())
461 for (Graphic3d_ShaderAttributeList::Iterator anAttribIter (myProxy->VertexAttributes());
462 anAttribIter.More(); anAttribIter.Next())
464 SetAttributeName (theCtx, anAttribIter.Value()->Location(), anAttribIter.Value()->Name().ToCString());
470 return Standard_False;
473 // set uniform defaults
474 const Handle(OpenGl_ShaderProgram)& anOldProgram = theCtx->ActiveProgram();
475 theCtx->core20fwd->glUseProgram (myProgramID);
476 if (const OpenGl_ShaderUniformLocation aLocTexEnable = GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE))
478 SetUniform (theCtx, aLocTexEnable, 0); // Off
480 if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occActiveSampler"))
482 SetUniform (theCtx, aLocSampler, GLint(Graphic3d_TextureUnit_0));
485 const TCollection_AsciiString aSamplerNamePrefix ("occSampler");
486 const Standard_Integer aNbUnitsMax = Max (theCtx->MaxCombinedTextureUnits(), Graphic3d_TextureUnit_NB);
487 for (GLint aUnitIter = 0; aUnitIter < aNbUnitsMax; ++aUnitIter)
489 const TCollection_AsciiString aName = aSamplerNamePrefix + aUnitIter;
490 if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, aName.ToCString()))
492 SetUniform (theCtx, aLocSampler, aUnitIter);
496 theCtx->core20fwd->glUseProgram (!anOldProgram.IsNull() ? anOldProgram->ProgramId() : OpenGl_ShaderProgram::NO_PROGRAM);
497 return Standard_True;
500 // =======================================================================
501 // function : ~OpenGl_ShaderProgram
502 // purpose : Releases resources of shader program
503 // =======================================================================
504 OpenGl_ShaderProgram::~OpenGl_ShaderProgram()
509 // =======================================================================
510 // function : AttachShader
511 // purpose : Attaches shader object to the program object
512 // =======================================================================
513 Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context)& theCtx,
514 const Handle(OpenGl_ShaderObject)& theShader)
516 if (myProgramID == NO_PROGRAM || theShader.IsNull())
518 return Standard_False;
521 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
523 if (theShader == anIter.Value())
525 return Standard_False;
529 myShaderObjects.Append (theShader);
530 theCtx->core20fwd->glAttachShader (myProgramID, theShader->myShaderID);
531 return Standard_True;
534 // =======================================================================
535 // function : DetachShader
536 // purpose : Detaches shader object to the program object
537 // =======================================================================
538 Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context)& theCtx,
539 const Handle(OpenGl_ShaderObject)& theShader)
541 if (myProgramID == NO_PROGRAM
542 || theShader.IsNull())
544 return Standard_False;
547 OpenGl_ShaderList::Iterator anIter (myShaderObjects);
548 while (anIter.More())
550 if (theShader == anIter.Value())
552 myShaderObjects.Remove (anIter);
561 return Standard_False;
564 theCtx->core20fwd->glDetachShader (myProgramID, theShader->myShaderID);
565 return Standard_True;
568 // =======================================================================
570 // purpose : Links the program object
571 // =======================================================================
572 Standard_Boolean OpenGl_ShaderProgram::link (const Handle(OpenGl_Context)& theCtx)
574 if (myProgramID == NO_PROGRAM)
576 return Standard_False;
579 GLint aStatus = GL_FALSE;
580 theCtx->core20fwd->glLinkProgram (myProgramID);
581 theCtx->core20fwd->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
582 if (aStatus == GL_FALSE)
584 return Standard_False;
587 memset (myCurrentState, 0, sizeof (myCurrentState));
588 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
590 myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]);
592 return Standard_True;
595 // =======================================================================
598 // =======================================================================
599 Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx,
604 return link (theCtx);
609 TCollection_AsciiString aLog;
610 FetchInfoLog (theCtx, aLog);
613 aLog = "Linker log is empty.";
615 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
616 TCollection_AsciiString ("Failed to link program object! Linker log:\n") + aLog);
619 else if (theCtx->caps->glslWarnings)
621 TCollection_AsciiString aLog;
622 FetchInfoLog (theCtx, aLog);
624 && !aLog.IsEqual ("No errors.\n"))
626 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_LOW,
627 TCollection_AsciiString ("GLSL linker log:\n") + aLog);
633 // =======================================================================
634 // function : FetchInfoLog
635 // purpose : Fetches information log of the last link operation
636 // =======================================================================
637 Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
638 TCollection_AsciiString& theOutput)
640 if (myProgramID == NO_PROGRAM)
642 return Standard_False;
646 theCtx->core20fwd->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
649 GLchar* aLog = (GLchar*) alloca (aLength);
650 memset (aLog, 0, aLength);
651 theCtx->core20fwd->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
654 return Standard_True;
657 // =======================================================================
658 // function : ApplyVariables
659 // purpose : Fetches uniform variables from proxy shader program
660 // =======================================================================
661 Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Context)& theCtx)
663 if (myProxy.IsNull() || myProxy->Variables().IsEmpty())
665 return Standard_False;
668 for (Graphic3d_ShaderVariableList::Iterator anIter (myProxy->Variables()); anIter.More(); anIter.Next())
670 mySetterSelector.Set (theCtx, anIter.Value(), this);
673 myProxy->ClearVariables();
674 return Standard_True;
677 // =======================================================================
678 // function : GetUniformLocation
679 // purpose : Returns location (index) of the specific uniform variable
680 // =======================================================================
681 OpenGl_ShaderUniformLocation OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& theCtx,
682 const GLchar* theName) const
684 return OpenGl_ShaderUniformLocation (myProgramID != NO_PROGRAM
685 ? theCtx->core20fwd->glGetUniformLocation (myProgramID, theName)
689 // =======================================================================
690 // function : GetAttributeLocation
691 // purpose : Returns location (index) of the generic vertex attribute
692 // =======================================================================
693 GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)& theCtx,
694 const GLchar* theName) const
696 return myProgramID != NO_PROGRAM
697 ? theCtx->core20fwd->glGetAttribLocation (myProgramID, theName)
701 // =======================================================================
702 // function : GetUniform
703 // purpose : Returns the value of the integer uniform variable
704 // =======================================================================
705 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
706 const GLchar* theName,
707 OpenGl_Vec4i& theValue) const
709 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
712 // =======================================================================
713 // function : GetUniform
714 // purpose : Returns the value of the integer uniform variable
715 // =======================================================================
716 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
718 OpenGl_Vec4i& theValue) const
720 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
722 return Standard_False;
725 theCtx->core20fwd->glGetUniformiv (myProgramID, theLocation, theValue);
726 return Standard_True;
729 // =======================================================================
730 // function : GetUniform
731 // purpose : Returns the value of the floating-point uniform variable
732 // =======================================================================
733 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
734 const GLchar* theName,
735 OpenGl_Vec4& theValue) const
737 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
740 // =======================================================================
741 // function : GetUniform
742 // purpose : Returns the value of the floating-point uniform variable
743 // =======================================================================
744 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
746 OpenGl_Vec4& theValue) const
748 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
750 return Standard_False;
753 theCtx->core20fwd->glGetUniformfv (myProgramID, theLocation, theValue);
754 return Standard_True;
757 // =======================================================================
758 // function : GetAttribute
759 // purpose : Returns the integer vertex attribute
760 // =======================================================================
761 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
762 const GLchar* theName,
763 OpenGl_Vec4i& theValue) const
765 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
768 // =======================================================================
769 // function : GetAttribute
770 // purpose : Returns the integer vertex attribute
771 // =======================================================================
772 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
774 OpenGl_Vec4i& theValue) const
776 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
778 return Standard_False;
781 theCtx->core20fwd->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
782 return Standard_True;
785 // =======================================================================
786 // function : GetAttribute
787 // purpose : Returns the floating-point vertex attribute
788 // =======================================================================
789 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
790 const GLchar* theName,
791 OpenGl_Vec4& theValue) const
793 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
796 // =======================================================================
797 // function : GetAttribute
798 // purpose : Returns the floating-point vertex attribute
799 // =======================================================================
800 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
802 OpenGl_Vec4& theValue) const
804 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
806 return Standard_False;
809 theCtx->core20fwd->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
810 return Standard_True;
813 // =======================================================================
814 // function : SetAttributeName
816 // =======================================================================
817 Standard_Boolean OpenGl_ShaderProgram::SetAttributeName (const Handle(OpenGl_Context)& theCtx,
819 const GLchar* theName)
821 theCtx->core20fwd->glBindAttribLocation (myProgramID, theIndex, theName);
822 return Standard_True;
825 // =======================================================================
826 // function : SetAttribute
828 // =======================================================================
829 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
830 const GLchar* theName,
833 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
836 // =======================================================================
837 // function : SetAttribute
839 // =======================================================================
840 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
844 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
846 return Standard_False;
849 theCtx->core20fwd->glVertexAttrib1f (theIndex, theValue);
850 return Standard_True;
853 // =======================================================================
854 // function : SetAttribute
856 // =======================================================================
857 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
858 const GLchar* theName,
859 const OpenGl_Vec2& theValue)
861 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
864 // =======================================================================
865 // function : SetAttribute
867 // =======================================================================
868 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
870 const OpenGl_Vec2& theValue)
872 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
874 return Standard_False;
877 theCtx->core20fwd->glVertexAttrib2fv (theIndex, theValue);
878 return Standard_True;
881 // =======================================================================
882 // function : SetAttribute
884 // =======================================================================
885 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
886 const GLchar* theName,
887 const OpenGl_Vec3& theValue)
889 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
892 // =======================================================================
893 // function : SetAttribute
895 // =======================================================================
896 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
898 const OpenGl_Vec3& theValue)
900 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
902 return Standard_False;
905 theCtx->core20fwd->glVertexAttrib3fv (theIndex, theValue);
906 return Standard_True;
909 // =======================================================================
910 // function : SetAttribute
912 // =======================================================================
913 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
914 const GLchar* theName,
915 const OpenGl_Vec4& theValue)
917 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
920 // =======================================================================
921 // function : SetAttribute
923 // =======================================================================
924 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
926 const OpenGl_Vec4& theValue)
928 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
930 return Standard_False;
933 theCtx->core20fwd->glVertexAttrib4fv (theIndex, theValue);
934 return Standard_True;
937 // =======================================================================
938 // function : SetUniform
939 // purpose : Specifies the value of the integer uniform variable
940 // =======================================================================
941 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
942 const GLchar* theName,
945 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
948 // =======================================================================
949 // function : SetUniform
950 // purpose : Specifies the value of the integer uniform variable
951 // =======================================================================
952 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
956 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
958 return Standard_False;
961 theCtx->core20fwd->glUniform1i (theLocation, theValue);
962 return Standard_True;
965 // =======================================================================
966 // function : SetUniform
968 // =======================================================================
969 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
970 const GLchar* theName,
971 const OpenGl_Vec2u& theValue)
973 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
976 // =======================================================================
977 // function : SetUniform
979 // =======================================================================
980 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
982 const OpenGl_Vec2u& theValue)
984 if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
986 return Standard_False;
989 #if !defined(GL_ES_VERSION_2_0)
990 theCtx->core32->glUniform2uiv (theLocation, 1, theValue.GetData());
991 return Standard_True;
994 return Standard_False;
998 // =======================================================================
999 // function : SetUniform
1001 // =======================================================================
1002 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1003 const GLchar* theName,
1004 const GLsizei theCount,
1005 const OpenGl_Vec2u* theValue)
1007 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theCount, theValue);
1010 // =======================================================================
1011 // function : SetUniform
1013 // =======================================================================
1014 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1016 const GLsizei theCount,
1017 const OpenGl_Vec2u* theValue)
1019 if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1021 return Standard_False;
1024 #if !defined(GL_ES_VERSION_2_0)
1025 theCtx->core32->glUniform2uiv (theLocation, theCount, theValue->GetData());
1026 return Standard_True;
1030 return Standard_False;
1034 // =======================================================================
1035 // function : SetUniform
1036 // purpose : Specifies the value of the floating-point uniform variable
1037 // =======================================================================
1038 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1039 const GLchar* theName,
1042 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1045 // =======================================================================
1046 // function : SetUniform
1047 // purpose : Specifies the value of the floating-point uniform variable
1048 // =======================================================================
1049 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1053 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1055 return Standard_False;
1058 theCtx->core20fwd->glUniform1f (theLocation, theValue);
1059 return Standard_True;
1062 // =======================================================================
1063 // function : SetUniform
1064 // purpose : Specifies the value of the integer uniform 2D vector
1065 // =======================================================================
1066 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1067 const GLchar* theName,
1068 const OpenGl_Vec2i& theValue)
1070 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1073 // =======================================================================
1074 // function : SetUniform
1075 // purpose : Specifies the value of the integer uniform 2D vector
1076 // =======================================================================
1077 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1079 const OpenGl_Vec2i& theValue)
1081 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1083 return Standard_False;
1086 theCtx->core20fwd->glUniform2iv (theLocation, 1, theValue);
1087 return Standard_True;
1090 // =======================================================================
1091 // function : SetUniform
1092 // purpose : Specifies the value of the integer uniform 3D vector
1093 // =======================================================================
1094 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1095 const GLchar* theName,
1096 const OpenGl_Vec3i& theValue)
1098 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1101 // =======================================================================
1102 // function : SetUniform
1103 // purpose : Specifies the value of the integer uniform 3D vector
1104 // =======================================================================
1105 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1107 const OpenGl_Vec3i& theValue)
1109 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1111 return Standard_False;
1114 theCtx->core20fwd->glUniform3iv (theLocation, 1, theValue);
1115 return Standard_True;
1118 // =======================================================================
1119 // function : SetUniform
1120 // purpose : Specifies the value of the integer uniform 4D vector
1121 // =======================================================================
1122 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1123 const GLchar* theName,
1124 const OpenGl_Vec4i& theValue)
1126 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1129 // =======================================================================
1130 // function : SetUniform
1131 // purpose : Specifies the value of the integer uniform 4D vector
1132 // =======================================================================
1133 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1135 const OpenGl_Vec4i& theValue)
1137 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1139 return Standard_False;
1142 theCtx->core20fwd->glUniform4iv (theLocation, 1, theValue);
1143 return Standard_True;
1146 // =======================================================================
1147 // function : SetUniform
1148 // purpose : Specifies the value of the floating-point uniform 2D vector
1149 // =======================================================================
1150 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1151 const GLchar* theName,
1152 const OpenGl_Vec2& theValue)
1154 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1157 // =======================================================================
1158 // function : SetUniform
1159 // purpose : Specifies the value of the floating-point uniform 2D vector
1160 // =======================================================================
1161 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1163 const OpenGl_Vec2& theValue)
1165 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1167 return Standard_False;
1170 theCtx->core20fwd->glUniform2fv (theLocation, 1, theValue);
1171 return Standard_True;
1174 // =======================================================================
1175 // function : SetUniform
1176 // purpose : Specifies the value of the floating-point uniform 3D vector
1177 // =======================================================================
1178 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1179 const GLchar* theName,
1180 const OpenGl_Vec3& theValue)
1182 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1185 // =======================================================================
1186 // function : SetUniform
1187 // purpose : Specifies the value of the floating-point uniform 3D vector
1188 // =======================================================================
1189 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1191 const OpenGl_Vec3& theValue)
1193 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1195 return Standard_False;
1198 theCtx->core20fwd->glUniform3fv (theLocation, 1, theValue);
1199 return Standard_True;
1202 // =======================================================================
1203 // function : SetUniform
1204 // purpose : Specifies the value of the floating-point uniform 4D vector
1205 // =======================================================================
1206 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1207 const GLchar* theName,
1208 const OpenGl_Vec4& theValue)
1210 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1213 // =======================================================================
1214 // function : SetUniform
1215 // purpose : Specifies the value of the floating-point uniform 4D vector
1216 // =======================================================================
1217 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1219 const OpenGl_Vec4& theValue)
1221 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1223 return Standard_False;
1226 theCtx->core20fwd->glUniform4fv (theLocation, 1, theValue);
1227 return Standard_True;
1230 // =======================================================================
1231 // function : SetUniform
1232 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1233 // =======================================================================
1234 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1235 const GLchar* theName,
1236 const OpenGl_Mat4& theValue,
1237 GLboolean theTranspose)
1239 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1242 // =======================================================================
1243 // function : SetUniform
1244 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1245 // =======================================================================
1246 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1248 const OpenGl_Mat4& theValue,
1249 GLboolean theTranspose)
1251 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1253 return Standard_False;
1256 theCtx->core20fwd->glUniformMatrix4fv (theLocation, 1, GL_FALSE, theTranspose ? theValue.Transposed() : theValue);
1257 return Standard_True;
1260 // =======================================================================
1261 // function : SetUniform
1262 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1263 // =======================================================================
1264 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1265 const GLchar* theName,
1266 const OpenGl_Matrix& theValue,
1267 GLboolean theTranspose)
1269 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1272 // =======================================================================
1273 // function : SetUniform
1274 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1275 // =======================================================================
1276 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1278 const OpenGl_Matrix& theValue,
1279 GLboolean theTranspose)
1281 return SetUniform (theCtx, theLocation, OpenGl_Mat4::Map (*theValue.mat), theTranspose);
1284 // =======================================================================
1285 // function : SetUniform
1286 // purpose : Specifies the value of the float uniform array
1287 // =======================================================================
1288 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1291 const Standard_ShortReal* theData)
1293 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1295 return Standard_False;
1298 theCtx->core20fwd->glUniform1fv (theLocation, theCount, theData);
1299 return Standard_True;
1302 // =======================================================================
1303 // function : SetUniform
1304 // purpose : Specifies the value of the float2 uniform array
1305 // =======================================================================
1306 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1309 const OpenGl_Vec2* theData)
1311 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1313 return Standard_False;
1316 theCtx->core20fwd->glUniform2fv (theLocation, theCount, theData[0].GetData());
1317 return Standard_True;
1320 // =======================================================================
1321 // function : SetUniform
1322 // purpose : Specifies the value of the float3 uniform array
1323 // =======================================================================
1324 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1327 const OpenGl_Vec3* theData)
1329 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1331 return Standard_False;
1334 theCtx->core20fwd->glUniform3fv (theLocation, theCount, theData[0].GetData());
1335 return Standard_True;
1338 // =======================================================================
1339 // function : SetUniform
1340 // purpose : Specifies the value of the float4 uniform array
1341 // =======================================================================
1342 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1345 const OpenGl_Vec4* theData)
1347 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1349 return Standard_False;
1352 theCtx->core20fwd->glUniform4fv (theLocation, theCount, theData[0].GetData());
1353 return Standard_True;
1356 // =======================================================================
1357 // function : SetUniform
1358 // purpose : Specifies the value of the integer uniform array
1359 // =======================================================================
1360 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1363 const Standard_Integer* theData)
1365 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1367 return Standard_False;
1370 theCtx->core20fwd->glUniform1iv (theLocation, theCount, theData);
1371 return Standard_True;
1374 // =======================================================================
1375 // function : SetUniform
1376 // purpose : Specifies the value of the int2 uniform array
1377 // =======================================================================
1378 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1381 const OpenGl_Vec2i* theData)
1383 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1385 return Standard_False;
1388 theCtx->core20fwd->glUniform2iv (theLocation, theCount, theData[0].GetData());
1389 return Standard_True;
1392 // =======================================================================
1393 // function : SetUniform
1394 // purpose : Specifies the value of the int3 uniform array
1395 // =======================================================================
1396 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1399 const OpenGl_Vec3i* theData)
1401 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1403 return Standard_False;
1406 theCtx->core20fwd->glUniform3iv (theLocation, theCount, theData[0].GetData());
1407 return Standard_True;
1410 // =======================================================================
1411 // function : SetUniform
1412 // purpose : Specifies the value of the int4 uniform array
1413 // =======================================================================
1414 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1417 const OpenGl_Vec4i* theData)
1419 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1421 return Standard_False;
1424 theCtx->core20fwd->glUniform4iv (theLocation, theCount, theData[0].GetData());
1425 return Standard_True;
1428 // =======================================================================
1429 // function : SetSampler
1430 // purpose : Specifies the value of the sampler uniform variable
1431 // =======================================================================
1432 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1433 const GLchar* theName,
1434 const Graphic3d_TextureUnit theTextureUnit)
1436 return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit);
1439 // =======================================================================
1440 // function : SetSampler
1441 // purpose : Specifies the value of the sampler uniform variable
1442 // =======================================================================
1443 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1445 const Graphic3d_TextureUnit theTextureUnit)
1447 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1449 return Standard_False;
1452 theCtx->core20fwd->glUniform1i (theLocation, theTextureUnit);
1453 return Standard_True;
1456 // =======================================================================
1457 // function : Create
1458 // purpose : Creates new empty shader program of specified type
1459 // =======================================================================
1460 Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx)
1462 if (myProgramID == NO_PROGRAM
1463 && theCtx->core20fwd != NULL)
1465 myProgramID = theCtx->core20fwd->glCreateProgram();
1468 return myProgramID != NO_PROGRAM;
1471 // =======================================================================
1472 // function : Release
1473 // purpose : Destroys shader program
1474 // =======================================================================
1475 void OpenGl_ShaderProgram::Release (OpenGl_Context* theCtx)
1477 if (myProgramID == NO_PROGRAM)
1482 Standard_ASSERT_RETURN (theCtx != NULL,
1483 "OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...",);
1485 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
1487 if (!anIter.Value().IsNull())
1489 anIter.ChangeValue()->Release (theCtx);
1490 anIter.ChangeValue().Nullify();
1494 if (theCtx->core20fwd != NULL
1495 && theCtx->IsValid())
1497 theCtx->core20fwd->glDeleteProgram (myProgramID);
1500 myProgramID = NO_PROGRAM;
1503 // =======================================================================
1504 // function : UpdateDebugDump
1506 // =======================================================================
1507 Standard_Boolean OpenGl_ShaderProgram::UpdateDebugDump (const Handle(OpenGl_Context)& theCtx,
1508 const TCollection_AsciiString& theFolder,
1509 Standard_Boolean theToBeautify,
1510 Standard_Boolean theToReset)
1512 if (myProgramID == NO_PROGRAM)
1514 return Standard_False;
1517 TCollection_AsciiString aFolder = theFolder;
1518 if (aFolder.IsEmpty())
1520 OSD_Environment aShaderVar ("CSF_ShadersDirectoryDump");
1521 aFolder = aShaderVar.Value();
1522 if (aFolder.IsEmpty())
1528 bool hasUpdates = false;
1529 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
1531 if (!anIter.Value().IsNull())
1533 // desktop OpenGL (but not OpenGL ES) allows multiple shaders of the same stage to be attached,
1534 // but here we expect only single source per stage
1535 hasUpdates = anIter.ChangeValue()->updateDebugDump (theCtx, myResourceId, aFolder, theToBeautify, theToReset) || hasUpdates;
1540 return Link (theCtx);
1542 return Standard_False;