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 "occPbrFrontMaterial", // OpenGl_OCCT_PBR_FRONT_MATERIAL
71 "occPbrBackMaterial", // OpenGl_OCCT_PBR_BACK_MATERIAL
72 "occFrontMaterial", // OpenGl_OCCT_COMMON_FRONT_MATERIAL
73 "occBackMaterial", // OpenGl_OCCT_COMMON_BACK_MATERIAL
74 "occAlphaCutoff", // OpenGl_OCCT_ALPHA_CUTOFF
75 "occColor", // OpenGl_OCCT_COLOR
77 "occOitOutput", // OpenGl_OCCT_OIT_OUTPUT
78 "occOitDepthFactor", // OpenGl_OCCT_OIT_DEPTH_FACTOR
80 "occTexTrsf2d", // OpenGl_OCCT_TEXTURE_TRSF2D
81 "occPointSize", // OpenGl_OCCT_POINT_SIZE
83 "occViewport", // OpenGl_OCCT_VIEWPORT
84 "occLineWidth", // OpenGl_OCCT_LINE_WIDTH
85 "occLineFeather", // OpenGl_OCCT_LINE_FEATHER
86 "occStipplePattern", // OpenGl_OCCT_LINE_STIPPLE_PATTERN
87 "occStippleFactor", // OpenGl_OCCT_LINE_STIPPLE_FACTOR
88 "occWireframeColor", // OpenGl_OCCT_WIREFRAME_COLOR
89 "occIsQuadMode", // OpenGl_OCCT_QUAD_MODE_STATE
91 "occOrthoScale", // OpenGl_OCCT_ORTHO_SCALE
92 "occSilhouetteThickness", // OpenGl_OCCT_SILHOUETTE_THICKNESS
94 "occNbSpecIBLLevels" // OpenGl_OCCT_NB_SPEC_IBL_LEVELS
99 //! Convert Graphic3d_TypeOfShaderObject enumeration into OpenGL enumeration.
100 static GLenum shaderTypeToGl (Graphic3d_TypeOfShaderObject theType)
104 case Graphic3d_TOS_VERTEX: return GL_VERTEX_SHADER;
105 case Graphic3d_TOS_FRAGMENT: return GL_FRAGMENT_SHADER;
106 case Graphic3d_TOS_GEOMETRY: return GL_GEOMETRY_SHADER;
107 case Graphic3d_TOS_TESS_CONTROL: return GL_TESS_CONTROL_SHADER;
108 case Graphic3d_TOS_TESS_EVALUATION: return GL_TESS_EVALUATION_SHADER;
109 case Graphic3d_TOS_COMPUTE: return GL_COMPUTE_SHADER;
115 // =======================================================================
116 // function : OpenGl_VariableSetterSelector
117 // purpose : Creates new variable setter selector
118 // =======================================================================
119 OpenGl_VariableSetterSelector::OpenGl_VariableSetterSelector()
121 // Note: Add new variable setters here
122 mySetterList = OpenGl_HashMapInitializer::CreateListOf<size_t, OpenGl_SetterInterface*>
123 (Graphic3d_UniformValueTypeID<int>::ID, new OpenGl_VariableSetter<int>())
124 (Graphic3d_UniformValueTypeID<float>::ID, new OpenGl_VariableSetter<float>())
125 (Graphic3d_UniformValueTypeID<OpenGl_Vec2>::ID, new OpenGl_VariableSetter<OpenGl_Vec2>())
126 (Graphic3d_UniformValueTypeID<OpenGl_Vec3>::ID, new OpenGl_VariableSetter<OpenGl_Vec3>())
127 (Graphic3d_UniformValueTypeID<OpenGl_Vec4>::ID, new OpenGl_VariableSetter<OpenGl_Vec4>())
128 (Graphic3d_UniformValueTypeID<OpenGl_Vec2i>::ID, new OpenGl_VariableSetter<OpenGl_Vec2i>())
129 (Graphic3d_UniformValueTypeID<OpenGl_Vec3i>::ID, new OpenGl_VariableSetter<OpenGl_Vec3i>())
130 (Graphic3d_UniformValueTypeID<OpenGl_Vec4i>::ID, new OpenGl_VariableSetter<OpenGl_Vec4i>());
133 // =======================================================================
134 // function : ~OpenGl_VariableSetterSelector
135 // purpose : Releases memory resources of variable setter selector
136 // =======================================================================
137 OpenGl_VariableSetterSelector::~OpenGl_VariableSetterSelector()
139 for (OpenGl_SetterList::Iterator anIt (mySetterList); anIt.More(); anIt.Next())
144 mySetterList.Clear();
147 // =======================================================================
149 // purpose : Sets generic variable to specified shader program
150 // =======================================================================
151 void OpenGl_VariableSetterSelector::Set (const Handle(OpenGl_Context)& theCtx,
152 const Handle(Graphic3d_ShaderVariable)& theVariable,
153 OpenGl_ShaderProgram* theProgram) const
155 Standard_ASSERT_RETURN (mySetterList.IsBound (theVariable->Value()->TypeID()),
156 "The type of user-defined uniform variable is not supported...", );
158 mySetterList.Find (theVariable->Value()->TypeID())->Set (theCtx, theVariable, theProgram);
161 // =======================================================================
162 // function : OpenGl_ShaderProgram
163 // purpose : Creates uninitialized shader program
164 // =======================================================================
165 OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy,
166 const TCollection_AsciiString& theId)
167 : OpenGl_NamedResource (!theProxy.IsNull() ? theProxy->GetId() : theId),
168 myProgramID (NO_PROGRAM),
172 myNbClipPlanesMax (0),
174 myHasAlphaTest (false),
175 myHasWeightOitOutput (false),
176 myHasTessShader (false)
178 memset (myCurrentState, 0, sizeof (myCurrentState));
181 // =======================================================================
182 // function : Initialize
183 // purpose : Initializes program object with the list of shader objects
184 // =======================================================================
185 Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& theCtx,
186 const Graphic3d_ShaderObjectList& theShaders)
188 myHasTessShader = false;
189 if (theCtx.IsNull() || !Create (theCtx))
191 return Standard_False;
194 TCollection_AsciiString aHeaderVer = !myProxy.IsNull() ? myProxy->Header() : TCollection_AsciiString();
196 for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders); anIter.More(); anIter.Next())
198 aShaderMask |= anIter.Value()->Type();
200 myHasTessShader = (aShaderMask & (Graphic3d_TOS_TESS_CONTROL | Graphic3d_TOS_TESS_EVALUATION)) != 0;
201 myNbFragOutputs = !myProxy.IsNull() ? myProxy->NbFragmentOutputs() : 1;
202 myHasAlphaTest = !myProxy.IsNull() && myProxy->HasAlphaTest();
203 myHasWeightOitOutput = !myProxy.IsNull() ? myProxy->HasWeightOitOutput() && myNbFragOutputs >= 2 : 1;
205 // detect the minimum GLSL version required for defined Shader Objects
206 #if defined(GL_ES_VERSION_2_0)
209 if (!theCtx->IsGlGreaterEqual (3, 2))
211 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
212 "Error! Tessellation shader requires OpenGL ES 3.2+");
215 else if (aHeaderVer.IsEmpty())
217 aHeaderVer = "#version 320 es";
220 else if ((aShaderMask & Graphic3d_TOS_GEOMETRY) != 0)
222 switch (theCtx->hasGeometryStage)
224 case OpenGl_FeatureNotAvailable:
226 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
227 "Error! Geometry shader requires OpenGL ES 3.2+ or GL_EXT_geometry_shader");
230 case OpenGl_FeatureInExtensions:
232 if (aHeaderVer.IsEmpty())
234 aHeaderVer = "#version 310 es";
238 case OpenGl_FeatureInCore:
240 if (aHeaderVer.IsEmpty())
242 aHeaderVer = "#version 320 es";
248 else if ((aShaderMask & Graphic3d_TOS_COMPUTE) != 0)
250 if (!theCtx->IsGlGreaterEqual (3, 1))
252 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
253 "Error! Compute shaders require OpenGL ES 3.1+");
256 else if (aHeaderVer.IsEmpty())
258 aHeaderVer = "#version 310 es";
262 if ((aShaderMask & Graphic3d_TOS_COMPUTE) != 0)
264 if (!theCtx->IsGlGreaterEqual (4, 3))
266 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
267 "Error! Compute shaders require OpenGL 4.3+");
270 else if (aHeaderVer.IsEmpty())
272 aHeaderVer = "#version 430";
275 else if (myHasTessShader)
277 if (!theCtx->IsGlGreaterEqual (4, 0))
279 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
280 "Error! Tessellation shaders require OpenGL 4.0+");
283 else if (aHeaderVer.IsEmpty())
285 aHeaderVer = "#version 400";
288 else if ((aShaderMask & Graphic3d_TOS_GEOMETRY) != 0)
290 if (!theCtx->IsGlGreaterEqual (3, 2))
292 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
293 "Error! Geometry shaders require OpenGL 3.2+");
296 else if (aHeaderVer.IsEmpty())
298 aHeaderVer = "#version 150";
303 for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders); anIter.More(); anIter.Next())
305 if (!anIter.Value()->IsDone())
307 const TCollection_ExtendedString aMsg = "Error! Failed to get shader source";
308 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
309 return Standard_False;
312 const GLenum aShaderType = shaderTypeToGl (anIter.Value()->Type());
313 if (aShaderType == 0)
315 return Standard_False;
318 Handle(OpenGl_ShaderObject) aShader = new OpenGl_ShaderObject (aShaderType);
319 if (!aShader->Create (theCtx))
321 aShader->Release (theCtx.operator->());
322 return Standard_False;
325 TCollection_AsciiString anExtensions = "// Enable extensions used in OCCT GLSL programs\n";
326 if (myNbFragOutputs > 1)
328 if (theCtx->hasDrawBuffers)
330 anExtensions += "#define OCC_ENABLE_draw_buffers\n";
331 if (myHasWeightOitOutput)
333 anExtensions += "#define OCC_WRITE_WEIGHT_OIT_COVERAGE\n";
338 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
339 "Error! Multiple draw buffers required by the program, but aren't supported by OpenGL");
340 return Standard_False;
343 if (theCtx->hasDrawBuffers == OpenGl_FeatureInExtensions)
345 if (theCtx->arbDrawBuffers)
347 anExtensions += "#extension GL_ARB_draw_buffers : enable\n";
349 else if (theCtx->extDrawBuffers)
351 anExtensions += "#extension GL_EXT_draw_buffers : enable\n";
357 anExtensions += "#define OCC_ALPHA_TEST\n";
360 if (theCtx->hasSampleVariables == OpenGl_FeatureInExtensions)
362 #if defined(GL_ES_VERSION_2_0)
363 if (theCtx->oesSampleVariables)
365 anExtensions += "#extension GL_OES_sample_variables : enable\n";
368 if (theCtx->arbSampleShading)
370 anExtensions += "#extension GL_ARB_sample_shading : enable\n";
374 #if defined(GL_ES_VERSION_2_0)
375 if (theCtx->hasGeometryStage == OpenGl_FeatureInExtensions)
377 anExtensions += "#extension GL_EXT_geometry_shader : enable\n"
378 "#extension GL_EXT_shader_io_blocks : enable\n";
382 TCollection_AsciiString aPrecisionHeader;
383 if (anIter.Value()->Type() == Graphic3d_TOS_FRAGMENT)
385 #if defined(GL_ES_VERSION_2_0)
386 aPrecisionHeader = theCtx->hasHighp
387 ? "precision highp float;\n"
388 "precision highp int;\n"
389 : "precision mediump float;\n"
390 "precision mediump int;\n";
394 TCollection_AsciiString aHeaderType;
395 switch (anIter.Value()->Type())
397 case Graphic3d_TOS_COMPUTE: { aHeaderType = "#define COMPUTE_SHADER\n"; break; }
398 case Graphic3d_TOS_VERTEX: { aHeaderType = "#define VERTEX_SHADER\n"; break; }
399 case Graphic3d_TOS_TESS_CONTROL: { aHeaderType = "#define TESS_CONTROL_SHADER\n"; break; }
400 case Graphic3d_TOS_TESS_EVALUATION: { aHeaderType = "#define TESS_EVALUATION_SHADER\n"; break; }
401 case Graphic3d_TOS_GEOMETRY: { aHeaderType = "#define GEOMETRY_SHADER\n"; break; }
402 case Graphic3d_TOS_FRAGMENT: { aHeaderType = "#define FRAGMENT_SHADER\n"; break; }
405 TCollection_AsciiString aHeaderConstants;
406 myNbLightsMax = !myProxy.IsNull() ? myProxy->NbLightsMax() : 0;
407 myNbClipPlanesMax = !myProxy.IsNull() ? myProxy->NbClipPlanesMax() : 0;
408 aHeaderConstants += TCollection_AsciiString("#define THE_MAX_LIGHTS ") + myNbLightsMax + "\n";
409 aHeaderConstants += TCollection_AsciiString("#define THE_MAX_CLIP_PLANES ") + myNbClipPlanesMax + "\n";
410 aHeaderConstants += TCollection_AsciiString("#define THE_NB_FRAG_OUTPUTS ") + myNbFragOutputs + "\n";
411 if (!myProxy.IsNull()
412 && myProxy->HasDefaultSampler())
414 aHeaderConstants += "#define THE_HAS_DEFAULT_SAMPLER\n";
416 if (!myProxy.IsNull()
419 aHeaderConstants += "#define THE_IS_PBR\n";
422 const TCollection_AsciiString aSource = aHeaderVer // #version - header defining GLSL version, should be first
423 + (!aHeaderVer.IsEmpty() ? "\n" : "")
424 + anExtensions // #extension - list of enabled extensions, should be second
425 + aPrecisionHeader // precision - default precision qualifiers, should be before any code
426 + aHeaderType // auxiliary macros defining a shader stage (type)
428 + Shaders_Declarations_glsl // common declarations (global constants and Vertex Shader inputs)
429 + Shaders_DeclarationsImpl_glsl
430 + anIter.Value()->Source(); // the source code itself (defining main() function)
431 if (!aShader->LoadAndCompile (theCtx, myResourceId, aSource))
433 aShader->Release (theCtx.operator->());
434 return Standard_False;
437 if (theCtx->caps->glslDumpLevel)
439 TCollection_AsciiString anOutputSource = aSource;
440 if (theCtx->caps->glslDumpLevel == OpenGl_ShaderProgramDumpLevel_Short)
442 anOutputSource = aHeaderVer
443 + (!aHeaderVer.IsEmpty() ? "\n" : "")
448 + anIter.Value()->Source();
450 aShader->DumpSourceCode (theCtx, myResourceId, anOutputSource);
453 if (!AttachShader (theCtx, aShader))
455 aShader->Release (theCtx.operator->());
456 return Standard_False;
460 // bind locations for pre-defined Vertex Attributes
461 SetAttributeName (theCtx, Graphic3d_TOA_POS, "occVertex");
462 SetAttributeName (theCtx, Graphic3d_TOA_NORM, "occNormal");
463 SetAttributeName (theCtx, Graphic3d_TOA_UV, "occTexCoord");
464 SetAttributeName (theCtx, Graphic3d_TOA_COLOR, "occVertColor");
466 // bind custom Vertex Attributes
467 if (!myProxy.IsNull())
469 for (Graphic3d_ShaderAttributeList::Iterator anAttribIter (myProxy->VertexAttributes());
470 anAttribIter.More(); anAttribIter.Next())
472 SetAttributeName (theCtx, anAttribIter.Value()->Location(), anAttribIter.Value()->Name().ToCString());
478 return Standard_False;
481 // set uniform defaults
482 const Handle(OpenGl_ShaderProgram)& anOldProgram = theCtx->ActiveProgram();
483 theCtx->core20fwd->glUseProgram (myProgramID);
484 if (const OpenGl_ShaderUniformLocation aLocTexEnable = GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE))
486 SetUniform (theCtx, aLocTexEnable, 0); // Off
488 if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occActiveSampler"))
490 SetUniform (theCtx, aLocSampler, GLint(Graphic3d_TextureUnit_0));
492 if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occSamplerBaseColor"))
494 SetUniform (theCtx, aLocSampler, GLint(Graphic3d_TextureUnit_BaseColor));
496 if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occSamplerPointSprite"))
498 SetUniform (theCtx, aLocSampler, GLint(theCtx->SpriteTextureUnit()));
500 if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occDiffIBLMapSHCoeffs"))
502 SetUniform (theCtx, aLocSampler, GLint(theCtx->PBRDiffIBLMapSHTexUnit()));
504 if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occSpecIBLMap"))
506 SetUniform (theCtx, aLocSampler, GLint(theCtx->PBRSpecIBLMapTexUnit()));
508 if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occEnvLUT"))
510 SetUniform (theCtx, aLocSampler, GLint(theCtx->PBREnvLUTTexUnit()));
513 const TCollection_AsciiString aSamplerNamePrefix ("occSampler");
514 const Standard_Integer aNbUnitsMax = Max (theCtx->MaxCombinedTextureUnits(), Graphic3d_TextureUnit_NB);
515 for (GLint aUnitIter = 0; aUnitIter < aNbUnitsMax; ++aUnitIter)
517 const TCollection_AsciiString aName = aSamplerNamePrefix + aUnitIter;
518 if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, aName.ToCString()))
520 SetUniform (theCtx, aLocSampler, aUnitIter);
524 theCtx->core20fwd->glUseProgram (!anOldProgram.IsNull() ? anOldProgram->ProgramId() : OpenGl_ShaderProgram::NO_PROGRAM);
525 return Standard_True;
528 // =======================================================================
529 // function : ~OpenGl_ShaderProgram
530 // purpose : Releases resources of shader program
531 // =======================================================================
532 OpenGl_ShaderProgram::~OpenGl_ShaderProgram()
537 // =======================================================================
538 // function : AttachShader
539 // purpose : Attaches shader object to the program object
540 // =======================================================================
541 Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context)& theCtx,
542 const Handle(OpenGl_ShaderObject)& theShader)
544 if (myProgramID == NO_PROGRAM || theShader.IsNull())
546 return Standard_False;
549 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
551 if (theShader == anIter.Value())
553 return Standard_False;
557 myShaderObjects.Append (theShader);
558 theCtx->core20fwd->glAttachShader (myProgramID, theShader->myShaderID);
559 return Standard_True;
562 // =======================================================================
563 // function : DetachShader
564 // purpose : Detaches shader object to the program object
565 // =======================================================================
566 Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context)& theCtx,
567 const Handle(OpenGl_ShaderObject)& theShader)
569 if (myProgramID == NO_PROGRAM
570 || theShader.IsNull())
572 return Standard_False;
575 OpenGl_ShaderList::Iterator anIter (myShaderObjects);
576 while (anIter.More())
578 if (theShader == anIter.Value())
580 myShaderObjects.Remove (anIter);
589 return Standard_False;
592 theCtx->core20fwd->glDetachShader (myProgramID, theShader->myShaderID);
593 return Standard_True;
596 // =======================================================================
598 // purpose : Links the program object
599 // =======================================================================
600 Standard_Boolean OpenGl_ShaderProgram::link (const Handle(OpenGl_Context)& theCtx)
602 if (myProgramID == NO_PROGRAM)
604 return Standard_False;
607 GLint aStatus = GL_FALSE;
608 theCtx->core20fwd->glLinkProgram (myProgramID);
609 theCtx->core20fwd->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
610 if (aStatus == GL_FALSE)
612 return Standard_False;
615 memset (myCurrentState, 0, sizeof (myCurrentState));
616 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
618 myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]);
620 return Standard_True;
623 // =======================================================================
626 // =======================================================================
627 Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx,
632 return link (theCtx);
637 TCollection_AsciiString aLog;
638 FetchInfoLog (theCtx, aLog);
641 aLog = "Linker log is empty.";
643 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
644 TCollection_AsciiString ("Failed to link program object [") + myResourceId + "]! Linker log:\n" + aLog);
647 else if (theCtx->caps->glslWarnings)
649 TCollection_AsciiString aLog;
650 FetchInfoLog (theCtx, aLog);
652 && !aLog.IsEqual ("No errors.\n"))
654 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_LOW,
655 TCollection_AsciiString ("GLSL linker log [") + myResourceId +"]:\n" + aLog);
661 // =======================================================================
662 // function : FetchInfoLog
663 // purpose : Fetches information log of the last link operation
664 // =======================================================================
665 Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
666 TCollection_AsciiString& theOutput)
668 if (myProgramID == NO_PROGRAM)
670 return Standard_False;
674 theCtx->core20fwd->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
677 GLchar* aLog = (GLchar*) alloca (aLength);
678 memset (aLog, 0, aLength);
679 theCtx->core20fwd->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
682 return Standard_True;
685 // =======================================================================
686 // function : ApplyVariables
687 // purpose : Fetches uniform variables from proxy shader program
688 // =======================================================================
689 Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Context)& theCtx)
691 if (myProxy.IsNull() || myProxy->Variables().IsEmpty())
693 return Standard_False;
696 for (Graphic3d_ShaderVariableList::Iterator anIter (myProxy->Variables()); anIter.More(); anIter.Next())
698 mySetterSelector.Set (theCtx, anIter.Value(), this);
701 myProxy->ClearVariables();
702 return Standard_True;
705 // =======================================================================
706 // function : GetUniformLocation
707 // purpose : Returns location (index) of the specific uniform variable
708 // =======================================================================
709 OpenGl_ShaderUniformLocation OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& theCtx,
710 const GLchar* theName) const
712 return OpenGl_ShaderUniformLocation (myProgramID != NO_PROGRAM
713 ? theCtx->core20fwd->glGetUniformLocation (myProgramID, theName)
717 // =======================================================================
718 // function : GetAttributeLocation
719 // purpose : Returns location (index) of the generic vertex attribute
720 // =======================================================================
721 GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)& theCtx,
722 const GLchar* theName) const
724 return myProgramID != NO_PROGRAM
725 ? theCtx->core20fwd->glGetAttribLocation (myProgramID, theName)
729 // =======================================================================
730 // function : GetUniform
731 // purpose : Returns the value of the integer uniform variable
732 // =======================================================================
733 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
734 const GLchar* theName,
735 OpenGl_Vec4i& theValue) const
737 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
740 // =======================================================================
741 // function : GetUniform
742 // purpose : Returns the value of the integer uniform variable
743 // =======================================================================
744 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
746 OpenGl_Vec4i& theValue) const
748 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
750 return Standard_False;
753 theCtx->core20fwd->glGetUniformiv (myProgramID, theLocation, theValue);
754 return Standard_True;
757 // =======================================================================
758 // function : GetUniform
759 // purpose : Returns the value of the floating-point uniform variable
760 // =======================================================================
761 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
762 const GLchar* theName,
763 OpenGl_Vec4& theValue) const
765 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
768 // =======================================================================
769 // function : GetUniform
770 // purpose : Returns the value of the floating-point uniform variable
771 // =======================================================================
772 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
774 OpenGl_Vec4& theValue) const
776 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
778 return Standard_False;
781 theCtx->core20fwd->glGetUniformfv (myProgramID, theLocation, theValue);
782 return Standard_True;
785 // =======================================================================
786 // function : GetAttribute
787 // purpose : Returns the integer vertex attribute
788 // =======================================================================
789 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
790 const GLchar* theName,
791 OpenGl_Vec4i& theValue) const
793 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
796 // =======================================================================
797 // function : GetAttribute
798 // purpose : Returns the integer vertex attribute
799 // =======================================================================
800 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
802 OpenGl_Vec4i& theValue) const
804 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
806 return Standard_False;
809 theCtx->core20fwd->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
810 return Standard_True;
813 // =======================================================================
814 // function : GetAttribute
815 // purpose : Returns the floating-point vertex attribute
816 // =======================================================================
817 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
818 const GLchar* theName,
819 OpenGl_Vec4& theValue) const
821 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
824 // =======================================================================
825 // function : GetAttribute
826 // purpose : Returns the floating-point vertex attribute
827 // =======================================================================
828 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
830 OpenGl_Vec4& theValue) const
832 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
834 return Standard_False;
837 theCtx->core20fwd->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
838 return Standard_True;
841 // =======================================================================
842 // function : SetAttributeName
844 // =======================================================================
845 Standard_Boolean OpenGl_ShaderProgram::SetAttributeName (const Handle(OpenGl_Context)& theCtx,
847 const GLchar* theName)
849 theCtx->core20fwd->glBindAttribLocation (myProgramID, theIndex, theName);
850 return Standard_True;
853 // =======================================================================
854 // function : SetAttribute
856 // =======================================================================
857 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
858 const GLchar* theName,
861 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
864 // =======================================================================
865 // function : SetAttribute
867 // =======================================================================
868 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
872 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
874 return Standard_False;
877 theCtx->core20fwd->glVertexAttrib1f (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_Vec2& 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_Vec2& theValue)
900 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
902 return Standard_False;
905 theCtx->core20fwd->glVertexAttrib2fv (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_Vec3& 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_Vec3& theValue)
928 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
930 return Standard_False;
933 theCtx->core20fwd->glVertexAttrib3fv (theIndex, theValue);
934 return Standard_True;
937 // =======================================================================
938 // function : SetAttribute
940 // =======================================================================
941 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
942 const GLchar* theName,
943 const OpenGl_Vec4& theValue)
945 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
948 // =======================================================================
949 // function : SetAttribute
951 // =======================================================================
952 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
954 const OpenGl_Vec4& theValue)
956 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
958 return Standard_False;
961 theCtx->core20fwd->glVertexAttrib4fv (theIndex, theValue);
962 return Standard_True;
965 // =======================================================================
966 // function : SetUniform
967 // purpose : Specifies the value of the integer uniform variable
968 // =======================================================================
969 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
970 const GLchar* theName,
973 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
976 // =======================================================================
977 // function : SetUniform
978 // purpose : Specifies the value of the integer uniform variable
979 // =======================================================================
980 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
984 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
986 return Standard_False;
989 theCtx->core20fwd->glUniform1i (theLocation, theValue);
990 return Standard_True;
993 // =======================================================================
994 // function : SetUniform
996 // =======================================================================
997 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
998 const GLchar* theName,
999 const OpenGl_Vec2u& theValue)
1001 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1004 // =======================================================================
1005 // function : SetUniform
1007 // =======================================================================
1008 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1010 const OpenGl_Vec2u& theValue)
1012 if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1014 return Standard_False;
1017 #if !defined(GL_ES_VERSION_2_0)
1018 theCtx->core32->glUniform2uiv (theLocation, 1, theValue.GetData());
1019 return Standard_True;
1022 return Standard_False;
1026 // =======================================================================
1027 // function : SetUniform
1029 // =======================================================================
1030 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1031 const GLchar* theName,
1032 const GLsizei theCount,
1033 const OpenGl_Vec2u* theValue)
1035 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theCount, theValue);
1038 // =======================================================================
1039 // function : SetUniform
1041 // =======================================================================
1042 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1044 const GLsizei theCount,
1045 const OpenGl_Vec2u* theValue)
1047 if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1049 return Standard_False;
1052 #if !defined(GL_ES_VERSION_2_0)
1053 theCtx->core32->glUniform2uiv (theLocation, theCount, theValue->GetData());
1054 return Standard_True;
1058 return Standard_False;
1062 // =======================================================================
1063 // function : SetUniform
1064 // purpose : Specifies the value of the floating-point uniform variable
1065 // =======================================================================
1066 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1067 const GLchar* theName,
1070 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1073 // =======================================================================
1074 // function : SetUniform
1075 // purpose : Specifies the value of the floating-point uniform variable
1076 // =======================================================================
1077 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1081 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1083 return Standard_False;
1086 theCtx->core20fwd->glUniform1f (theLocation, theValue);
1087 return Standard_True;
1090 // =======================================================================
1091 // function : SetUniform
1092 // purpose : Specifies the value of the integer uniform 2D vector
1093 // =======================================================================
1094 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1095 const GLchar* theName,
1096 const OpenGl_Vec2i& theValue)
1098 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1101 // =======================================================================
1102 // function : SetUniform
1103 // purpose : Specifies the value of the integer uniform 2D vector
1104 // =======================================================================
1105 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1107 const OpenGl_Vec2i& theValue)
1109 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1111 return Standard_False;
1114 theCtx->core20fwd->glUniform2iv (theLocation, 1, theValue);
1115 return Standard_True;
1118 // =======================================================================
1119 // function : SetUniform
1120 // purpose : Specifies the value of the integer uniform 3D vector
1121 // =======================================================================
1122 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1123 const GLchar* theName,
1124 const OpenGl_Vec3i& theValue)
1126 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1129 // =======================================================================
1130 // function : SetUniform
1131 // purpose : Specifies the value of the integer uniform 3D vector
1132 // =======================================================================
1133 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1135 const OpenGl_Vec3i& theValue)
1137 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1139 return Standard_False;
1142 theCtx->core20fwd->glUniform3iv (theLocation, 1, theValue);
1143 return Standard_True;
1146 // =======================================================================
1147 // function : SetUniform
1148 // purpose : Specifies the value of the integer uniform 4D vector
1149 // =======================================================================
1150 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1151 const GLchar* theName,
1152 const OpenGl_Vec4i& theValue)
1154 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1157 // =======================================================================
1158 // function : SetUniform
1159 // purpose : Specifies the value of the integer uniform 4D vector
1160 // =======================================================================
1161 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1163 const OpenGl_Vec4i& theValue)
1165 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1167 return Standard_False;
1170 theCtx->core20fwd->glUniform4iv (theLocation, 1, theValue);
1171 return Standard_True;
1174 // =======================================================================
1175 // function : SetUniform
1176 // purpose : Specifies the value of the floating-point uniform 2D vector
1177 // =======================================================================
1178 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1179 const GLchar* theName,
1180 const OpenGl_Vec2& theValue)
1182 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1185 // =======================================================================
1186 // function : SetUniform
1187 // purpose : Specifies the value of the floating-point uniform 2D vector
1188 // =======================================================================
1189 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1191 const OpenGl_Vec2& theValue)
1193 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1195 return Standard_False;
1198 theCtx->core20fwd->glUniform2fv (theLocation, 1, theValue);
1199 return Standard_True;
1202 // =======================================================================
1203 // function : SetUniform
1204 // purpose : Specifies the value of the floating-point uniform 3D vector
1205 // =======================================================================
1206 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1207 const GLchar* theName,
1208 const OpenGl_Vec3& theValue)
1210 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1213 // =======================================================================
1214 // function : SetUniform
1215 // purpose : Specifies the value of the floating-point uniform 3D vector
1216 // =======================================================================
1217 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1219 const OpenGl_Vec3& theValue)
1221 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1223 return Standard_False;
1226 theCtx->core20fwd->glUniform3fv (theLocation, 1, theValue);
1227 return Standard_True;
1230 // =======================================================================
1231 // function : SetUniform
1232 // purpose : Specifies the value of the floating-point uniform 4D vector
1233 // =======================================================================
1234 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1235 const GLchar* theName,
1236 const OpenGl_Vec4& theValue)
1238 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1241 // =======================================================================
1242 // function : SetUniform
1243 // purpose : Specifies the value of the floating-point uniform 4D vector
1244 // =======================================================================
1245 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1247 const OpenGl_Vec4& theValue)
1249 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1251 return Standard_False;
1254 theCtx->core20fwd->glUniform4fv (theLocation, 1, theValue);
1255 return Standard_True;
1258 // =======================================================================
1259 // function : SetUniform
1260 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1261 // =======================================================================
1262 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1263 const GLchar* theName,
1264 const OpenGl_Mat4& theValue,
1265 GLboolean theTranspose)
1267 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1270 // =======================================================================
1271 // function : SetUniform
1272 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1273 // =======================================================================
1274 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1276 const OpenGl_Mat4& theValue,
1277 GLboolean theTranspose)
1279 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1281 return Standard_False;
1284 theCtx->core20fwd->glUniformMatrix4fv (theLocation, 1, GL_FALSE, theTranspose ? theValue.Transposed() : theValue);
1285 return Standard_True;
1288 // =======================================================================
1289 // function : SetUniform
1290 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1291 // =======================================================================
1292 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1293 const GLchar* theName,
1294 const OpenGl_Matrix& theValue,
1295 GLboolean theTranspose)
1297 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1300 // =======================================================================
1301 // function : SetUniform
1302 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1303 // =======================================================================
1304 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1306 const OpenGl_Matrix& theValue,
1307 GLboolean theTranspose)
1309 return SetUniform (theCtx, theLocation, OpenGl_Mat4::Map (*theValue.mat), theTranspose);
1312 // =======================================================================
1313 // function : SetUniform
1314 // purpose : Specifies the value of the float uniform array
1315 // =======================================================================
1316 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1319 const Standard_ShortReal* theData)
1321 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1323 return Standard_False;
1326 theCtx->core20fwd->glUniform1fv (theLocation, theCount, theData);
1327 return Standard_True;
1330 // =======================================================================
1331 // function : SetUniform
1332 // purpose : Specifies the value of the float2 uniform array
1333 // =======================================================================
1334 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1337 const OpenGl_Vec2* theData)
1339 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1341 return Standard_False;
1344 theCtx->core20fwd->glUniform2fv (theLocation, theCount, theData[0].GetData());
1345 return Standard_True;
1348 // =======================================================================
1349 // function : SetUniform
1350 // purpose : Specifies the value of the float3 uniform array
1351 // =======================================================================
1352 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1355 const OpenGl_Vec3* theData)
1357 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1359 return Standard_False;
1362 theCtx->core20fwd->glUniform3fv (theLocation, theCount, theData[0].GetData());
1363 return Standard_True;
1366 // =======================================================================
1367 // function : SetUniform
1368 // purpose : Specifies the value of the float4 uniform array
1369 // =======================================================================
1370 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1373 const OpenGl_Vec4* theData)
1375 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1377 return Standard_False;
1380 theCtx->core20fwd->glUniform4fv (theLocation, theCount, theData[0].GetData());
1381 return Standard_True;
1384 // =======================================================================
1385 // function : SetUniform
1386 // purpose : Specifies the value of the integer uniform array
1387 // =======================================================================
1388 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1391 const Standard_Integer* theData)
1393 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1395 return Standard_False;
1398 theCtx->core20fwd->glUniform1iv (theLocation, theCount, theData);
1399 return Standard_True;
1402 // =======================================================================
1403 // function : SetUniform
1404 // purpose : Specifies the value of the int2 uniform array
1405 // =======================================================================
1406 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1409 const OpenGl_Vec2i* theData)
1411 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1413 return Standard_False;
1416 theCtx->core20fwd->glUniform2iv (theLocation, theCount, theData[0].GetData());
1417 return Standard_True;
1420 // =======================================================================
1421 // function : SetUniform
1422 // purpose : Specifies the value of the int3 uniform array
1423 // =======================================================================
1424 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1427 const OpenGl_Vec3i* theData)
1429 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1431 return Standard_False;
1434 theCtx->core20fwd->glUniform3iv (theLocation, theCount, theData[0].GetData());
1435 return Standard_True;
1438 // =======================================================================
1439 // function : SetUniform
1440 // purpose : Specifies the value of the int4 uniform array
1441 // =======================================================================
1442 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1445 const OpenGl_Vec4i* theData)
1447 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1449 return Standard_False;
1452 theCtx->core20fwd->glUniform4iv (theLocation, theCount, theData[0].GetData());
1453 return Standard_True;
1456 // =======================================================================
1457 // function : SetSampler
1458 // purpose : Specifies the value of the sampler uniform variable
1459 // =======================================================================
1460 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1461 const GLchar* theName,
1462 const Graphic3d_TextureUnit theTextureUnit)
1464 return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit);
1467 // =======================================================================
1468 // function : SetSampler
1469 // purpose : Specifies the value of the sampler uniform variable
1470 // =======================================================================
1471 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1473 const Graphic3d_TextureUnit theTextureUnit)
1475 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1477 return Standard_False;
1480 theCtx->core20fwd->glUniform1i (theLocation, theTextureUnit);
1481 return Standard_True;
1484 // =======================================================================
1485 // function : Create
1486 // purpose : Creates new empty shader program of specified type
1487 // =======================================================================
1488 Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx)
1490 if (myProgramID == NO_PROGRAM
1491 && theCtx->core20fwd != NULL)
1493 myProgramID = theCtx->core20fwd->glCreateProgram();
1496 return myProgramID != NO_PROGRAM;
1499 // =======================================================================
1500 // function : Release
1501 // purpose : Destroys shader program
1502 // =======================================================================
1503 void OpenGl_ShaderProgram::Release (OpenGl_Context* theCtx)
1505 if (myProgramID == NO_PROGRAM)
1510 Standard_ASSERT_RETURN (theCtx != NULL,
1511 "OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...",);
1513 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
1515 if (!anIter.Value().IsNull())
1517 anIter.ChangeValue()->Release (theCtx);
1518 anIter.ChangeValue().Nullify();
1522 if (theCtx->core20fwd != NULL
1523 && theCtx->IsValid())
1525 theCtx->core20fwd->glDeleteProgram (myProgramID);
1528 myProgramID = NO_PROGRAM;
1531 // =======================================================================
1532 // function : UpdateDebugDump
1534 // =======================================================================
1535 Standard_Boolean OpenGl_ShaderProgram::UpdateDebugDump (const Handle(OpenGl_Context)& theCtx,
1536 const TCollection_AsciiString& theFolder,
1537 Standard_Boolean theToBeautify,
1538 Standard_Boolean theToReset)
1540 if (myProgramID == NO_PROGRAM)
1542 return Standard_False;
1545 TCollection_AsciiString aFolder = theFolder;
1546 if (aFolder.IsEmpty())
1548 OSD_Environment aShaderVar ("CSF_ShadersDirectoryDump");
1549 aFolder = aShaderVar.Value();
1550 if (aFolder.IsEmpty())
1556 bool hasUpdates = false;
1557 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
1559 if (!anIter.Value().IsNull())
1561 // desktop OpenGL (but not OpenGL ES) allows multiple shaders of the same stage to be attached,
1562 // but here we expect only single source per stage
1563 hasUpdates = anIter.ChangeValue()->updateDebugDump (theCtx, myResourceId, aFolder, theToBeautify, theToReset) || hasUpdates;
1568 return Link (theCtx);
1570 return Standard_False;