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->LoadSource (theCtx, aSource))
376 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aSource);
377 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, "Error! Failed to set shader source");
378 aShader->Release (theCtx.operator->());
379 return Standard_False;
382 if (!aShader->Compile (theCtx))
384 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aSource);
385 TCollection_AsciiString aLog;
386 aShader->FetchInfoLog (theCtx, aLog);
389 aLog = "Compilation log is empty.";
391 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
392 TCollection_ExtendedString ("Failed to compile shader object. Compilation log:\n") + aLog);
393 aShader->Release (theCtx.operator->());
394 return Standard_False;
396 else if (theCtx->caps->glslWarnings)
398 TCollection_AsciiString aLog;
399 aShader->FetchInfoLog (theCtx, aLog);
401 && !aLog.IsEqual ("No errors.\n"))
403 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_LOW,
404 TCollection_ExtendedString ("Shader compilation log:\n") + aLog);
408 if (!AttachShader (theCtx, aShader))
410 aShader->Release (theCtx.operator->());
411 return Standard_False;
415 // bind locations for pre-defined Vertex Attributes
416 SetAttributeName (theCtx, Graphic3d_TOA_POS, "occVertex");
417 SetAttributeName (theCtx, Graphic3d_TOA_NORM, "occNormal");
418 SetAttributeName (theCtx, Graphic3d_TOA_UV, "occTexCoord");
419 SetAttributeName (theCtx, Graphic3d_TOA_COLOR, "occVertColor");
421 // bind custom Vertex Attributes
422 if (!myProxy.IsNull())
424 for (Graphic3d_ShaderAttributeList::Iterator anAttribIter (myProxy->VertexAttributes());
425 anAttribIter.More(); anAttribIter.Next())
427 SetAttributeName (theCtx, anAttribIter.Value()->Location(), anAttribIter.Value()->Name().ToCString());
433 TCollection_AsciiString aLog;
434 FetchInfoLog (theCtx, aLog);
437 aLog = "Linker log is empty.";
439 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
440 TCollection_ExtendedString ("Failed to link program object! Linker log:\n") + aLog);
441 return Standard_False;
443 else if (theCtx->caps->glslWarnings)
445 TCollection_AsciiString aLog;
446 FetchInfoLog (theCtx, aLog);
448 && !aLog.IsEqual ("No errors.\n"))
450 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_LOW,
451 TCollection_ExtendedString ("GLSL linker log:\n") + aLog);
455 // set uniform defaults
456 const Handle(OpenGl_ShaderProgram)& anOldProgram = theCtx->ActiveProgram();
457 theCtx->core20fwd->glUseProgram (myProgramID);
459 const GLint aLocTexEnable = GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE);
460 if (aLocTexEnable != INVALID_LOCATION)
462 SetUniform (theCtx, aLocTexEnable, 0); // Off
466 const GLint aLocSampler = GetUniformLocation (theCtx, "occActiveSampler");
467 if (aLocSampler != INVALID_LOCATION)
469 SetUniform (theCtx, aLocSampler, GLint(Graphic3d_TextureUnit_0));
473 const TCollection_AsciiString aSamplerNamePrefix ("occSampler");
474 const Standard_Integer aNbUnitsMax = Max (theCtx->MaxCombinedTextureUnits(), Graphic3d_TextureUnit_NB);
475 for (GLint aUnitIter = 0; aUnitIter < aNbUnitsMax; ++aUnitIter)
477 const TCollection_AsciiString aName = aSamplerNamePrefix + aUnitIter;
478 const GLint aLocSampler = GetUniformLocation (theCtx, aName.ToCString());
479 if (aLocSampler != INVALID_LOCATION)
481 SetUniform (theCtx, aLocSampler, aUnitIter);
485 theCtx->core20fwd->glUseProgram (!anOldProgram.IsNull() ? anOldProgram->ProgramId() : OpenGl_ShaderProgram::NO_PROGRAM);
486 return Standard_True;
489 // =======================================================================
490 // function : ~OpenGl_ShaderProgram
491 // purpose : Releases resources of shader program
492 // =======================================================================
493 OpenGl_ShaderProgram::~OpenGl_ShaderProgram()
498 // =======================================================================
499 // function : AttachShader
500 // purpose : Attaches shader object to the program object
501 // =======================================================================
502 Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context)& theCtx,
503 const Handle(OpenGl_ShaderObject)& theShader)
505 if (myProgramID == NO_PROGRAM || theShader.IsNull())
507 return Standard_False;
510 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
512 if (theShader == anIter.Value())
514 return Standard_False;
518 myShaderObjects.Append (theShader);
519 theCtx->core20fwd->glAttachShader (myProgramID, theShader->myShaderID);
520 return Standard_True;
523 // =======================================================================
524 // function : DetachShader
525 // purpose : Detaches shader object to the program object
526 // =======================================================================
527 Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context)& theCtx,
528 const Handle(OpenGl_ShaderObject)& theShader)
530 if (myProgramID == NO_PROGRAM
531 || theShader.IsNull())
533 return Standard_False;
536 OpenGl_ShaderList::Iterator anIter (myShaderObjects);
537 while (anIter.More())
539 if (theShader == anIter.Value())
541 myShaderObjects.Remove (anIter);
550 return Standard_False;
553 theCtx->core20fwd->glDetachShader (myProgramID, theShader->myShaderID);
554 return Standard_True;
557 // =======================================================================
559 // purpose : Links the program object
560 // =======================================================================
561 Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx)
563 if (myProgramID == NO_PROGRAM)
565 return Standard_False;
568 GLint aStatus = GL_FALSE;
569 theCtx->core20fwd->glLinkProgram (myProgramID);
570 theCtx->core20fwd->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
571 if (aStatus == GL_FALSE)
573 return Standard_False;
576 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
578 myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]);
580 return Standard_True;
583 // =======================================================================
584 // function : FetchInfoLog
585 // purpose : Fetches information log of the last link operation
586 // =======================================================================
587 Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
588 TCollection_AsciiString& theOutput)
590 if (myProgramID == NO_PROGRAM)
592 return Standard_False;
596 theCtx->core20fwd->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
599 GLchar* aLog = (GLchar*) alloca (aLength);
600 memset (aLog, 0, aLength);
601 theCtx->core20fwd->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
604 return Standard_True;
607 // =======================================================================
608 // function : ApplyVariables
609 // purpose : Fetches uniform variables from proxy shader program
610 // =======================================================================
611 Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Context)& theCtx)
613 if (myProxy.IsNull() || myProxy->Variables().IsEmpty())
615 return Standard_False;
618 for (Graphic3d_ShaderVariableList::Iterator anIter (myProxy->Variables()); anIter.More(); anIter.Next())
620 mySetterSelector.Set (theCtx, anIter.Value(), this);
623 myProxy->ClearVariables();
624 return Standard_True;
627 // =======================================================================
628 // function : GetUniformLocation
629 // purpose : Returns location (index) of the specific uniform variable
630 // =======================================================================
631 GLint OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& theCtx,
632 const GLchar* theName) const
634 return myProgramID != NO_PROGRAM
635 ? theCtx->core20fwd->glGetUniformLocation (myProgramID, theName)
639 // =======================================================================
640 // function : GetAttributeLocation
641 // purpose : Returns location (index) of the generic vertex attribute
642 // =======================================================================
643 GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)& theCtx,
644 const GLchar* theName) const
646 return myProgramID != NO_PROGRAM
647 ? theCtx->core20fwd->glGetAttribLocation (myProgramID, theName)
651 // =======================================================================
652 // function : GetStateLocation
653 // purpose : Returns location of the OCCT state uniform variable
654 // =======================================================================
655 GLint OpenGl_ShaderProgram::GetStateLocation (const GLuint theVariable) const
657 if (theVariable < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES)
659 return myStateLocations[theVariable];
661 return INVALID_LOCATION;
664 // =======================================================================
665 // function : GetUniform
666 // purpose : Returns the value of the integer uniform variable
667 // =======================================================================
668 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
669 const GLchar* theName,
670 OpenGl_Vec4i& theValue) const
672 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
675 // =======================================================================
676 // function : GetUniform
677 // purpose : Returns the value of the integer uniform variable
678 // =======================================================================
679 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
681 OpenGl_Vec4i& theValue) const
683 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
685 return Standard_False;
688 theCtx->core20fwd->glGetUniformiv (myProgramID, theLocation, theValue);
689 return Standard_True;
692 // =======================================================================
693 // function : GetUniform
694 // purpose : Returns the value of the floating-point uniform variable
695 // =======================================================================
696 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
697 const GLchar* theName,
698 OpenGl_Vec4& theValue) const
700 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
703 // =======================================================================
704 // function : GetUniform
705 // purpose : Returns the value of the floating-point uniform variable
706 // =======================================================================
707 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
709 OpenGl_Vec4& theValue) const
711 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
713 return Standard_False;
716 theCtx->core20fwd->glGetUniformfv (myProgramID, theLocation, theValue);
717 return Standard_True;
720 // =======================================================================
721 // function : GetAttribute
722 // purpose : Returns the integer vertex attribute
723 // =======================================================================
724 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
725 const GLchar* theName,
726 OpenGl_Vec4i& theValue) const
728 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
731 // =======================================================================
732 // function : GetAttribute
733 // purpose : Returns the integer vertex attribute
734 // =======================================================================
735 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
737 OpenGl_Vec4i& theValue) const
739 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
741 return Standard_False;
744 theCtx->core20fwd->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
745 return Standard_True;
748 // =======================================================================
749 // function : GetAttribute
750 // purpose : Returns the floating-point vertex attribute
751 // =======================================================================
752 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
753 const GLchar* theName,
754 OpenGl_Vec4& theValue) const
756 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
759 // =======================================================================
760 // function : GetAttribute
761 // purpose : Returns the floating-point vertex attribute
762 // =======================================================================
763 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
765 OpenGl_Vec4& theValue) const
767 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
769 return Standard_False;
772 theCtx->core20fwd->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
773 return Standard_True;
776 // =======================================================================
777 // function : SetAttributeName
779 // =======================================================================
780 Standard_Boolean OpenGl_ShaderProgram::SetAttributeName (const Handle(OpenGl_Context)& theCtx,
782 const GLchar* theName)
784 theCtx->core20fwd->glBindAttribLocation (myProgramID, theIndex, theName);
785 return Standard_True;
788 // =======================================================================
789 // function : SetAttribute
791 // =======================================================================
792 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
793 const GLchar* theName,
796 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
799 // =======================================================================
800 // function : SetAttribute
802 // =======================================================================
803 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
807 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
809 return Standard_False;
812 theCtx->core20fwd->glVertexAttrib1f (theIndex, theValue);
813 return Standard_True;
816 // =======================================================================
817 // function : SetAttribute
819 // =======================================================================
820 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
821 const GLchar* theName,
822 const OpenGl_Vec2& theValue)
824 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
827 // =======================================================================
828 // function : SetAttribute
830 // =======================================================================
831 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
833 const OpenGl_Vec2& theValue)
835 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
837 return Standard_False;
840 theCtx->core20fwd->glVertexAttrib2fv (theIndex, theValue);
841 return Standard_True;
844 // =======================================================================
845 // function : SetAttribute
847 // =======================================================================
848 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
849 const GLchar* theName,
850 const OpenGl_Vec3& theValue)
852 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
855 // =======================================================================
856 // function : SetAttribute
858 // =======================================================================
859 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
861 const OpenGl_Vec3& theValue)
863 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
865 return Standard_False;
868 theCtx->core20fwd->glVertexAttrib3fv (theIndex, theValue);
869 return Standard_True;
872 // =======================================================================
873 // function : SetAttribute
875 // =======================================================================
876 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
877 const GLchar* theName,
878 const OpenGl_Vec4& theValue)
880 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
883 // =======================================================================
884 // function : SetAttribute
886 // =======================================================================
887 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
889 const OpenGl_Vec4& theValue)
891 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
893 return Standard_False;
896 theCtx->core20fwd->glVertexAttrib4fv (theIndex, theValue);
897 return Standard_True;
900 // =======================================================================
901 // function : SetUniform
902 // purpose : Specifies the value of the integer uniform variable
903 // =======================================================================
904 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
905 const GLchar* theName,
908 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
911 // =======================================================================
912 // function : SetUniform
913 // purpose : Specifies the value of the integer uniform variable
914 // =======================================================================
915 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
919 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
921 return Standard_False;
924 theCtx->core20fwd->glUniform1i (theLocation, theValue);
925 return Standard_True;
928 // =======================================================================
929 // function : SetUniform
931 // =======================================================================
932 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
933 const GLchar* theName,
934 const OpenGl_Vec2u& theValue)
936 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
939 // =======================================================================
940 // function : SetUniform
942 // =======================================================================
943 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
945 const OpenGl_Vec2u& theValue)
947 if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
949 return Standard_False;
952 #if !defined(GL_ES_VERSION_2_0)
953 theCtx->core32->glUniform2uiv (theLocation, 1, theValue.GetData());
954 return Standard_True;
957 return Standard_False;
961 // =======================================================================
962 // function : SetUniform
964 // =======================================================================
965 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
966 const GLchar* theName,
967 const GLsizei theCount,
968 const OpenGl_Vec2u* theValue)
970 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theCount, theValue);
973 // =======================================================================
974 // function : SetUniform
976 // =======================================================================
977 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
979 const GLsizei theCount,
980 const OpenGl_Vec2u* theValue)
982 if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
984 return Standard_False;
987 #if !defined(GL_ES_VERSION_2_0)
988 theCtx->core32->glUniform2uiv (theLocation, theCount, theValue->GetData());
989 return Standard_True;
993 return Standard_False;
997 // =======================================================================
998 // function : SetUniform
999 // purpose : Specifies the value of the floating-point uniform variable
1000 // =======================================================================
1001 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1002 const GLchar* theName,
1005 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1008 // =======================================================================
1009 // function : SetUniform
1010 // purpose : Specifies the value of the floating-point uniform variable
1011 // =======================================================================
1012 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1016 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1018 return Standard_False;
1021 theCtx->core20fwd->glUniform1f (theLocation, theValue);
1022 return Standard_True;
1025 // =======================================================================
1026 // function : SetUniform
1027 // purpose : Specifies the value of the integer uniform 2D vector
1028 // =======================================================================
1029 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1030 const GLchar* theName,
1031 const OpenGl_Vec2i& theValue)
1033 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1036 // =======================================================================
1037 // function : SetUniform
1038 // purpose : Specifies the value of the integer uniform 2D vector
1039 // =======================================================================
1040 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1042 const OpenGl_Vec2i& theValue)
1044 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1046 return Standard_False;
1049 theCtx->core20fwd->glUniform2iv (theLocation, 1, theValue);
1050 return Standard_True;
1053 // =======================================================================
1054 // function : SetUniform
1055 // purpose : Specifies the value of the integer uniform 3D vector
1056 // =======================================================================
1057 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1058 const GLchar* theName,
1059 const OpenGl_Vec3i& theValue)
1061 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1064 // =======================================================================
1065 // function : SetUniform
1066 // purpose : Specifies the value of the integer uniform 3D vector
1067 // =======================================================================
1068 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1070 const OpenGl_Vec3i& theValue)
1072 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1074 return Standard_False;
1077 theCtx->core20fwd->glUniform3iv (theLocation, 1, theValue);
1078 return Standard_True;
1081 // =======================================================================
1082 // function : SetUniform
1083 // purpose : Specifies the value of the integer uniform 4D vector
1084 // =======================================================================
1085 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1086 const GLchar* theName,
1087 const OpenGl_Vec4i& theValue)
1089 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1092 // =======================================================================
1093 // function : SetUniform
1094 // purpose : Specifies the value of the integer uniform 4D vector
1095 // =======================================================================
1096 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1098 const OpenGl_Vec4i& theValue)
1100 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1102 return Standard_False;
1105 theCtx->core20fwd->glUniform4iv (theLocation, 1, theValue);
1106 return Standard_True;
1109 // =======================================================================
1110 // function : SetUniform
1111 // purpose : Specifies the value of the floating-point uniform 2D vector
1112 // =======================================================================
1113 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1114 const GLchar* theName,
1115 const OpenGl_Vec2& theValue)
1117 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1120 // =======================================================================
1121 // function : SetUniform
1122 // purpose : Specifies the value of the floating-point uniform 2D vector
1123 // =======================================================================
1124 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1126 const OpenGl_Vec2& theValue)
1128 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1130 return Standard_False;
1133 theCtx->core20fwd->glUniform2fv (theLocation, 1, theValue);
1134 return Standard_True;
1137 // =======================================================================
1138 // function : SetUniform
1139 // purpose : Specifies the value of the floating-point uniform 3D vector
1140 // =======================================================================
1141 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1142 const GLchar* theName,
1143 const OpenGl_Vec3& theValue)
1145 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1148 // =======================================================================
1149 // function : SetUniform
1150 // purpose : Specifies the value of the floating-point uniform 3D vector
1151 // =======================================================================
1152 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1154 const OpenGl_Vec3& theValue)
1156 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1158 return Standard_False;
1161 theCtx->core20fwd->glUniform3fv (theLocation, 1, theValue);
1162 return Standard_True;
1165 // =======================================================================
1166 // function : SetUniform
1167 // purpose : Specifies the value of the floating-point uniform 4D vector
1168 // =======================================================================
1169 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1170 const GLchar* theName,
1171 const OpenGl_Vec4& theValue)
1173 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1176 // =======================================================================
1177 // function : SetUniform
1178 // purpose : Specifies the value of the floating-point uniform 4D vector
1179 // =======================================================================
1180 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1182 const OpenGl_Vec4& theValue)
1184 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1186 return Standard_False;
1189 theCtx->core20fwd->glUniform4fv (theLocation, 1, theValue);
1190 return Standard_True;
1193 // =======================================================================
1194 // function : SetUniform
1195 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1196 // =======================================================================
1197 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1198 const GLchar* theName,
1199 const OpenGl_Mat4& theValue,
1200 GLboolean theTranspose)
1202 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1205 // =======================================================================
1206 // function : SetUniform
1207 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1208 // =======================================================================
1209 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1211 const OpenGl_Mat4& theValue,
1212 GLboolean theTranspose)
1214 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1216 return Standard_False;
1219 theCtx->core20fwd->glUniformMatrix4fv (theLocation, 1, GL_FALSE, theTranspose ? theValue.Transposed() : theValue);
1220 return Standard_True;
1223 // =======================================================================
1224 // function : SetUniform
1225 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1226 // =======================================================================
1227 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1228 const GLchar* theName,
1229 const OpenGl_Matrix& theValue,
1230 GLboolean theTranspose)
1232 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1235 // =======================================================================
1236 // function : SetUniform
1237 // purpose : Specifies the value of the floating-point uniform 4x4 matrix
1238 // =======================================================================
1239 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1241 const OpenGl_Matrix& theValue,
1242 GLboolean theTranspose)
1244 return SetUniform (theCtx, theLocation, OpenGl_Mat4::Map (*theValue.mat), theTranspose);
1247 // =======================================================================
1248 // function : SetUniform
1249 // purpose : Specifies the value of the float uniform array
1250 // =======================================================================
1251 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1254 const Standard_ShortReal* theData)
1256 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1258 return Standard_False;
1261 theCtx->core20fwd->glUniform1fv (theLocation, theCount, theData);
1262 return Standard_True;
1265 // =======================================================================
1266 // function : SetUniform
1267 // purpose : Specifies the value of the float2 uniform array
1268 // =======================================================================
1269 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1272 const OpenGl_Vec2* theData)
1274 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1276 return Standard_False;
1279 theCtx->core20fwd->glUniform2fv (theLocation, theCount, theData[0].GetData());
1280 return Standard_True;
1283 // =======================================================================
1284 // function : SetUniform
1285 // purpose : Specifies the value of the float3 uniform array
1286 // =======================================================================
1287 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1290 const OpenGl_Vec3* theData)
1292 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1294 return Standard_False;
1297 theCtx->core20fwd->glUniform3fv (theLocation, theCount, theData[0].GetData());
1298 return Standard_True;
1301 // =======================================================================
1302 // function : SetUniform
1303 // purpose : Specifies the value of the float4 uniform array
1304 // =======================================================================
1305 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1308 const OpenGl_Vec4* theData)
1310 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1312 return Standard_False;
1315 theCtx->core20fwd->glUniform4fv (theLocation, theCount, theData[0].GetData());
1316 return Standard_True;
1319 // =======================================================================
1320 // function : SetUniform
1321 // purpose : Specifies the value of the integer uniform array
1322 // =======================================================================
1323 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1326 const Standard_Integer* theData)
1328 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1330 return Standard_False;
1333 theCtx->core20fwd->glUniform1iv (theLocation, theCount, theData);
1334 return Standard_True;
1337 // =======================================================================
1338 // function : SetUniform
1339 // purpose : Specifies the value of the int2 uniform array
1340 // =======================================================================
1341 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1344 const OpenGl_Vec2i* theData)
1346 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1348 return Standard_False;
1351 theCtx->core20fwd->glUniform2iv (theLocation, theCount, theData[0].GetData());
1352 return Standard_True;
1355 // =======================================================================
1356 // function : SetUniform
1357 // purpose : Specifies the value of the int3 uniform array
1358 // =======================================================================
1359 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1362 const OpenGl_Vec3i* theData)
1364 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1366 return Standard_False;
1369 theCtx->core20fwd->glUniform3iv (theLocation, theCount, theData[0].GetData());
1370 return Standard_True;
1373 // =======================================================================
1374 // function : SetUniform
1375 // purpose : Specifies the value of the int4 uniform array
1376 // =======================================================================
1377 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1380 const OpenGl_Vec4i* theData)
1382 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1384 return Standard_False;
1387 theCtx->core20fwd->glUniform4iv (theLocation, theCount, theData[0].GetData());
1388 return Standard_True;
1391 // =======================================================================
1392 // function : SetSampler
1393 // purpose : Specifies the value of the sampler uniform variable
1394 // =======================================================================
1395 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1396 const GLchar* theName,
1397 const Graphic3d_TextureUnit theTextureUnit)
1399 return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit);
1402 // =======================================================================
1403 // function : SetSampler
1404 // purpose : Specifies the value of the sampler uniform variable
1405 // =======================================================================
1406 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1408 const Graphic3d_TextureUnit theTextureUnit)
1410 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1412 return Standard_False;
1415 theCtx->core20fwd->glUniform1i (theLocation, theTextureUnit);
1416 return Standard_True;
1419 // =======================================================================
1420 // function : Create
1421 // purpose : Creates new empty shader program of specified type
1422 // =======================================================================
1423 Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx)
1425 if (myProgramID == NO_PROGRAM
1426 && theCtx->core20fwd != NULL)
1428 myProgramID = theCtx->core20fwd->glCreateProgram();
1431 return myProgramID != NO_PROGRAM;
1434 // =======================================================================
1435 // function : Release
1436 // purpose : Destroys shader program
1437 // =======================================================================
1438 void OpenGl_ShaderProgram::Release (OpenGl_Context* theCtx)
1440 if (myProgramID == NO_PROGRAM)
1445 Standard_ASSERT_RETURN (theCtx != NULL,
1446 "OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...",);
1448 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
1450 if (!anIter.Value().IsNull())
1452 anIter.ChangeValue()->Release (theCtx);
1453 anIter.ChangeValue().Nullify();
1457 if (theCtx->core20fwd != NULL
1458 && theCtx->IsValid())
1460 theCtx->core20fwd->glDeleteProgram (myProgramID);
1463 myProgramID = NO_PROGRAM;