1 // Created on: 2013-09-19
2 // Created by: Denis BOGOLEPOV
3 // Copyright (c) 2013-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <OSD_File.hxx>
17 #include <OSD_Protection.hxx>
19 #include <Graphic3d_Buffer.hxx>
20 #include <Standard_Assert.hxx>
21 #include <Standard_Atomic.hxx>
22 #include <TCollection_ExtendedString.hxx>
24 #include <OpenGl_Context.hxx>
25 #include <OpenGl_ShaderProgram.hxx>
26 #include <OpenGl_ShaderManager.hxx>
27 #include <OpenGl_ArbTexBindless.hxx>
29 #include <OpenGl_GlCore32.hxx>
31 #include "../Shaders/Shaders_DeclarationsImpl_glsl.pxx"
32 #include "../Shaders/Shaders_Declarations_glsl.pxx"
35 #include <malloc.h> // for alloca()
38 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderProgram, OpenGl_NamedResource)
40 OpenGl_VariableSetterSelector OpenGl_ShaderProgram::mySetterSelector = OpenGl_VariableSetterSelector();
42 // Declare OCCT-specific OpenGL/GLSL shader variables
43 Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] =
45 "occModelWorldMatrix", // OpenGl_OCC_MODEL_WORLD_MATRIX
46 "occWorldViewMatrix", // OpenGl_OCC_WORLD_VIEW_MATRIX
47 "occProjectionMatrix", // OpenGl_OCC_PROJECTION_MATRIX
48 "occModelWorldMatrixInverse", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE
49 "occWorldViewMatrixInverse", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE
50 "occProjectionMatrixInverse", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE
51 "occModelWorldMatrixTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE
52 "occWorldViewMatrixTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE
53 "occProjectionMatrixTranspose", // OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE
54 "occModelWorldMatrixInverseTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE
55 "occWorldViewMatrixInverseTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE
56 "occProjectionMatrixInverseTranspose", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE
58 "occClipPlaneEquations", // OpenGl_OCC_CLIP_PLANE_EQUATIONS
59 "occClipPlaneChains", // OpenGl_OCC_CLIP_PLANE_CHAINS
60 "occClipPlaneCount", // OpenGl_OCC_CLIP_PLANE_COUNT
62 "occLightSourcesCount", // OpenGl_OCC_LIGHT_SOURCE_COUNT
63 "occLightSourcesTypes", // OpenGl_OCC_LIGHT_SOURCE_TYPES
64 "occLightSources", // OpenGl_OCC_LIGHT_SOURCE_PARAMS
65 "occLightAmbient", // OpenGl_OCC_LIGHT_AMBIENT
67 "occTextureEnable", // OpenGl_OCCT_TEXTURE_ENABLE
68 "occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE
69 "occFrontMaterial", // OpenGl_OCCT_FRONT_MATERIAL
70 "occBackMaterial", // OpenGl_OCCT_BACK_MATERIAL
71 "occAlphaCutoff", // OpenGl_OCCT_ALPHA_CUTOFF
72 "occColor", // OpenGl_OCCT_COLOR
74 "occOitOutput", // OpenGl_OCCT_OIT_OUTPUT
75 "occOitDepthFactor", // OpenGl_OCCT_OIT_DEPTH_FACTOR
77 "occTexTrsf2d", // OpenGl_OCCT_TEXTURE_TRSF2D
78 "occPointSize" // OpenGl_OCCT_POINT_SIZE
83 //! Convert Graphic3d_TypeOfShaderObject enumeration into OpenGL enumeration.
84 static GLenum shaderTypeToGl (Graphic3d_TypeOfShaderObject theType)
88 case Graphic3d_TOS_VERTEX: return GL_VERTEX_SHADER;
89 case Graphic3d_TOS_FRAGMENT: return GL_FRAGMENT_SHADER;
90 case Graphic3d_TOS_GEOMETRY: return GL_GEOMETRY_SHADER;
91 case Graphic3d_TOS_TESS_CONTROL: return GL_TESS_CONTROL_SHADER;
92 case Graphic3d_TOS_TESS_EVALUATION: return GL_TESS_EVALUATION_SHADER;
93 case Graphic3d_TOS_COMPUTE: return GL_COMPUTE_SHADER;
99 // =======================================================================
100 // function : OpenGl_VariableSetterSelector
101 // purpose : Creates new variable setter selector
102 // =======================================================================
103 OpenGl_VariableSetterSelector::OpenGl_VariableSetterSelector()
105 // Note: Add new variable setters here
106 mySetterList = OpenGl_HashMapInitializer::CreateListOf<size_t, OpenGl_SetterInterface*>
107 (Graphic3d_UniformValueTypeID<int>::ID, new OpenGl_VariableSetter<int>())
108 (Graphic3d_UniformValueTypeID<float>::ID, new OpenGl_VariableSetter<float>())
109 (Graphic3d_UniformValueTypeID<OpenGl_Vec2>::ID, new OpenGl_VariableSetter<OpenGl_Vec2>())
110 (Graphic3d_UniformValueTypeID<OpenGl_Vec3>::ID, new OpenGl_VariableSetter<OpenGl_Vec3>())
111 (Graphic3d_UniformValueTypeID<OpenGl_Vec4>::ID, new OpenGl_VariableSetter<OpenGl_Vec4>())
112 (Graphic3d_UniformValueTypeID<OpenGl_Vec2i>::ID, new OpenGl_VariableSetter<OpenGl_Vec2i>())
113 (Graphic3d_UniformValueTypeID<OpenGl_Vec3i>::ID, new OpenGl_VariableSetter<OpenGl_Vec3i>())
114 (Graphic3d_UniformValueTypeID<OpenGl_Vec4i>::ID, new OpenGl_VariableSetter<OpenGl_Vec4i>());
117 // =======================================================================
118 // function : ~OpenGl_VariableSetterSelector
119 // purpose : Releases memory resources of variable setter selector
120 // =======================================================================
121 OpenGl_VariableSetterSelector::~OpenGl_VariableSetterSelector()
123 for (OpenGl_SetterList::Iterator anIt (mySetterList); anIt.More(); anIt.Next())
128 mySetterList.Clear();
131 // =======================================================================
133 // purpose : Sets generic variable to specified shader program
134 // =======================================================================
135 void OpenGl_VariableSetterSelector::Set (const Handle(OpenGl_Context)& theCtx,
136 const Handle(Graphic3d_ShaderVariable)& theVariable,
137 OpenGl_ShaderProgram* theProgram) const
139 Standard_ASSERT_RETURN (mySetterList.IsBound (theVariable->Value()->TypeID()),
140 "The type of user-defined uniform variable is not supported...", );
142 mySetterList.Find (theVariable->Value()->TypeID())->Set (theCtx, theVariable, theProgram);
145 // =======================================================================
146 // function : OpenGl_ShaderProgram
147 // purpose : Creates uninitialized shader program
148 // =======================================================================
149 OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy)
150 : OpenGl_NamedResource (!theProxy.IsNull() ? theProxy->GetId() : ""),
151 myProgramID (NO_PROGRAM),
155 myNbClipPlanesMax (0),
157 myHasAlphaTest (false),
158 myHasWeightOitOutput (false),
159 myHasTessShader (false)
161 memset (myCurrentState, 0, sizeof (myCurrentState));
162 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
164 myStateLocations[aVar] = INVALID_LOCATION;
168 // =======================================================================
169 // function : Initialize
170 // purpose : Initializes program object with the list of shader objects
171 // =======================================================================
172 Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& theCtx,
173 const Graphic3d_ShaderObjectList& theShaders)
175 myHasTessShader = false;
176 if (theCtx.IsNull() || !Create (theCtx))
178 return Standard_False;
181 TCollection_AsciiString aHeaderVer = !myProxy.IsNull() ? myProxy->Header() : TCollection_AsciiString();
183 for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders); anIter.More(); anIter.Next())
185 aShaderMask |= anIter.Value()->Type();
187 myHasTessShader = (aShaderMask & (Graphic3d_TOS_TESS_CONTROL | Graphic3d_TOS_TESS_EVALUATION)) != 0;
188 myNbFragOutputs = !myProxy.IsNull() ? myProxy->NbFragmentOutputs() : 1;
189 myHasAlphaTest = !myProxy.IsNull() && myProxy->HasAlphaTest();
190 myHasWeightOitOutput = !myProxy.IsNull() ? myProxy->HasWeightOitOutput() && myNbFragOutputs >= 2 : 1;
192 // detect the minimum GLSL version required for defined Shader Objects
193 #if defined(GL_ES_VERSION_2_0)
195 || (aShaderMask & Graphic3d_TOS_GEOMETRY) != 0)
197 if (!theCtx->IsGlGreaterEqual (3, 2))
199 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
200 "Error! Geometry and Tessellation shaders require OpenGL ES 3.2+");
203 else if (aHeaderVer.IsEmpty())
205 aHeaderVer = "#version 320 es";
208 else if ((aShaderMask & Graphic3d_TOS_COMPUTE) != 0)
210 if (!theCtx->IsGlGreaterEqual (3, 1))
212 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
213 "Error! Compute shaders require OpenGL ES 3.1+");
216 else if (aHeaderVer.IsEmpty())
218 aHeaderVer = "#version 310 es";
222 if ((aShaderMask & Graphic3d_TOS_COMPUTE) != 0)
224 if (!theCtx->IsGlGreaterEqual (4, 3))
226 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
227 "Error! Compute shaders require OpenGL 4.3+");
230 else if (aHeaderVer.IsEmpty())
232 aHeaderVer = "#version 430";
235 else if (myHasTessShader)
237 if (!theCtx->IsGlGreaterEqual (4, 0))
239 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
240 "Error! Tessellation shaders require OpenGL 4.0+");
243 else if (aHeaderVer.IsEmpty())
245 aHeaderVer = "#version 400";
248 else if ((aShaderMask & Graphic3d_TOS_GEOMETRY) != 0)
250 if (!theCtx->IsGlGreaterEqual (3, 2))
252 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
253 "Error! Geometry shaders require OpenGL 3.2+");
256 else if (aHeaderVer.IsEmpty())
258 aHeaderVer = "#version 150";
263 for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders); anIter.More(); anIter.Next())
265 if (!anIter.Value()->IsDone())
267 const TCollection_ExtendedString aMsg = "Error! Failed to get shader source";
268 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
269 return Standard_False;
272 const GLenum aShaderType = shaderTypeToGl (anIter.Value()->Type());
273 if (aShaderType == 0)
275 return Standard_False;
278 Handle(OpenGl_ShaderObject) aShader = new OpenGl_ShaderObject (aShaderType);
279 if (!aShader->Create (theCtx))
281 aShader->Release (theCtx.operator->());
282 return Standard_False;
285 TCollection_AsciiString anExtensions = "// Enable extensions used in OCCT GLSL programs\n";
286 if (myNbFragOutputs > 1)
288 if (theCtx->hasDrawBuffers)
290 anExtensions += "#define OCC_ENABLE_draw_buffers\n";
291 if (myHasWeightOitOutput)
293 anExtensions += "#define OCC_WRITE_WEIGHT_OIT_COVERAGE\n";
298 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
299 "Error! Multiple draw buffers required by the program, but aren't supported by OpenGL");
300 return Standard_False;
303 if (theCtx->hasDrawBuffers == OpenGl_FeatureInExtensions)
305 if (theCtx->arbDrawBuffers)
307 anExtensions += "#extension GL_ARB_draw_buffers : enable\n";
309 else if (theCtx->extDrawBuffers)
311 anExtensions += "#extension GL_EXT_draw_buffers : enable\n";
317 anExtensions += "#define OCC_ALPHA_TEST\n";
320 if (theCtx->hasSampleVariables == OpenGl_FeatureInExtensions)
322 #if defined(GL_ES_VERSION_2_0)
323 if (theCtx->oesSampleVariables)
325 anExtensions += "#extension GL_OES_sample_variables : enable\n";
328 if (theCtx->arbSampleShading)
330 anExtensions += "#extension GL_ARB_sample_shading : enable\n";
335 TCollection_AsciiString aPrecisionHeader;
336 if (anIter.Value()->Type() == Graphic3d_TOS_FRAGMENT)
338 #if defined(GL_ES_VERSION_2_0)
339 aPrecisionHeader = theCtx->hasHighp
340 ? "precision highp float;\n"
341 "precision highp int;\n"
342 : "precision mediump float;\n"
343 "precision mediump int;\n";
347 TCollection_AsciiString aHeaderType;
348 switch (anIter.Value()->Type())
350 case Graphic3d_TOS_COMPUTE: { aHeaderType = "#define COMPUTE_SHADER\n"; break; }
351 case Graphic3d_TOS_VERTEX: { aHeaderType = "#define VERTEX_SHADER\n"; break; }
352 case Graphic3d_TOS_TESS_CONTROL: { aHeaderType = "#define TESS_CONTROL_SHADER\n"; break; }
353 case Graphic3d_TOS_TESS_EVALUATION: { aHeaderType = "#define TESS_EVALUATION_SHADER\n"; break; }
354 case Graphic3d_TOS_GEOMETRY: { aHeaderType = "#define GEOMETRY_SHADER\n"; break; }
355 case Graphic3d_TOS_FRAGMENT: { aHeaderType = "#define FRAGMENT_SHADER\n"; break; }
358 TCollection_AsciiString aHeaderConstants;
359 myNbLightsMax = !myProxy.IsNull() ? myProxy->NbLightsMax() : 0;
360 myNbClipPlanesMax = !myProxy.IsNull() ? myProxy->NbClipPlanesMax() : 0;
361 aHeaderConstants += TCollection_AsciiString("#define THE_MAX_LIGHTS ") + myNbLightsMax + "\n";
362 aHeaderConstants += TCollection_AsciiString("#define THE_MAX_CLIP_PLANES ") + myNbClipPlanesMax + "\n";
363 aHeaderConstants += TCollection_AsciiString("#define THE_NB_FRAG_OUTPUTS ") + myNbFragOutputs + "\n";
365 const TCollection_AsciiString aSource = aHeaderVer // #version - header defining GLSL version, should be first
366 + (!aHeaderVer.IsEmpty() ? "\n" : "")
367 + anExtensions // #extension - list of enabled extensions, should be second
368 + aPrecisionHeader // precision - default precision qualifiers, should be before any code
369 + aHeaderType // auxiliary macros defining a shader stage (type)
371 + Shaders_Declarations_glsl // common declarations (global constants and Vertex Shader inputs)
372 + Shaders_DeclarationsImpl_glsl
373 + anIter.Value()->Source(); // the source code itself (defining main() function)
374 if (!aShader->LoadAndCompile (theCtx, aSource))
376 return Standard_False;
379 if (theCtx->caps->glslDumpLevel)
381 TCollection_AsciiString aShaderTypeMsg;
382 switch (anIter.Value()->Type())
384 case Graphic3d_TOS_COMPUTE: { aShaderTypeMsg = "Compute shader source code:\n"; break; }
385 case Graphic3d_TOS_VERTEX: { aShaderTypeMsg = "Vertex shader source code:\n"; break; }
386 case Graphic3d_TOS_TESS_CONTROL: { aShaderTypeMsg = "Tesselation control shader source code:\n"; break; }
387 case Graphic3d_TOS_TESS_EVALUATION: { aShaderTypeMsg = "Tesselation evaluation shader source code:\n"; break; }
388 case Graphic3d_TOS_GEOMETRY: { aShaderTypeMsg = "Geometry shader source code:\n"; break; }
389 case Graphic3d_TOS_FRAGMENT: { aShaderTypeMsg = "Fragment shader source code:\n"; break; }
391 TCollection_AsciiString anOutputSource = aSource;
392 if (theCtx->caps->glslDumpLevel == OpenGl_ShaderProgramDumpLevel_Short)
394 anOutputSource = aHeaderVer
395 + (!aHeaderVer.IsEmpty() ? "\n" : "")
400 + anIter.Value()->Source();
402 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 0, GL_DEBUG_SEVERITY_MEDIUM,
403 TCollection_ExtendedString (aShaderTypeMsg + anOutputSource));
406 if (!AttachShader (theCtx, aShader))
408 aShader->Release (theCtx.operator->());
409 return Standard_False;
413 // bind locations for pre-defined Vertex Attributes
414 SetAttributeName (theCtx, Graphic3d_TOA_POS, "occVertex");
415 SetAttributeName (theCtx, Graphic3d_TOA_NORM, "occNormal");
416 SetAttributeName (theCtx, Graphic3d_TOA_UV, "occTexCoord");
417 SetAttributeName (theCtx, Graphic3d_TOA_COLOR, "occVertColor");
419 // bind custom Vertex Attributes
420 if (!myProxy.IsNull())
422 for (Graphic3d_ShaderAttributeList::Iterator anAttribIter (myProxy->VertexAttributes());
423 anAttribIter.More(); anAttribIter.Next())
425 SetAttributeName (theCtx, anAttribIter.Value()->Location(), anAttribIter.Value()->Name().ToCString());
431 return Standard_False;
434 // set uniform defaults
435 const Handle(OpenGl_ShaderProgram)& anOldProgram = theCtx->ActiveProgram();
436 theCtx->core20fwd->glUseProgram (myProgramID);
438 const GLint aLocTexEnable = GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE);
439 if (aLocTexEnable != INVALID_LOCATION)
441 SetUniform (theCtx, aLocTexEnable, 0); // Off
445 const GLint aLocSampler = GetUniformLocation (theCtx, "occActiveSampler");
446 if (aLocSampler != INVALID_LOCATION)
448 SetUniform (theCtx, aLocSampler, GLint(Graphic3d_TextureUnit_0));
452 const TCollection_AsciiString aSamplerNamePrefix ("occSampler");
453 const Standard_Integer aNbUnitsMax = Max (theCtx->MaxCombinedTextureUnits(), Graphic3d_TextureUnit_NB);
454 for (GLint aUnitIter = 0; aUnitIter < aNbUnitsMax; ++aUnitIter)
456 const TCollection_AsciiString aName = aSamplerNamePrefix + aUnitIter;
457 const GLint aLocSampler = GetUniformLocation (theCtx, aName.ToCString());
458 if (aLocSampler != INVALID_LOCATION)
460 SetUniform (theCtx, aLocSampler, aUnitIter);
464 theCtx->core20fwd->glUseProgram (!anOldProgram.IsNull() ? anOldProgram->ProgramId() : OpenGl_ShaderProgram::NO_PROGRAM);
465 return Standard_True;
468 // =======================================================================
469 // function : ~OpenGl_ShaderProgram
470 // purpose : Releases resources of shader program
471 // =======================================================================
472 OpenGl_ShaderProgram::~OpenGl_ShaderProgram()
477 // =======================================================================
478 // function : AttachShader
479 // purpose : Attaches shader object to the program object
480 // =======================================================================
481 Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context)& theCtx,
482 const Handle(OpenGl_ShaderObject)& theShader)
484 if (myProgramID == NO_PROGRAM || theShader.IsNull())
486 return Standard_False;
489 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
491 if (theShader == anIter.Value())
493 return Standard_False;
497 myShaderObjects.Append (theShader);
498 theCtx->core20fwd->glAttachShader (myProgramID, theShader->myShaderID);
499 return Standard_True;
502 // =======================================================================
503 // function : DetachShader
504 // purpose : Detaches shader object to the program object
505 // =======================================================================
506 Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context)& theCtx,
507 const Handle(OpenGl_ShaderObject)& theShader)
509 if (myProgramID == NO_PROGRAM
510 || theShader.IsNull())
512 return Standard_False;
515 OpenGl_ShaderList::Iterator anIter (myShaderObjects);
516 while (anIter.More())
518 if (theShader == anIter.Value())
520 myShaderObjects.Remove (anIter);
529 return Standard_False;
532 theCtx->core20fwd->glDetachShader (myProgramID, theShader->myShaderID);
533 return Standard_True;
536 // =======================================================================
538 // purpose : Links the program object
539 // =======================================================================
540 Standard_Boolean OpenGl_ShaderProgram::link (const Handle(OpenGl_Context)& theCtx)
542 if (myProgramID == NO_PROGRAM)
544 return Standard_False;
547 GLint aStatus = GL_FALSE;
548 theCtx->core20fwd->glLinkProgram (myProgramID);
549 theCtx->core20fwd->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
550 if (aStatus == GL_FALSE)
552 return Standard_False;
555 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
557 myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]);
559 return Standard_True;
562 // =======================================================================
565 // =======================================================================
566 Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx,
571 return link (theCtx);
576 TCollection_AsciiString aLog;
577 FetchInfoLog (theCtx, aLog);
580 aLog = "Linker log is empty.";
582 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
583 TCollection_AsciiString ("Failed to link program object! Linker log:\n") + aLog);
586 else if (theCtx->caps->glslWarnings)
588 TCollection_AsciiString aLog;
589 FetchInfoLog (theCtx, aLog);
591 && !aLog.IsEqual ("No errors.\n"))
593 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_LOW,
594 TCollection_AsciiString ("GLSL linker log:\n") + aLog);
600 // =======================================================================
601 // function : FetchInfoLog
602 // purpose : Fetches information log of the last link operation
603 // =======================================================================
604 Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
605 TCollection_AsciiString& theOutput)
607 if (myProgramID == NO_PROGRAM)
609 return Standard_False;
613 theCtx->core20fwd->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
616 GLchar* aLog = (GLchar*) alloca (aLength);
617 memset (aLog, 0, aLength);
618 theCtx->core20fwd->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
621 return Standard_True;
624 // =======================================================================
625 // function : ApplyVariables
626 // purpose : Fetches uniform variables from proxy shader program
627 // =======================================================================
628 Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Context)& theCtx)
630 if (myProxy.IsNull() || myProxy->Variables().IsEmpty())
632 return Standard_False;
635 for (Graphic3d_ShaderVariableList::Iterator anIter (myProxy->Variables()); anIter.More(); anIter.Next())
637 mySetterSelector.Set (theCtx, anIter.Value(), this);
640 myProxy->ClearVariables();
641 return Standard_True;
644 // =======================================================================
645 // function : GetUniformLocation
646 // purpose : Returns location (index) of the specific uniform variable
647 // =======================================================================
648 GLint OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& theCtx,
649 const GLchar* theName) const
651 return myProgramID != NO_PROGRAM
652 ? theCtx->core20fwd->glGetUniformLocation (myProgramID, theName)
656 // =======================================================================
657 // function : GetAttributeLocation
658 // purpose : Returns location (index) of the generic vertex attribute
659 // =======================================================================
660 GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)& theCtx,
661 const GLchar* theName) const
663 return myProgramID != NO_PROGRAM
664 ? theCtx->core20fwd->glGetAttribLocation (myProgramID, theName)
668 // =======================================================================
669 // function : GetStateLocation
670 // purpose : Returns location of the OCCT state uniform variable
671 // =======================================================================
672 GLint OpenGl_ShaderProgram::GetStateLocation (const GLuint theVariable) const
674 if (theVariable < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES)
676 return myStateLocations[theVariable];
678 return INVALID_LOCATION;
681 // =======================================================================
682 // function : GetUniform
683 // purpose : Returns the value of the integer uniform variable
684 // =======================================================================
685 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
686 const GLchar* theName,
687 OpenGl_Vec4i& theValue) const
689 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
692 // =======================================================================
693 // function : GetUniform
694 // purpose : Returns the value of the integer uniform variable
695 // =======================================================================
696 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
698 OpenGl_Vec4i& theValue) const
700 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
702 return Standard_False;
705 theCtx->core20fwd->glGetUniformiv (myProgramID, theLocation, theValue);
706 return Standard_True;
709 // =======================================================================
710 // function : GetUniform
711 // purpose : Returns the value of the floating-point uniform variable
712 // =======================================================================
713 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
714 const GLchar* theName,
715 OpenGl_Vec4& theValue) const
717 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
720 // =======================================================================
721 // function : GetUniform
722 // purpose : Returns the value of the floating-point uniform variable
723 // =======================================================================
724 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
726 OpenGl_Vec4& theValue) const
728 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
730 return Standard_False;
733 theCtx->core20fwd->glGetUniformfv (myProgramID, theLocation, theValue);
734 return Standard_True;
737 // =======================================================================
738 // function : GetAttribute
739 // purpose : Returns the integer vertex attribute
740 // =======================================================================
741 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
742 const GLchar* theName,
743 OpenGl_Vec4i& theValue) const
745 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
748 // =======================================================================
749 // function : GetAttribute
750 // purpose : Returns the integer vertex attribute
751 // =======================================================================
752 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
754 OpenGl_Vec4i& theValue) const
756 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
758 return Standard_False;
761 theCtx->core20fwd->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
762 return Standard_True;
765 // =======================================================================
766 // function : GetAttribute
767 // purpose : Returns the floating-point vertex attribute
768 // =======================================================================
769 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
770 const GLchar* theName,
771 OpenGl_Vec4& theValue) const
773 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
776 // =======================================================================
777 // function : GetAttribute
778 // purpose : Returns the floating-point vertex attribute
779 // =======================================================================
780 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
782 OpenGl_Vec4& theValue) const
784 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
786 return Standard_False;
789 theCtx->core20fwd->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
790 return Standard_True;
793 // =======================================================================
794 // function : SetAttributeName
796 // =======================================================================
797 Standard_Boolean OpenGl_ShaderProgram::SetAttributeName (const Handle(OpenGl_Context)& theCtx,
799 const GLchar* theName)
801 theCtx->core20fwd->glBindAttribLocation (myProgramID, theIndex, theName);
802 return Standard_True;
805 // =======================================================================
806 // function : SetAttribute
808 // =======================================================================
809 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
810 const GLchar* theName,
813 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
816 // =======================================================================
817 // function : SetAttribute
819 // =======================================================================
820 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
824 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
826 return Standard_False;
829 theCtx->core20fwd->glVertexAttrib1f (theIndex, theValue);
830 return Standard_True;
833 // =======================================================================
834 // function : SetAttribute
836 // =======================================================================
837 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
838 const GLchar* theName,
839 const OpenGl_Vec2& theValue)
841 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
844 // =======================================================================
845 // function : SetAttribute
847 // =======================================================================
848 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
850 const OpenGl_Vec2& theValue)
852 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
854 return Standard_False;
857 theCtx->core20fwd->glVertexAttrib2fv (theIndex, theValue);
858 return Standard_True;
861 // =======================================================================
862 // function : SetAttribute
864 // =======================================================================
865 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
866 const GLchar* theName,
867 const OpenGl_Vec3& theValue)
869 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
872 // =======================================================================
873 // function : SetAttribute
875 // =======================================================================
876 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
878 const OpenGl_Vec3& theValue)
880 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
882 return Standard_False;
885 theCtx->core20fwd->glVertexAttrib3fv (theIndex, theValue);
886 return Standard_True;
889 // =======================================================================
890 // function : SetAttribute
892 // =======================================================================
893 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
894 const GLchar* theName,
895 const OpenGl_Vec4& theValue)
897 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
900 // =======================================================================
901 // function : SetAttribute
903 // =======================================================================
904 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
906 const OpenGl_Vec4& theValue)
908 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
910 return Standard_False;
913 theCtx->core20fwd->glVertexAttrib4fv (theIndex, theValue);
914 return Standard_True;
917 // =======================================================================
918 // function : SetUniform
919 // purpose : Specifies the value of the integer uniform variable
920 // =======================================================================
921 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
922 const GLchar* theName,
925 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
928 // =======================================================================
929 // function : SetUniform
930 // purpose : Specifies the value of the integer uniform variable
931 // =======================================================================
932 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
936 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
938 return Standard_False;
941 theCtx->core20fwd->glUniform1i (theLocation, theValue);
942 return Standard_True;
945 // =======================================================================
946 // function : SetUniform
948 // =======================================================================
949 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
950 const GLchar* theName,
951 const OpenGl_Vec2u& theValue)
953 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
956 // =======================================================================
957 // function : SetUniform
959 // =======================================================================
960 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
962 const OpenGl_Vec2u& theValue)
964 if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
966 return Standard_False;
969 #if !defined(GL_ES_VERSION_2_0)
970 theCtx->core32->glUniform2uiv (theLocation, 1, theValue.GetData());
971 return Standard_True;
974 return Standard_False;
978 // =======================================================================
979 // function : SetUniform
981 // =======================================================================
982 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
983 const GLchar* theName,
984 const GLsizei theCount,
985 const OpenGl_Vec2u* theValue)
987 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theCount, theValue);
990 // =======================================================================
991 // function : SetUniform
993 // =======================================================================
994 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
996 const GLsizei theCount,
997 const OpenGl_Vec2u* theValue)
999 if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1001 return Standard_False;
1004 #if !defined(GL_ES_VERSION_2_0)
1005 theCtx->core32->glUniform2uiv (theLocation, theCount, theValue->GetData());
1006 return Standard_True;
1010 return Standard_False;
1014 // =======================================================================
1015 // function : SetUniform
1016 // purpose : Specifies the value of the floating-point uniform variable
1017 // =======================================================================
1018 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1019 const GLchar* theName,
1022 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1025 // =======================================================================
1026 // function : SetUniform
1027 // purpose : Specifies the value of the floating-point uniform variable
1028 // =======================================================================
1029 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1033 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1035 return Standard_False;
1038 theCtx->core20fwd->glUniform1f (theLocation, theValue);
1039 return Standard_True;
1042 // =======================================================================
1043 // function : SetUniform
1044 // purpose : Specifies the value of the integer uniform 2D vector
1045 // =======================================================================
1046 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1047 const GLchar* theName,
1048 const OpenGl_Vec2i& theValue)
1050 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1053 // =======================================================================
1054 // function : SetUniform
1055 // purpose : Specifies the value of the integer uniform 2D vector
1056 // =======================================================================
1057 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1059 const OpenGl_Vec2i& theValue)
1061 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1063 return Standard_False;
1066 theCtx->core20fwd->glUniform2iv (theLocation, 1, theValue);
1067 return Standard_True;
1070 // =======================================================================
1071 // function : SetUniform
1072 // purpose : Specifies the value of the integer uniform 3D vector
1073 // =======================================================================
1074 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1075 const GLchar* theName,
1076 const OpenGl_Vec3i& theValue)
1078 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1081 // =======================================================================
1082 // function : SetUniform
1083 // purpose : Specifies the value of the integer uniform 3D vector
1084 // =======================================================================
1085 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1087 const OpenGl_Vec3i& theValue)
1089 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1091 return Standard_False;
1094 theCtx->core20fwd->glUniform3iv (theLocation, 1, theValue);
1095 return Standard_True;
1098 // =======================================================================
1099 // function : SetUniform
1100 // purpose : Specifies the value of the integer uniform 4D vector
1101 // =======================================================================
1102 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1103 const GLchar* theName,
1104 const OpenGl_Vec4i& theValue)
1106 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1109 // =======================================================================
1110 // function : SetUniform
1111 // purpose : Specifies the value of the integer uniform 4D vector
1112 // =======================================================================
1113 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1115 const OpenGl_Vec4i& theValue)
1117 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1119 return Standard_False;
1122 theCtx->core20fwd->glUniform4iv (theLocation, 1, theValue);
1123 return Standard_True;
1126 // =======================================================================
1127 // function : SetUniform
1128 // purpose : Specifies the value of the floating-point uniform 2D vector
1129 // =======================================================================
1130 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1131 const GLchar* theName,
1132 const OpenGl_Vec2& theValue)
1134 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1137 // =======================================================================
1138 // function : SetUniform
1139 // purpose : Specifies the value of the floating-point uniform 2D vector
1140 // =======================================================================
1141 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1143 const OpenGl_Vec2& theValue)
1145 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1147 return Standard_False;
1150 theCtx->core20fwd->glUniform2fv (theLocation, 1, theValue);
1151 return Standard_True;
1154 // =======================================================================
1155 // function : SetUniform
1156 // purpose : Specifies the value of the floating-point uniform 3D vector
1157 // =======================================================================
1158 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1159 const GLchar* theName,
1160 const OpenGl_Vec3& theValue)
1162 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1165 // =======================================================================
1166 // function : SetUniform
1167 // purpose : Specifies the value of the floating-point uniform 3D vector
1168 // =======================================================================
1169 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1171 const OpenGl_Vec3& theValue)
1173 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1175 return Standard_False;
1178 theCtx->core20fwd->glUniform3fv (theLocation, 1, theValue);
1179 return Standard_True;
1182 // =======================================================================
1183 // function : SetUniform
1184 // purpose : Specifies the value of the floating-point uniform 4D vector
1185 // =======================================================================
1186 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1187 const GLchar* theName,
1188 const OpenGl_Vec4& theValue)
1190 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1193 // =======================================================================
1194 // function : SetUniform
1195 // purpose : Specifies the value of the floating-point uniform 4D vector
1196 // =======================================================================
1197 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1199 const OpenGl_Vec4& theValue)
1201 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1203 return Standard_False;
1206 theCtx->core20fwd->glUniform4fv (theLocation, 1, theValue);
1207 return Standard_True;
1210 // =======================================================================
1211 // function : SetUniform
1212 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1213 // =======================================================================
1214 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1215 const GLchar* theName,
1216 const OpenGl_Mat4& theValue,
1217 GLboolean theTranspose)
1219 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1222 // =======================================================================
1223 // function : SetUniform
1224 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1225 // =======================================================================
1226 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1228 const OpenGl_Mat4& theValue,
1229 GLboolean theTranspose)
1231 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1233 return Standard_False;
1236 theCtx->core20fwd->glUniformMatrix4fv (theLocation, 1, GL_FALSE, theTranspose ? theValue.Transposed() : theValue);
1237 return Standard_True;
1240 // =======================================================================
1241 // function : SetUniform
1242 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1243 // =======================================================================
1244 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1245 const GLchar* theName,
1246 const OpenGl_Matrix& theValue,
1247 GLboolean theTranspose)
1249 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1252 // =======================================================================
1253 // function : SetUniform
1254 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1255 // =======================================================================
1256 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1258 const OpenGl_Matrix& theValue,
1259 GLboolean theTranspose)
1261 return SetUniform (theCtx, theLocation, OpenGl_Mat4::Map (*theValue.mat), theTranspose);
1264 // =======================================================================
1265 // function : SetUniform
1266 // purpose : Specifies the value of the float uniform array
1267 // =======================================================================
1268 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1271 const Standard_ShortReal* theData)
1273 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1275 return Standard_False;
1278 theCtx->core20fwd->glUniform1fv (theLocation, theCount, theData);
1279 return Standard_True;
1282 // =======================================================================
1283 // function : SetUniform
1284 // purpose : Specifies the value of the float2 uniform array
1285 // =======================================================================
1286 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1289 const OpenGl_Vec2* theData)
1291 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1293 return Standard_False;
1296 theCtx->core20fwd->glUniform2fv (theLocation, theCount, theData[0].GetData());
1297 return Standard_True;
1300 // =======================================================================
1301 // function : SetUniform
1302 // purpose : Specifies the value of the float3 uniform array
1303 // =======================================================================
1304 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1307 const OpenGl_Vec3* theData)
1309 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1311 return Standard_False;
1314 theCtx->core20fwd->glUniform3fv (theLocation, theCount, theData[0].GetData());
1315 return Standard_True;
1318 // =======================================================================
1319 // function : SetUniform
1320 // purpose : Specifies the value of the float4 uniform array
1321 // =======================================================================
1322 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1325 const OpenGl_Vec4* theData)
1327 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1329 return Standard_False;
1332 theCtx->core20fwd->glUniform4fv (theLocation, theCount, theData[0].GetData());
1333 return Standard_True;
1336 // =======================================================================
1337 // function : SetUniform
1338 // purpose : Specifies the value of the integer uniform array
1339 // =======================================================================
1340 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1343 const Standard_Integer* theData)
1345 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1347 return Standard_False;
1350 theCtx->core20fwd->glUniform1iv (theLocation, theCount, theData);
1351 return Standard_True;
1354 // =======================================================================
1355 // function : SetUniform
1356 // purpose : Specifies the value of the int2 uniform array
1357 // =======================================================================
1358 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1361 const OpenGl_Vec2i* theData)
1363 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1365 return Standard_False;
1368 theCtx->core20fwd->glUniform2iv (theLocation, theCount, theData[0].GetData());
1369 return Standard_True;
1372 // =======================================================================
1373 // function : SetUniform
1374 // purpose : Specifies the value of the int3 uniform array
1375 // =======================================================================
1376 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1379 const OpenGl_Vec3i* theData)
1381 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1383 return Standard_False;
1386 theCtx->core20fwd->glUniform3iv (theLocation, theCount, theData[0].GetData());
1387 return Standard_True;
1390 // =======================================================================
1391 // function : SetUniform
1392 // purpose : Specifies the value of the int4 uniform array
1393 // =======================================================================
1394 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1397 const OpenGl_Vec4i* theData)
1399 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1401 return Standard_False;
1404 theCtx->core20fwd->glUniform4iv (theLocation, theCount, theData[0].GetData());
1405 return Standard_True;
1408 // =======================================================================
1409 // function : SetSampler
1410 // purpose : Specifies the value of the sampler uniform variable
1411 // =======================================================================
1412 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1413 const GLchar* theName,
1414 const Graphic3d_TextureUnit theTextureUnit)
1416 return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit);
1419 // =======================================================================
1420 // function : SetSampler
1421 // purpose : Specifies the value of the sampler uniform variable
1422 // =======================================================================
1423 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1425 const Graphic3d_TextureUnit theTextureUnit)
1427 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1429 return Standard_False;
1432 theCtx->core20fwd->glUniform1i (theLocation, theTextureUnit);
1433 return Standard_True;
1436 // =======================================================================
1437 // function : Create
1438 // purpose : Creates new empty shader program of specified type
1439 // =======================================================================
1440 Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx)
1442 if (myProgramID == NO_PROGRAM
1443 && theCtx->core20fwd != NULL)
1445 myProgramID = theCtx->core20fwd->glCreateProgram();
1448 return myProgramID != NO_PROGRAM;
1451 // =======================================================================
1452 // function : Release
1453 // purpose : Destroys shader program
1454 // =======================================================================
1455 void OpenGl_ShaderProgram::Release (OpenGl_Context* theCtx)
1457 if (myProgramID == NO_PROGRAM)
1462 Standard_ASSERT_RETURN (theCtx != NULL,
1463 "OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...",);
1465 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
1467 if (!anIter.Value().IsNull())
1469 anIter.ChangeValue()->Release (theCtx);
1470 anIter.ChangeValue().Nullify();
1474 if (theCtx->core20fwd != NULL
1475 && theCtx->IsValid())
1477 theCtx->core20fwd->glDeleteProgram (myProgramID);
1480 myProgramID = NO_PROGRAM;