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
87 "occOrthoScale", // OpenGl_OCCT_ORTHO_SCALE
88 "occSilhouetteThickness" // OpenGl_OCCT_SILHOUETTE_THICKNESS
93 //! Convert Graphic3d_TypeOfShaderObject enumeration into OpenGL enumeration.
94 static GLenum shaderTypeToGl (Graphic3d_TypeOfShaderObject theType)
98 case Graphic3d_TOS_VERTEX: return GL_VERTEX_SHADER;
99 case Graphic3d_TOS_FRAGMENT: return GL_FRAGMENT_SHADER;
100 case Graphic3d_TOS_GEOMETRY: return GL_GEOMETRY_SHADER;
101 case Graphic3d_TOS_TESS_CONTROL: return GL_TESS_CONTROL_SHADER;
102 case Graphic3d_TOS_TESS_EVALUATION: return GL_TESS_EVALUATION_SHADER;
103 case Graphic3d_TOS_COMPUTE: return GL_COMPUTE_SHADER;
109 // =======================================================================
110 // function : OpenGl_VariableSetterSelector
111 // purpose : Creates new variable setter selector
112 // =======================================================================
113 OpenGl_VariableSetterSelector::OpenGl_VariableSetterSelector()
115 // Note: Add new variable setters here
116 mySetterList = OpenGl_HashMapInitializer::CreateListOf<size_t, OpenGl_SetterInterface*>
117 (Graphic3d_UniformValueTypeID<int>::ID, new OpenGl_VariableSetter<int>())
118 (Graphic3d_UniformValueTypeID<float>::ID, new OpenGl_VariableSetter<float>())
119 (Graphic3d_UniformValueTypeID<OpenGl_Vec2>::ID, new OpenGl_VariableSetter<OpenGl_Vec2>())
120 (Graphic3d_UniformValueTypeID<OpenGl_Vec3>::ID, new OpenGl_VariableSetter<OpenGl_Vec3>())
121 (Graphic3d_UniformValueTypeID<OpenGl_Vec4>::ID, new OpenGl_VariableSetter<OpenGl_Vec4>())
122 (Graphic3d_UniformValueTypeID<OpenGl_Vec2i>::ID, new OpenGl_VariableSetter<OpenGl_Vec2i>())
123 (Graphic3d_UniformValueTypeID<OpenGl_Vec3i>::ID, new OpenGl_VariableSetter<OpenGl_Vec3i>())
124 (Graphic3d_UniformValueTypeID<OpenGl_Vec4i>::ID, new OpenGl_VariableSetter<OpenGl_Vec4i>());
127 // =======================================================================
128 // function : ~OpenGl_VariableSetterSelector
129 // purpose : Releases memory resources of variable setter selector
130 // =======================================================================
131 OpenGl_VariableSetterSelector::~OpenGl_VariableSetterSelector()
133 for (OpenGl_SetterList::Iterator anIt (mySetterList); anIt.More(); anIt.Next())
138 mySetterList.Clear();
141 // =======================================================================
143 // purpose : Sets generic variable to specified shader program
144 // =======================================================================
145 void OpenGl_VariableSetterSelector::Set (const Handle(OpenGl_Context)& theCtx,
146 const Handle(Graphic3d_ShaderVariable)& theVariable,
147 OpenGl_ShaderProgram* theProgram) const
149 Standard_ASSERT_RETURN (mySetterList.IsBound (theVariable->Value()->TypeID()),
150 "The type of user-defined uniform variable is not supported...", );
152 mySetterList.Find (theVariable->Value()->TypeID())->Set (theCtx, theVariable, theProgram);
155 // =======================================================================
156 // function : OpenGl_ShaderProgram
157 // purpose : Creates uninitialized shader program
158 // =======================================================================
159 OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy,
160 const TCollection_AsciiString& theId)
161 : OpenGl_NamedResource (!theProxy.IsNull() ? theProxy->GetId() : theId),
162 myProgramID (NO_PROGRAM),
166 myNbClipPlanesMax (0),
168 myHasAlphaTest (false),
169 myHasWeightOitOutput (false),
170 myHasTessShader (false)
172 memset (myCurrentState, 0, sizeof (myCurrentState));
175 // =======================================================================
176 // function : Initialize
177 // purpose : Initializes program object with the list of shader objects
178 // =======================================================================
179 Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& theCtx,
180 const Graphic3d_ShaderObjectList& theShaders)
182 myHasTessShader = false;
183 if (theCtx.IsNull() || !Create (theCtx))
185 return Standard_False;
188 TCollection_AsciiString aHeaderVer = !myProxy.IsNull() ? myProxy->Header() : TCollection_AsciiString();
190 for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders); anIter.More(); anIter.Next())
192 aShaderMask |= anIter.Value()->Type();
194 myHasTessShader = (aShaderMask & (Graphic3d_TOS_TESS_CONTROL | Graphic3d_TOS_TESS_EVALUATION)) != 0;
195 myNbFragOutputs = !myProxy.IsNull() ? myProxy->NbFragmentOutputs() : 1;
196 myHasAlphaTest = !myProxy.IsNull() && myProxy->HasAlphaTest();
197 myHasWeightOitOutput = !myProxy.IsNull() ? myProxy->HasWeightOitOutput() && myNbFragOutputs >= 2 : 1;
199 // detect the minimum GLSL version required for defined Shader Objects
200 #if defined(GL_ES_VERSION_2_0)
203 if (!theCtx->IsGlGreaterEqual (3, 2))
205 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
206 "Error! Tessellation shader requires OpenGL ES 3.2+");
209 else if (aHeaderVer.IsEmpty())
211 aHeaderVer = "#version 320 es";
214 else if ((aShaderMask & Graphic3d_TOS_GEOMETRY) != 0)
216 switch (theCtx->hasGeometryStage)
218 case OpenGl_FeatureNotAvailable:
220 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
221 "Error! Geometry shader requires OpenGL ES 3.2+ or GL_EXT_geometry_shader");
224 case OpenGl_FeatureInExtensions:
226 if (aHeaderVer.IsEmpty())
228 aHeaderVer = "#version 310 es";
232 case OpenGl_FeatureInCore:
234 if (aHeaderVer.IsEmpty())
236 aHeaderVer = "#version 320 es";
242 else if ((aShaderMask & Graphic3d_TOS_COMPUTE) != 0)
244 if (!theCtx->IsGlGreaterEqual (3, 1))
246 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
247 "Error! Compute shaders require OpenGL ES 3.1+");
250 else if (aHeaderVer.IsEmpty())
252 aHeaderVer = "#version 310 es";
256 if ((aShaderMask & Graphic3d_TOS_COMPUTE) != 0)
258 if (!theCtx->IsGlGreaterEqual (4, 3))
260 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
261 "Error! Compute shaders require OpenGL 4.3+");
264 else if (aHeaderVer.IsEmpty())
266 aHeaderVer = "#version 430";
269 else if (myHasTessShader)
271 if (!theCtx->IsGlGreaterEqual (4, 0))
273 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
274 "Error! Tessellation shaders require OpenGL 4.0+");
277 else if (aHeaderVer.IsEmpty())
279 aHeaderVer = "#version 400";
282 else if ((aShaderMask & Graphic3d_TOS_GEOMETRY) != 0)
284 if (!theCtx->IsGlGreaterEqual (3, 2))
286 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
287 "Error! Geometry shaders require OpenGL 3.2+");
290 else if (aHeaderVer.IsEmpty())
292 aHeaderVer = "#version 150";
297 for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders); anIter.More(); anIter.Next())
299 if (!anIter.Value()->IsDone())
301 const TCollection_ExtendedString aMsg = "Error! Failed to get shader source";
302 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
303 return Standard_False;
306 const GLenum aShaderType = shaderTypeToGl (anIter.Value()->Type());
307 if (aShaderType == 0)
309 return Standard_False;
312 Handle(OpenGl_ShaderObject) aShader = new OpenGl_ShaderObject (aShaderType);
313 if (!aShader->Create (theCtx))
315 aShader->Release (theCtx.operator->());
316 return Standard_False;
319 TCollection_AsciiString anExtensions = "// Enable extensions used in OCCT GLSL programs\n";
320 if (myNbFragOutputs > 1)
322 if (theCtx->hasDrawBuffers)
324 anExtensions += "#define OCC_ENABLE_draw_buffers\n";
325 if (myHasWeightOitOutput)
327 anExtensions += "#define OCC_WRITE_WEIGHT_OIT_COVERAGE\n";
332 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
333 "Error! Multiple draw buffers required by the program, but aren't supported by OpenGL");
334 return Standard_False;
337 if (theCtx->hasDrawBuffers == OpenGl_FeatureInExtensions)
339 if (theCtx->arbDrawBuffers)
341 anExtensions += "#extension GL_ARB_draw_buffers : enable\n";
343 else if (theCtx->extDrawBuffers)
345 anExtensions += "#extension GL_EXT_draw_buffers : enable\n";
351 anExtensions += "#define OCC_ALPHA_TEST\n";
354 if (theCtx->hasSampleVariables == OpenGl_FeatureInExtensions)
356 #if defined(GL_ES_VERSION_2_0)
357 if (theCtx->oesSampleVariables)
359 anExtensions += "#extension GL_OES_sample_variables : enable\n";
362 if (theCtx->arbSampleShading)
364 anExtensions += "#extension GL_ARB_sample_shading : enable\n";
368 #if defined(GL_ES_VERSION_2_0)
369 if (theCtx->hasGeometryStage == OpenGl_FeatureInExtensions)
371 anExtensions += "#extension GL_EXT_geometry_shader : enable\n"
372 "#extension GL_EXT_shader_io_blocks : enable\n";
376 TCollection_AsciiString aPrecisionHeader;
377 if (anIter.Value()->Type() == Graphic3d_TOS_FRAGMENT)
379 #if defined(GL_ES_VERSION_2_0)
380 aPrecisionHeader = theCtx->hasHighp
381 ? "precision highp float;\n"
382 "precision highp int;\n"
383 : "precision mediump float;\n"
384 "precision mediump int;\n";
388 TCollection_AsciiString aHeaderType;
389 switch (anIter.Value()->Type())
391 case Graphic3d_TOS_COMPUTE: { aHeaderType = "#define COMPUTE_SHADER\n"; break; }
392 case Graphic3d_TOS_VERTEX: { aHeaderType = "#define VERTEX_SHADER\n"; break; }
393 case Graphic3d_TOS_TESS_CONTROL: { aHeaderType = "#define TESS_CONTROL_SHADER\n"; break; }
394 case Graphic3d_TOS_TESS_EVALUATION: { aHeaderType = "#define TESS_EVALUATION_SHADER\n"; break; }
395 case Graphic3d_TOS_GEOMETRY: { aHeaderType = "#define GEOMETRY_SHADER\n"; break; }
396 case Graphic3d_TOS_FRAGMENT: { aHeaderType = "#define FRAGMENT_SHADER\n"; break; }
399 TCollection_AsciiString aHeaderConstants;
400 myNbLightsMax = !myProxy.IsNull() ? myProxy->NbLightsMax() : 0;
401 myNbClipPlanesMax = !myProxy.IsNull() ? myProxy->NbClipPlanesMax() : 0;
402 aHeaderConstants += TCollection_AsciiString("#define THE_MAX_LIGHTS ") + myNbLightsMax + "\n";
403 aHeaderConstants += TCollection_AsciiString("#define THE_MAX_CLIP_PLANES ") + myNbClipPlanesMax + "\n";
404 aHeaderConstants += TCollection_AsciiString("#define THE_NB_FRAG_OUTPUTS ") + myNbFragOutputs + "\n";
406 const TCollection_AsciiString aSource = aHeaderVer // #version - header defining GLSL version, should be first
407 + (!aHeaderVer.IsEmpty() ? "\n" : "")
408 + anExtensions // #extension - list of enabled extensions, should be second
409 + aPrecisionHeader // precision - default precision qualifiers, should be before any code
410 + aHeaderType // auxiliary macros defining a shader stage (type)
412 + Shaders_Declarations_glsl // common declarations (global constants and Vertex Shader inputs)
413 + Shaders_DeclarationsImpl_glsl
414 + anIter.Value()->Source(); // the source code itself (defining main() function)
415 if (!aShader->LoadAndCompile (theCtx, aSource))
417 aShader->Release (theCtx.operator->());
418 return Standard_False;
421 if (theCtx->caps->glslDumpLevel)
423 TCollection_AsciiString aShaderTypeMsg;
424 switch (anIter.Value()->Type())
426 case Graphic3d_TOS_COMPUTE: { aShaderTypeMsg = "Compute shader source code:\n"; break; }
427 case Graphic3d_TOS_VERTEX: { aShaderTypeMsg = "Vertex shader source code:\n"; break; }
428 case Graphic3d_TOS_TESS_CONTROL: { aShaderTypeMsg = "Tesselation control shader source code:\n"; break; }
429 case Graphic3d_TOS_TESS_EVALUATION: { aShaderTypeMsg = "Tesselation evaluation shader source code:\n"; break; }
430 case Graphic3d_TOS_GEOMETRY: { aShaderTypeMsg = "Geometry shader source code:\n"; break; }
431 case Graphic3d_TOS_FRAGMENT: { aShaderTypeMsg = "Fragment shader source code:\n"; break; }
433 TCollection_AsciiString anOutputSource = aSource;
434 if (theCtx->caps->glslDumpLevel == OpenGl_ShaderProgramDumpLevel_Short)
436 anOutputSource = aHeaderVer
437 + (!aHeaderVer.IsEmpty() ? "\n" : "")
442 + anIter.Value()->Source();
444 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 0, GL_DEBUG_SEVERITY_MEDIUM,
445 TCollection_ExtendedString (aShaderTypeMsg + anOutputSource));
448 if (!AttachShader (theCtx, aShader))
450 aShader->Release (theCtx.operator->());
451 return Standard_False;
455 // bind locations for pre-defined Vertex Attributes
456 SetAttributeName (theCtx, Graphic3d_TOA_POS, "occVertex");
457 SetAttributeName (theCtx, Graphic3d_TOA_NORM, "occNormal");
458 SetAttributeName (theCtx, Graphic3d_TOA_UV, "occTexCoord");
459 SetAttributeName (theCtx, Graphic3d_TOA_COLOR, "occVertColor");
461 // bind custom Vertex Attributes
462 if (!myProxy.IsNull())
464 for (Graphic3d_ShaderAttributeList::Iterator anAttribIter (myProxy->VertexAttributes());
465 anAttribIter.More(); anAttribIter.Next())
467 SetAttributeName (theCtx, anAttribIter.Value()->Location(), anAttribIter.Value()->Name().ToCString());
473 return Standard_False;
476 // set uniform defaults
477 const Handle(OpenGl_ShaderProgram)& anOldProgram = theCtx->ActiveProgram();
478 theCtx->core20fwd->glUseProgram (myProgramID);
479 if (const OpenGl_ShaderUniformLocation aLocTexEnable = GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE))
481 SetUniform (theCtx, aLocTexEnable, 0); // Off
483 if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occActiveSampler"))
485 SetUniform (theCtx, aLocSampler, GLint(Graphic3d_TextureUnit_0));
488 const TCollection_AsciiString aSamplerNamePrefix ("occSampler");
489 const Standard_Integer aNbUnitsMax = Max (theCtx->MaxCombinedTextureUnits(), Graphic3d_TextureUnit_NB);
490 for (GLint aUnitIter = 0; aUnitIter < aNbUnitsMax; ++aUnitIter)
492 const TCollection_AsciiString aName = aSamplerNamePrefix + aUnitIter;
493 if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, aName.ToCString()))
495 SetUniform (theCtx, aLocSampler, aUnitIter);
499 theCtx->core20fwd->glUseProgram (!anOldProgram.IsNull() ? anOldProgram->ProgramId() : OpenGl_ShaderProgram::NO_PROGRAM);
500 return Standard_True;
503 // =======================================================================
504 // function : ~OpenGl_ShaderProgram
505 // purpose : Releases resources of shader program
506 // =======================================================================
507 OpenGl_ShaderProgram::~OpenGl_ShaderProgram()
512 // =======================================================================
513 // function : AttachShader
514 // purpose : Attaches shader object to the program object
515 // =======================================================================
516 Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context)& theCtx,
517 const Handle(OpenGl_ShaderObject)& theShader)
519 if (myProgramID == NO_PROGRAM || theShader.IsNull())
521 return Standard_False;
524 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
526 if (theShader == anIter.Value())
528 return Standard_False;
532 myShaderObjects.Append (theShader);
533 theCtx->core20fwd->glAttachShader (myProgramID, theShader->myShaderID);
534 return Standard_True;
537 // =======================================================================
538 // function : DetachShader
539 // purpose : Detaches shader object to the program object
540 // =======================================================================
541 Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context)& theCtx,
542 const Handle(OpenGl_ShaderObject)& theShader)
544 if (myProgramID == NO_PROGRAM
545 || theShader.IsNull())
547 return Standard_False;
550 OpenGl_ShaderList::Iterator anIter (myShaderObjects);
551 while (anIter.More())
553 if (theShader == anIter.Value())
555 myShaderObjects.Remove (anIter);
564 return Standard_False;
567 theCtx->core20fwd->glDetachShader (myProgramID, theShader->myShaderID);
568 return Standard_True;
571 // =======================================================================
573 // purpose : Links the program object
574 // =======================================================================
575 Standard_Boolean OpenGl_ShaderProgram::link (const Handle(OpenGl_Context)& theCtx)
577 if (myProgramID == NO_PROGRAM)
579 return Standard_False;
582 GLint aStatus = GL_FALSE;
583 theCtx->core20fwd->glLinkProgram (myProgramID);
584 theCtx->core20fwd->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
585 if (aStatus == GL_FALSE)
587 return Standard_False;
590 memset (myCurrentState, 0, sizeof (myCurrentState));
591 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
593 myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]);
595 return Standard_True;
598 // =======================================================================
601 // =======================================================================
602 Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx,
607 return link (theCtx);
612 TCollection_AsciiString aLog;
613 FetchInfoLog (theCtx, aLog);
616 aLog = "Linker log is empty.";
618 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
619 TCollection_AsciiString ("Failed to link program object! Linker log:\n") + aLog);
622 else if (theCtx->caps->glslWarnings)
624 TCollection_AsciiString aLog;
625 FetchInfoLog (theCtx, aLog);
627 && !aLog.IsEqual ("No errors.\n"))
629 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_LOW,
630 TCollection_AsciiString ("GLSL linker log:\n") + aLog);
636 // =======================================================================
637 // function : FetchInfoLog
638 // purpose : Fetches information log of the last link operation
639 // =======================================================================
640 Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
641 TCollection_AsciiString& theOutput)
643 if (myProgramID == NO_PROGRAM)
645 return Standard_False;
649 theCtx->core20fwd->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
652 GLchar* aLog = (GLchar*) alloca (aLength);
653 memset (aLog, 0, aLength);
654 theCtx->core20fwd->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
657 return Standard_True;
660 // =======================================================================
661 // function : ApplyVariables
662 // purpose : Fetches uniform variables from proxy shader program
663 // =======================================================================
664 Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Context)& theCtx)
666 if (myProxy.IsNull() || myProxy->Variables().IsEmpty())
668 return Standard_False;
671 for (Graphic3d_ShaderVariableList::Iterator anIter (myProxy->Variables()); anIter.More(); anIter.Next())
673 mySetterSelector.Set (theCtx, anIter.Value(), this);
676 myProxy->ClearVariables();
677 return Standard_True;
680 // =======================================================================
681 // function : GetUniformLocation
682 // purpose : Returns location (index) of the specific uniform variable
683 // =======================================================================
684 OpenGl_ShaderUniformLocation OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& theCtx,
685 const GLchar* theName) const
687 return OpenGl_ShaderUniformLocation (myProgramID != NO_PROGRAM
688 ? theCtx->core20fwd->glGetUniformLocation (myProgramID, theName)
692 // =======================================================================
693 // function : GetAttributeLocation
694 // purpose : Returns location (index) of the generic vertex attribute
695 // =======================================================================
696 GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)& theCtx,
697 const GLchar* theName) const
699 return myProgramID != NO_PROGRAM
700 ? theCtx->core20fwd->glGetAttribLocation (myProgramID, theName)
704 // =======================================================================
705 // function : GetUniform
706 // purpose : Returns the value of the integer uniform variable
707 // =======================================================================
708 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
709 const GLchar* theName,
710 OpenGl_Vec4i& theValue) const
712 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
715 // =======================================================================
716 // function : GetUniform
717 // purpose : Returns the value of the integer uniform variable
718 // =======================================================================
719 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
721 OpenGl_Vec4i& theValue) const
723 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
725 return Standard_False;
728 theCtx->core20fwd->glGetUniformiv (myProgramID, theLocation, theValue);
729 return Standard_True;
732 // =======================================================================
733 // function : GetUniform
734 // purpose : Returns the value of the floating-point uniform variable
735 // =======================================================================
736 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
737 const GLchar* theName,
738 OpenGl_Vec4& theValue) const
740 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
743 // =======================================================================
744 // function : GetUniform
745 // purpose : Returns the value of the floating-point uniform variable
746 // =======================================================================
747 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
749 OpenGl_Vec4& theValue) const
751 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
753 return Standard_False;
756 theCtx->core20fwd->glGetUniformfv (myProgramID, theLocation, theValue);
757 return Standard_True;
760 // =======================================================================
761 // function : GetAttribute
762 // purpose : Returns the integer vertex attribute
763 // =======================================================================
764 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
765 const GLchar* theName,
766 OpenGl_Vec4i& theValue) const
768 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
771 // =======================================================================
772 // function : GetAttribute
773 // purpose : Returns the integer vertex attribute
774 // =======================================================================
775 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
777 OpenGl_Vec4i& theValue) const
779 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
781 return Standard_False;
784 theCtx->core20fwd->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
785 return Standard_True;
788 // =======================================================================
789 // function : GetAttribute
790 // purpose : Returns the floating-point vertex attribute
791 // =======================================================================
792 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
793 const GLchar* theName,
794 OpenGl_Vec4& theValue) const
796 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
799 // =======================================================================
800 // function : GetAttribute
801 // purpose : Returns the floating-point vertex attribute
802 // =======================================================================
803 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
805 OpenGl_Vec4& theValue) const
807 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
809 return Standard_False;
812 theCtx->core20fwd->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
813 return Standard_True;
816 // =======================================================================
817 // function : SetAttributeName
819 // =======================================================================
820 Standard_Boolean OpenGl_ShaderProgram::SetAttributeName (const Handle(OpenGl_Context)& theCtx,
822 const GLchar* theName)
824 theCtx->core20fwd->glBindAttribLocation (myProgramID, theIndex, theName);
825 return Standard_True;
828 // =======================================================================
829 // function : SetAttribute
831 // =======================================================================
832 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
833 const GLchar* theName,
836 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
839 // =======================================================================
840 // function : SetAttribute
842 // =======================================================================
843 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
847 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
849 return Standard_False;
852 theCtx->core20fwd->glVertexAttrib1f (theIndex, theValue);
853 return Standard_True;
856 // =======================================================================
857 // function : SetAttribute
859 // =======================================================================
860 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
861 const GLchar* theName,
862 const OpenGl_Vec2& theValue)
864 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
867 // =======================================================================
868 // function : SetAttribute
870 // =======================================================================
871 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
873 const OpenGl_Vec2& theValue)
875 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
877 return Standard_False;
880 theCtx->core20fwd->glVertexAttrib2fv (theIndex, theValue);
881 return Standard_True;
884 // =======================================================================
885 // function : SetAttribute
887 // =======================================================================
888 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
889 const GLchar* theName,
890 const OpenGl_Vec3& theValue)
892 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
895 // =======================================================================
896 // function : SetAttribute
898 // =======================================================================
899 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
901 const OpenGl_Vec3& theValue)
903 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
905 return Standard_False;
908 theCtx->core20fwd->glVertexAttrib3fv (theIndex, theValue);
909 return Standard_True;
912 // =======================================================================
913 // function : SetAttribute
915 // =======================================================================
916 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
917 const GLchar* theName,
918 const OpenGl_Vec4& theValue)
920 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
923 // =======================================================================
924 // function : SetAttribute
926 // =======================================================================
927 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
929 const OpenGl_Vec4& theValue)
931 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
933 return Standard_False;
936 theCtx->core20fwd->glVertexAttrib4fv (theIndex, theValue);
937 return Standard_True;
940 // =======================================================================
941 // function : SetUniform
942 // purpose : Specifies the value of the integer uniform variable
943 // =======================================================================
944 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
945 const GLchar* theName,
948 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
951 // =======================================================================
952 // function : SetUniform
953 // purpose : Specifies the value of the integer uniform variable
954 // =======================================================================
955 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
959 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
961 return Standard_False;
964 theCtx->core20fwd->glUniform1i (theLocation, theValue);
965 return Standard_True;
968 // =======================================================================
969 // function : SetUniform
971 // =======================================================================
972 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
973 const GLchar* theName,
974 const OpenGl_Vec2u& theValue)
976 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
979 // =======================================================================
980 // function : SetUniform
982 // =======================================================================
983 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
985 const OpenGl_Vec2u& theValue)
987 if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
989 return Standard_False;
992 #if !defined(GL_ES_VERSION_2_0)
993 theCtx->core32->glUniform2uiv (theLocation, 1, theValue.GetData());
994 return Standard_True;
997 return Standard_False;
1001 // =======================================================================
1002 // function : SetUniform
1004 // =======================================================================
1005 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1006 const GLchar* theName,
1007 const GLsizei theCount,
1008 const OpenGl_Vec2u* theValue)
1010 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theCount, theValue);
1013 // =======================================================================
1014 // function : SetUniform
1016 // =======================================================================
1017 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1019 const GLsizei theCount,
1020 const OpenGl_Vec2u* theValue)
1022 if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1024 return Standard_False;
1027 #if !defined(GL_ES_VERSION_2_0)
1028 theCtx->core32->glUniform2uiv (theLocation, theCount, theValue->GetData());
1029 return Standard_True;
1033 return Standard_False;
1037 // =======================================================================
1038 // function : SetUniform
1039 // purpose : Specifies the value of the floating-point uniform variable
1040 // =======================================================================
1041 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1042 const GLchar* theName,
1045 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1048 // =======================================================================
1049 // function : SetUniform
1050 // purpose : Specifies the value of the floating-point uniform variable
1051 // =======================================================================
1052 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1056 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1058 return Standard_False;
1061 theCtx->core20fwd->glUniform1f (theLocation, theValue);
1062 return Standard_True;
1065 // =======================================================================
1066 // function : SetUniform
1067 // purpose : Specifies the value of the integer uniform 2D vector
1068 // =======================================================================
1069 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1070 const GLchar* theName,
1071 const OpenGl_Vec2i& theValue)
1073 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1076 // =======================================================================
1077 // function : SetUniform
1078 // purpose : Specifies the value of the integer uniform 2D vector
1079 // =======================================================================
1080 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1082 const OpenGl_Vec2i& theValue)
1084 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1086 return Standard_False;
1089 theCtx->core20fwd->glUniform2iv (theLocation, 1, theValue);
1090 return Standard_True;
1093 // =======================================================================
1094 // function : SetUniform
1095 // purpose : Specifies the value of the integer uniform 3D vector
1096 // =======================================================================
1097 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1098 const GLchar* theName,
1099 const OpenGl_Vec3i& theValue)
1101 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1104 // =======================================================================
1105 // function : SetUniform
1106 // purpose : Specifies the value of the integer uniform 3D vector
1107 // =======================================================================
1108 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1110 const OpenGl_Vec3i& theValue)
1112 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1114 return Standard_False;
1117 theCtx->core20fwd->glUniform3iv (theLocation, 1, theValue);
1118 return Standard_True;
1121 // =======================================================================
1122 // function : SetUniform
1123 // purpose : Specifies the value of the integer uniform 4D vector
1124 // =======================================================================
1125 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1126 const GLchar* theName,
1127 const OpenGl_Vec4i& theValue)
1129 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1132 // =======================================================================
1133 // function : SetUniform
1134 // purpose : Specifies the value of the integer uniform 4D vector
1135 // =======================================================================
1136 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1138 const OpenGl_Vec4i& theValue)
1140 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1142 return Standard_False;
1145 theCtx->core20fwd->glUniform4iv (theLocation, 1, theValue);
1146 return Standard_True;
1149 // =======================================================================
1150 // function : SetUniform
1151 // purpose : Specifies the value of the floating-point uniform 2D vector
1152 // =======================================================================
1153 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1154 const GLchar* theName,
1155 const OpenGl_Vec2& theValue)
1157 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1160 // =======================================================================
1161 // function : SetUniform
1162 // purpose : Specifies the value of the floating-point uniform 2D vector
1163 // =======================================================================
1164 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1166 const OpenGl_Vec2& theValue)
1168 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1170 return Standard_False;
1173 theCtx->core20fwd->glUniform2fv (theLocation, 1, theValue);
1174 return Standard_True;
1177 // =======================================================================
1178 // function : SetUniform
1179 // purpose : Specifies the value of the floating-point uniform 3D vector
1180 // =======================================================================
1181 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1182 const GLchar* theName,
1183 const OpenGl_Vec3& theValue)
1185 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1188 // =======================================================================
1189 // function : SetUniform
1190 // purpose : Specifies the value of the floating-point uniform 3D vector
1191 // =======================================================================
1192 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1194 const OpenGl_Vec3& theValue)
1196 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1198 return Standard_False;
1201 theCtx->core20fwd->glUniform3fv (theLocation, 1, theValue);
1202 return Standard_True;
1205 // =======================================================================
1206 // function : SetUniform
1207 // purpose : Specifies the value of the floating-point uniform 4D vector
1208 // =======================================================================
1209 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1210 const GLchar* theName,
1211 const OpenGl_Vec4& theValue)
1213 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1216 // =======================================================================
1217 // function : SetUniform
1218 // purpose : Specifies the value of the floating-point uniform 4D vector
1219 // =======================================================================
1220 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1222 const OpenGl_Vec4& theValue)
1224 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1226 return Standard_False;
1229 theCtx->core20fwd->glUniform4fv (theLocation, 1, theValue);
1230 return Standard_True;
1233 // =======================================================================
1234 // function : SetUniform
1235 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1236 // =======================================================================
1237 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1238 const GLchar* theName,
1239 const OpenGl_Mat4& theValue,
1240 GLboolean theTranspose)
1242 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1245 // =======================================================================
1246 // function : SetUniform
1247 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1248 // =======================================================================
1249 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1251 const OpenGl_Mat4& theValue,
1252 GLboolean theTranspose)
1254 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1256 return Standard_False;
1259 theCtx->core20fwd->glUniformMatrix4fv (theLocation, 1, GL_FALSE, theTranspose ? theValue.Transposed() : theValue);
1260 return Standard_True;
1263 // =======================================================================
1264 // function : SetUniform
1265 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1266 // =======================================================================
1267 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1268 const GLchar* theName,
1269 const OpenGl_Matrix& theValue,
1270 GLboolean theTranspose)
1272 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1275 // =======================================================================
1276 // function : SetUniform
1277 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1278 // =======================================================================
1279 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1281 const OpenGl_Matrix& theValue,
1282 GLboolean theTranspose)
1284 return SetUniform (theCtx, theLocation, OpenGl_Mat4::Map (*theValue.mat), theTranspose);
1287 // =======================================================================
1288 // function : SetUniform
1289 // purpose : Specifies the value of the float uniform array
1290 // =======================================================================
1291 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1294 const Standard_ShortReal* theData)
1296 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1298 return Standard_False;
1301 theCtx->core20fwd->glUniform1fv (theLocation, theCount, theData);
1302 return Standard_True;
1305 // =======================================================================
1306 // function : SetUniform
1307 // purpose : Specifies the value of the float2 uniform array
1308 // =======================================================================
1309 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1312 const OpenGl_Vec2* theData)
1314 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1316 return Standard_False;
1319 theCtx->core20fwd->glUniform2fv (theLocation, theCount, theData[0].GetData());
1320 return Standard_True;
1323 // =======================================================================
1324 // function : SetUniform
1325 // purpose : Specifies the value of the float3 uniform array
1326 // =======================================================================
1327 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1330 const OpenGl_Vec3* theData)
1332 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1334 return Standard_False;
1337 theCtx->core20fwd->glUniform3fv (theLocation, theCount, theData[0].GetData());
1338 return Standard_True;
1341 // =======================================================================
1342 // function : SetUniform
1343 // purpose : Specifies the value of the float4 uniform array
1344 // =======================================================================
1345 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1348 const OpenGl_Vec4* theData)
1350 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1352 return Standard_False;
1355 theCtx->core20fwd->glUniform4fv (theLocation, theCount, theData[0].GetData());
1356 return Standard_True;
1359 // =======================================================================
1360 // function : SetUniform
1361 // purpose : Specifies the value of the integer uniform array
1362 // =======================================================================
1363 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1366 const Standard_Integer* theData)
1368 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1370 return Standard_False;
1373 theCtx->core20fwd->glUniform1iv (theLocation, theCount, theData);
1374 return Standard_True;
1377 // =======================================================================
1378 // function : SetUniform
1379 // purpose : Specifies the value of the int2 uniform array
1380 // =======================================================================
1381 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1384 const OpenGl_Vec2i* theData)
1386 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1388 return Standard_False;
1391 theCtx->core20fwd->glUniform2iv (theLocation, theCount, theData[0].GetData());
1392 return Standard_True;
1395 // =======================================================================
1396 // function : SetUniform
1397 // purpose : Specifies the value of the int3 uniform array
1398 // =======================================================================
1399 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1402 const OpenGl_Vec3i* theData)
1404 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1406 return Standard_False;
1409 theCtx->core20fwd->glUniform3iv (theLocation, theCount, theData[0].GetData());
1410 return Standard_True;
1413 // =======================================================================
1414 // function : SetUniform
1415 // purpose : Specifies the value of the int4 uniform array
1416 // =======================================================================
1417 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1420 const OpenGl_Vec4i* theData)
1422 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1424 return Standard_False;
1427 theCtx->core20fwd->glUniform4iv (theLocation, theCount, theData[0].GetData());
1428 return Standard_True;
1431 // =======================================================================
1432 // function : SetSampler
1433 // purpose : Specifies the value of the sampler uniform variable
1434 // =======================================================================
1435 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1436 const GLchar* theName,
1437 const Graphic3d_TextureUnit theTextureUnit)
1439 return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit);
1442 // =======================================================================
1443 // function : SetSampler
1444 // purpose : Specifies the value of the sampler uniform variable
1445 // =======================================================================
1446 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1448 const Graphic3d_TextureUnit theTextureUnit)
1450 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1452 return Standard_False;
1455 theCtx->core20fwd->glUniform1i (theLocation, theTextureUnit);
1456 return Standard_True;
1459 // =======================================================================
1460 // function : Create
1461 // purpose : Creates new empty shader program of specified type
1462 // =======================================================================
1463 Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx)
1465 if (myProgramID == NO_PROGRAM
1466 && theCtx->core20fwd != NULL)
1468 myProgramID = theCtx->core20fwd->glCreateProgram();
1471 return myProgramID != NO_PROGRAM;
1474 // =======================================================================
1475 // function : Release
1476 // purpose : Destroys shader program
1477 // =======================================================================
1478 void OpenGl_ShaderProgram::Release (OpenGl_Context* theCtx)
1480 if (myProgramID == NO_PROGRAM)
1485 Standard_ASSERT_RETURN (theCtx != NULL,
1486 "OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...",);
1488 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
1490 if (!anIter.Value().IsNull())
1492 anIter.ChangeValue()->Release (theCtx);
1493 anIter.ChangeValue().Nullify();
1497 if (theCtx->core20fwd != NULL
1498 && theCtx->IsValid())
1500 theCtx->core20fwd->glDeleteProgram (myProgramID);
1503 myProgramID = NO_PROGRAM;
1506 // =======================================================================
1507 // function : UpdateDebugDump
1509 // =======================================================================
1510 Standard_Boolean OpenGl_ShaderProgram::UpdateDebugDump (const Handle(OpenGl_Context)& theCtx,
1511 const TCollection_AsciiString& theFolder,
1512 Standard_Boolean theToBeautify,
1513 Standard_Boolean theToReset)
1515 if (myProgramID == NO_PROGRAM)
1517 return Standard_False;
1520 TCollection_AsciiString aFolder = theFolder;
1521 if (aFolder.IsEmpty())
1523 OSD_Environment aShaderVar ("CSF_ShadersDirectoryDump");
1524 aFolder = aShaderVar.Value();
1525 if (aFolder.IsEmpty())
1531 bool hasUpdates = false;
1532 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
1534 if (!anIter.Value().IsNull())
1536 // desktop OpenGL (but not OpenGL ES) allows multiple shaders of the same stage to be attached,
1537 // but here we expect only single source per stage
1538 hasUpdates = anIter.ChangeValue()->updateDebugDump (theCtx, myResourceId, aFolder, theToBeautify, theToReset) || hasUpdates;
1543 return Link (theCtx);
1545 return Standard_False;