0029337: Visualization, TKOpenGl - visual artifacts on Intel Broadwell GPU
[occt.git] / src / OpenGl / OpenGl_ShaderProgram.cxx
CommitLineData
30f0ad28 1// Created on: 2013-09-19
2// Created by: Denis BOGOLEPOV
d5f74e42 3// Copyright (c) 2013-2014 OPEN CASCADE SAS
30f0ad28 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
30f0ad28 6//
d5f74e42 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
973c2be1 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.
30f0ad28 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
30f0ad28 15
16#include <OSD_File.hxx>
17#include <OSD_Protection.hxx>
18
7d3e64ef 19#include <Graphic3d_Buffer.hxx>
30f0ad28 20#include <Standard_Assert.hxx>
21#include <Standard_Atomic.hxx>
22#include <TCollection_ExtendedString.hxx>
23
24#include <OpenGl_Context.hxx>
25#include <OpenGl_ShaderProgram.hxx>
26#include <OpenGl_ShaderManager.hxx>
25ef750e 27#include <OpenGl_ArbTexBindless.hxx>
30f0ad28 28
47e9c178 29#include <OpenGl_GlCore32.hxx>
30f0ad28 30
ee5befae 31#include "../Shaders/Shaders_DeclarationsImpl_glsl.pxx"
32#include "../Shaders/Shaders_Declarations_glsl.pxx"
33
7c65581d 34#ifdef _WIN32
35 #include <malloc.h> // for alloca()
36#endif
37
cc8cbabe 38IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderProgram, OpenGl_NamedResource)
92efcf78 39
30f0ad28 40OpenGl_VariableSetterSelector OpenGl_ShaderProgram::mySetterSelector = OpenGl_VariableSetterSelector();
41
42// Declare OCCT-specific OpenGL/GLSL shader variables
43Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] =
44{
12381341 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
57
58 "occClipPlaneEquations", // OpenGl_OCC_CLIP_PLANE_EQUATIONS
5495fa7e 59 "occClipPlaneCount", // OpenGl_OCC_CLIP_PLANE_COUNT
12381341 60
61 "occLightSourcesCount", // OpenGl_OCC_LIGHT_SOURCE_COUNT
62 "occLightSourcesTypes", // OpenGl_OCC_LIGHT_SOURCE_TYPES
63 "occLightSources", // OpenGl_OCC_LIGHT_SOURCE_PARAMS
64 "occLightAmbient", // OpenGl_OCC_LIGHT_AMBIENT
65
12381341 66 "occTextureEnable", // OpenGl_OCCT_TEXTURE_ENABLE
67 "occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE
68 "occFrontMaterial", // OpenGl_OCCT_FRONT_MATERIAL
8625ef7e 69 "occBackMaterial", // OpenGl_OCCT_BACK_MATERIAL
70 "occColor", // OpenGl_OCCT_COLOR
71
a1073ae2 72 "occOitOutput", // OpenGl_OCCT_OIT_OUTPUT
73 "occOitDepthFactor", // OpenGl_OCCT_OIT_DEPTH_FACTOR
74
79f4f036 75 "occTexTrsf2d", // OpenGl_OCCT_TEXTURE_TRSF2D
8625ef7e 76 "occPointSize" // OpenGl_OCCT_POINT_SIZE
30f0ad28 77};
78
8e0a2b19 79namespace
80{
81 //! Convert Graphic3d_TypeOfShaderObject enumeration into OpenGL enumeration.
82 static GLenum shaderTypeToGl (Graphic3d_TypeOfShaderObject theType)
83 {
84 switch (theType)
85 {
86 case Graphic3d_TOS_VERTEX: return GL_VERTEX_SHADER;
87 case Graphic3d_TOS_FRAGMENT: return GL_FRAGMENT_SHADER;
88 case Graphic3d_TOS_GEOMETRY: return GL_GEOMETRY_SHADER;
89 case Graphic3d_TOS_TESS_CONTROL: return GL_TESS_CONTROL_SHADER;
90 case Graphic3d_TOS_TESS_EVALUATION: return GL_TESS_EVALUATION_SHADER;
91 case Graphic3d_TOS_COMPUTE: return GL_COMPUTE_SHADER;
92 }
93 return 0;
94 }
95}
96
30f0ad28 97// =======================================================================
98// function : OpenGl_VariableSetterSelector
99// purpose : Creates new variable setter selector
100// =======================================================================
101OpenGl_VariableSetterSelector::OpenGl_VariableSetterSelector()
102{
103 // Note: Add new variable setters here
104 mySetterList = OpenGl_HashMapInitializer::CreateListOf<size_t, OpenGl_SetterInterface*>
105 (Graphic3d_UniformValueTypeID<int>::ID, new OpenGl_VariableSetter<int>())
106 (Graphic3d_UniformValueTypeID<float>::ID, new OpenGl_VariableSetter<float>())
107 (Graphic3d_UniformValueTypeID<OpenGl_Vec2>::ID, new OpenGl_VariableSetter<OpenGl_Vec2>())
108 (Graphic3d_UniformValueTypeID<OpenGl_Vec3>::ID, new OpenGl_VariableSetter<OpenGl_Vec3>())
109 (Graphic3d_UniformValueTypeID<OpenGl_Vec4>::ID, new OpenGl_VariableSetter<OpenGl_Vec4>())
110 (Graphic3d_UniformValueTypeID<OpenGl_Vec2i>::ID, new OpenGl_VariableSetter<OpenGl_Vec2i>())
111 (Graphic3d_UniformValueTypeID<OpenGl_Vec3i>::ID, new OpenGl_VariableSetter<OpenGl_Vec3i>())
112 (Graphic3d_UniformValueTypeID<OpenGl_Vec4i>::ID, new OpenGl_VariableSetter<OpenGl_Vec4i>());
113}
114
115// =======================================================================
116// function : ~OpenGl_VariableSetterSelector
117// purpose : Releases memory resources of variable setter selector
118// =======================================================================
119OpenGl_VariableSetterSelector::~OpenGl_VariableSetterSelector()
120{
121 for (OpenGl_SetterList::Iterator anIt (mySetterList); anIt.More(); anIt.Next())
122 {
123 delete anIt.Value();
124 }
125
126 mySetterList.Clear();
127}
128
129// =======================================================================
130// function : Set
131// purpose : Sets generic variable to specified shader program
132// =======================================================================
133void OpenGl_VariableSetterSelector::Set (const Handle(OpenGl_Context)& theCtx,
134 const Handle(Graphic3d_ShaderVariable)& theVariable,
135 OpenGl_ShaderProgram* theProgram) const
136{
137 Standard_ASSERT_RETURN (mySetterList.IsBound (theVariable->Value()->TypeID()),
138 "The type of user-defined uniform variable is not supported...", );
139
140 mySetterList.Find (theVariable->Value()->TypeID())->Set (theCtx, theVariable, theProgram);
141}
142
143// =======================================================================
144// function : OpenGl_ShaderProgram
145// purpose : Creates uninitialized shader program
146// =======================================================================
147OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy)
cc8cbabe 148: OpenGl_NamedResource (!theProxy.IsNull() ? theProxy->GetId() : ""),
149 myProgramID (NO_PROGRAM),
392ac980 150 myProxy (theProxy),
8e0a2b19 151 myShareCount(1),
daf73ab7 152 myNbLightsMax (0),
153 myNbClipPlanesMax (0),
b17e5bae 154 myNbFragOutputs (1),
155 myHasWeightOitOutput (false),
8e0a2b19 156 myHasTessShader (false)
30f0ad28 157{
158 memset (myCurrentState, 0, sizeof (myCurrentState));
159 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
160 {
161 myStateLocations[aVar] = INVALID_LOCATION;
162 }
163}
164
165// =======================================================================
166// function : Initialize
167// purpose : Initializes program object with the list of shader objects
168// =======================================================================
169Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& theCtx,
170 const Graphic3d_ShaderObjectList& theShaders)
171{
8e0a2b19 172 myHasTessShader = false;
30f0ad28 173 if (theCtx.IsNull() || !Create (theCtx))
174 {
175 return Standard_False;
176 }
177
8e0a2b19 178 TCollection_AsciiString aHeaderVer = !myProxy.IsNull() ? myProxy->Header() : TCollection_AsciiString();
179 int aShaderMask = 0;
180 for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders); anIter.More(); anIter.Next())
181 {
182 aShaderMask |= anIter.Value()->Type();
183 }
184 myHasTessShader = (aShaderMask & (Graphic3d_TOS_TESS_CONTROL | Graphic3d_TOS_TESS_EVALUATION)) != 0;
b17e5bae 185 myNbFragOutputs = !myProxy.IsNull() ? myProxy->NbFragmentOutputs() : 1;
186 myHasWeightOitOutput = !myProxy.IsNull() ? myProxy->HasWeightOitOutput() && myNbFragOutputs >= 2 : 1;
30f0ad28 187
8e0a2b19 188 // detect the minimum GLSL version required for defined Shader Objects
189#if defined(GL_ES_VERSION_2_0)
190 if (myHasTessShader
191 || (aShaderMask & Graphic3d_TOS_GEOMETRY) != 0)
192 {
193 if (!theCtx->IsGlGreaterEqual (3, 2))
194 {
195 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
196 "Error! Geometry and Tessellation shaders require OpenGL ES 3.2+");
197 return false;
198 }
199 else if (aHeaderVer.IsEmpty())
200 {
201 aHeaderVer = "#version 320 es";
202 }
203 }
204 else if ((aShaderMask & Graphic3d_TOS_COMPUTE) != 0)
205 {
206 if (!theCtx->IsGlGreaterEqual (3, 1))
207 {
208 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
209 "Error! Compute shaders require OpenGL ES 3.1+");
210 return false;
211 }
212 else if (aHeaderVer.IsEmpty())
213 {
214 aHeaderVer = "#version 310 es";
215 }
216 }
217#else
218 if ((aShaderMask & Graphic3d_TOS_COMPUTE) != 0)
219 {
220 if (!theCtx->IsGlGreaterEqual (4, 3))
221 {
222 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
223 "Error! Compute shaders require OpenGL 4.3+");
224 return 0;
225 }
226 else if (aHeaderVer.IsEmpty())
227 {
228 aHeaderVer = "#version 430";
229 }
230 }
231 else if (myHasTessShader)
232 {
233 if (!theCtx->IsGlGreaterEqual (4, 0))
234 {
235 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
236 "Error! Tessellation shaders require OpenGL 4.0+");
237 return 0;
238 }
239 else if (aHeaderVer.IsEmpty())
240 {
241 aHeaderVer = "#version 400";
242 }
243 }
244 else if ((aShaderMask & Graphic3d_TOS_GEOMETRY) != 0)
245 {
246 if (!theCtx->IsGlGreaterEqual (3, 2))
247 {
248 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
249 "Error! Geometry shaders require OpenGL 3.2+");
250 return 0;
251 }
252 else if (aHeaderVer.IsEmpty())
253 {
254 aHeaderVer = "#version 150";
255 }
256 }
257#endif
12381341 258
8e0a2b19 259 for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders); anIter.More(); anIter.Next())
30f0ad28 260 {
261 if (!anIter.Value()->IsDone())
262 {
392ac980 263 const TCollection_ExtendedString aMsg = "Error! Failed to get shader source";
8e0a2b19 264 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
30f0ad28 265 return Standard_False;
266 }
267
8e0a2b19 268 const GLenum aShaderType = shaderTypeToGl (anIter.Value()->Type());
269 if (aShaderType == 0)
30f0ad28 270 {
30f0ad28 271 return Standard_False;
272 }
273
8e0a2b19 274 Handle(OpenGl_ShaderObject) aShader = new OpenGl_ShaderObject (aShaderType);
30f0ad28 275 if (!aShader->Create (theCtx))
276 {
392ac980 277 aShader->Release (theCtx.operator->());
30f0ad28 278 return Standard_False;
279 }
280
177781da 281 TCollection_AsciiString anExtensions = "// Enable extensions used in OCCT GLSL programs\n";
b17e5bae 282 if (myNbFragOutputs > 1)
a1073ae2 283 {
b17e5bae 284 if (theCtx->hasDrawBuffers)
a1073ae2 285 {
b17e5bae 286 anExtensions += "#define OCC_ENABLE_draw_buffers\n";
287 if (myHasWeightOitOutput)
288 {
289 anExtensions += "#define OCC_WRITE_WEIGHT_OIT_COVERAGE\n";
290 }
a1073ae2 291 }
b17e5bae 292 else
293 {
294 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
295 "Error! Multiple draw buffers required by the program, but aren't supported by OpenGL");
296 return Standard_False;
297 }
298
299 if (theCtx->hasDrawBuffers == OpenGl_FeatureInExtensions)
a1073ae2 300 {
b17e5bae 301 if (theCtx->arbDrawBuffers)
302 {
303 anExtensions += "#extension GL_ARB_draw_buffers : enable\n";
304 }
305 else if (theCtx->extDrawBuffers)
306 {
307 anExtensions += "#extension GL_EXT_draw_buffers : enable\n";
308 }
a1073ae2 309 }
310 }
311
312 if (theCtx->hasSampleVariables == OpenGl_FeatureInExtensions)
313 {
314#if defined(GL_ES_VERSION_2_0)
315 if (theCtx->oesSampleVariables)
316 {
317 anExtensions += "#extension GL_OES_sample_variables : enable\n";
318 }
319#else
320 if (theCtx->arbSampleShading)
321 {
322 anExtensions += "#extension GL_ARB_sample_shading : enable\n";
323 }
324#endif
325 }
326
8e0a2b19 327 TCollection_AsciiString aPrecisionHeader;
328 if (anIter.Value()->Type() == Graphic3d_TOS_FRAGMENT)
329 {
330 #if defined(GL_ES_VERSION_2_0)
331 aPrecisionHeader = theCtx->hasHighp
332 ? "precision highp float;\n"
333 "precision highp int;\n"
334 : "precision mediump float;\n"
335 "precision mediump int;\n";
336 #endif
337 }
338
339 TCollection_AsciiString aHeaderType;
8625ef7e 340 switch (anIter.Value()->Type())
30f0ad28 341 {
8e0a2b19 342 case Graphic3d_TOS_COMPUTE: { aHeaderType = "#define COMPUTE_SHADER\n"; break; }
343 case Graphic3d_TOS_VERTEX: { aHeaderType = "#define VERTEX_SHADER\n"; break; }
344 case Graphic3d_TOS_TESS_CONTROL: { aHeaderType = "#define TESS_CONTROL_SHADER\n"; break; }
345 case Graphic3d_TOS_TESS_EVALUATION: { aHeaderType = "#define TESS_EVALUATION_SHADER\n"; break; }
346 case Graphic3d_TOS_GEOMETRY: { aHeaderType = "#define GEOMETRY_SHADER\n"; break; }
347 case Graphic3d_TOS_FRAGMENT: { aHeaderType = "#define FRAGMENT_SHADER\n"; break; }
30f0ad28 348 }
349
daf73ab7 350 TCollection_AsciiString aHeaderConstants;
351 myNbLightsMax = !myProxy.IsNull() ? myProxy->NbLightsMax() : 0;
352 myNbClipPlanesMax = !myProxy.IsNull() ? myProxy->NbClipPlanesMax() : 0;
05fb2b05 353 aHeaderConstants += TCollection_AsciiString("#define THE_MAX_LIGHTS ") + myNbLightsMax + "\n";
354 aHeaderConstants += TCollection_AsciiString("#define THE_MAX_CLIP_PLANES ") + myNbClipPlanesMax + "\n";
b17e5bae 355 aHeaderConstants += TCollection_AsciiString("#define THE_NB_FRAG_OUTPUTS ") + myNbFragOutputs + "\n";
daf73ab7 356
8e0a2b19 357 const TCollection_AsciiString aSource = aHeaderVer // #version - header defining GLSL version, should be first
358 + (!aHeaderVer.IsEmpty() ? "\n" : "")
359 + anExtensions // #extension - list of enabled extensions, should be second
360 + aPrecisionHeader // precision - default precision qualifiers, should be before any code
361 + aHeaderType // auxiliary macros defining a shader stage (type)
daf73ab7 362 + aHeaderConstants
8e0a2b19 363 + Shaders_Declarations_glsl // common declarations (global constants and Vertex Shader inputs)
364 + Shaders_DeclarationsImpl_glsl
365 + anIter.Value()->Source(); // the source code itself (defining main() function)
30f0ad28 366 if (!aShader->LoadSource (theCtx, aSource))
367 {
a1073ae2 368 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aSource);
05fb2b05 369 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, "Error! Failed to set shader source");
392ac980 370 aShader->Release (theCtx.operator->());
30f0ad28 371 return Standard_False;
372 }
373
374 if (!aShader->Compile (theCtx))
375 {
a1073ae2 376 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aSource);
392ac980 377 TCollection_AsciiString aLog;
378 aShader->FetchInfoLog (theCtx, aLog);
379 if (aLog.IsEmpty())
380 {
381 aLog = "Compilation log is empty.";
382 }
05fb2b05 383 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
392ac980 384 TCollection_ExtendedString ("Failed to compile shader object. Compilation log:\n") + aLog);
385 aShader->Release (theCtx.operator->());
386 return Standard_False;
387 }
388 else if (theCtx->caps->glslWarnings)
389 {
390 TCollection_AsciiString aLog;
391 aShader->FetchInfoLog (theCtx, aLog);
392 if (!aLog.IsEmpty()
393 && !aLog.IsEqual ("No errors.\n"))
30f0ad28 394 {
05fb2b05 395 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_LOW,
392ac980 396 TCollection_ExtendedString ("Shader compilation log:\n") + aLog);
30f0ad28 397 }
30f0ad28 398 }
399
400 if (!AttachShader (theCtx, aShader))
401 {
392ac980 402 aShader->Release (theCtx.operator->());
30f0ad28 403 return Standard_False;
404 }
405 }
406
7d3e64ef 407 // bind locations for pre-defined Vertex Attributes
408 SetAttributeName (theCtx, Graphic3d_TOA_POS, "occVertex");
409 SetAttributeName (theCtx, Graphic3d_TOA_NORM, "occNormal");
410 SetAttributeName (theCtx, Graphic3d_TOA_UV, "occTexCoord");
8625ef7e 411 SetAttributeName (theCtx, Graphic3d_TOA_COLOR, "occVertColor");
7d3e64ef 412
4a535d3f 413 // bind custom Vertex Attributes
414 if (!myProxy.IsNull())
415 {
416 for (Graphic3d_ShaderAttributeList::Iterator anAttribIter (myProxy->VertexAttributes());
417 anAttribIter.More(); anAttribIter.Next())
418 {
419 SetAttributeName (theCtx, anAttribIter.Value()->Location(), anAttribIter.Value()->Name().ToCString());
420 }
421 }
422
30f0ad28 423 if (!Link (theCtx))
424 {
392ac980 425 TCollection_AsciiString aLog;
426 FetchInfoLog (theCtx, aLog);
427 if (aLog.IsEmpty())
428 {
429 aLog = "Linker log is empty.";
430 }
05fb2b05 431 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
12381341 432 TCollection_ExtendedString ("Failed to link program object! Linker log:\n") + aLog);
392ac980 433 return Standard_False;
434 }
435 else if (theCtx->caps->glslWarnings)
436 {
437 TCollection_AsciiString aLog;
438 FetchInfoLog (theCtx, aLog);
439 if (!aLog.IsEmpty()
440 && !aLog.IsEqual ("No errors.\n"))
30f0ad28 441 {
05fb2b05 442 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_LOW,
392ac980 443 TCollection_ExtendedString ("GLSL linker log:\n") + aLog);
30f0ad28 444 }
30f0ad28 445 }
446
299e0ab9 447 // set uniform defaults
cc8cbabe 448 const Handle(OpenGl_ShaderProgram)& anOldProgram = theCtx->ActiveProgram();
449 theCtx->core20fwd->glUseProgram (myProgramID);
299e0ab9 450 {
cc8cbabe 451 const GLint aLocTexEnable = GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE);
452 if (aLocTexEnable != INVALID_LOCATION)
453 {
454 SetUniform (theCtx, aLocTexEnable, 0); // Off
455 }
456 }
457 {
458 const GLint aLocSampler = GetUniformLocation (theCtx, "occActiveSampler");
459 if (aLocSampler != INVALID_LOCATION)
460 {
461 SetUniform (theCtx, aLocSampler, GLint(Graphic3d_TextureUnit_0));
462 }
463 }
464
465 const TCollection_AsciiString aSamplerNamePrefix ("occSampler");
466 const Standard_Integer aNbUnitsMax = Max (theCtx->MaxCombinedTextureUnits(), Graphic3d_TextureUnit_NB);
467 for (GLint aUnitIter = 0; aUnitIter < aNbUnitsMax; ++aUnitIter)
468 {
469 const TCollection_AsciiString aName = aSamplerNamePrefix + aUnitIter;
470 const GLint aLocSampler = GetUniformLocation (theCtx, aName.ToCString());
471 if (aLocSampler != INVALID_LOCATION)
472 {
473 SetUniform (theCtx, aLocSampler, aUnitIter);
474 }
299e0ab9 475 }
476
cc8cbabe 477 theCtx->core20fwd->glUseProgram (!anOldProgram.IsNull() ? anOldProgram->ProgramId() : OpenGl_ShaderProgram::NO_PROGRAM);
30f0ad28 478 return Standard_True;
479}
480
481// =======================================================================
482// function : ~OpenGl_ShaderProgram
483// purpose : Releases resources of shader program
484// =======================================================================
485OpenGl_ShaderProgram::~OpenGl_ShaderProgram()
486{
487 Release (NULL);
488}
489
490// =======================================================================
491// function : AttachShader
492// purpose : Attaches shader object to the program object
493// =======================================================================
494Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context)& theCtx,
495 const Handle(OpenGl_ShaderObject)& theShader)
496{
497 if (myProgramID == NO_PROGRAM || theShader.IsNull())
498 {
499 return Standard_False;
500 }
501
502 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
503 {
504 if (theShader == anIter.Value())
505 {
506 return Standard_False;
507 }
508 }
509
510 myShaderObjects.Append (theShader);
4e1523ef 511 theCtx->core20fwd->glAttachShader (myProgramID, theShader->myShaderID);
30f0ad28 512 return Standard_True;
513}
514
515// =======================================================================
516// function : DetachShader
517// purpose : Detaches shader object to the program object
518// =======================================================================
519Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context)& theCtx,
520 const Handle(OpenGl_ShaderObject)& theShader)
521{
522 if (myProgramID == NO_PROGRAM
523 || theShader.IsNull())
524 {
525 return Standard_False;
526 }
527
528 OpenGl_ShaderList::Iterator anIter (myShaderObjects);
529 while (anIter.More())
530 {
531 if (theShader == anIter.Value())
532 {
533 myShaderObjects.Remove (anIter);
534 break;
535 }
536
537 anIter.Next();
538 }
539
540 if (!anIter.More())
541 {
542 return Standard_False;
543 }
544
4e1523ef 545 theCtx->core20fwd->glDetachShader (myProgramID, theShader->myShaderID);
30f0ad28 546 return Standard_True;
547}
548
549// =======================================================================
550// function : Link
551// purpose : Links the program object
552// =======================================================================
553Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx)
554{
555 if (myProgramID == NO_PROGRAM)
556 {
557 return Standard_False;
558 }
559
30f0ad28 560 GLint aStatus = GL_FALSE;
4e1523ef 561 theCtx->core20fwd->glLinkProgram (myProgramID);
562 theCtx->core20fwd->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
fc73a202 563 if (aStatus == GL_FALSE)
564 {
565 return Standard_False;
566 }
30f0ad28 567
568 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
569 {
570 myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]);
571 }
fc73a202 572 return Standard_True;
30f0ad28 573}
574
575// =======================================================================
576// function : FetchInfoLog
577// purpose : Fetches information log of the last link operation
578// =======================================================================
579Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
580 TCollection_AsciiString& theOutput)
581{
582 if (myProgramID == NO_PROGRAM)
583 {
584 return Standard_False;
585 }
586
587 GLint aLength = 0;
4e1523ef 588 theCtx->core20fwd->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
30f0ad28 589 if (aLength > 0)
590 {
591 GLchar* aLog = (GLchar*) alloca (aLength);
592 memset (aLog, 0, aLength);
4e1523ef 593 theCtx->core20fwd->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
30f0ad28 594 theOutput = aLog;
595 }
596 return Standard_True;
597}
598
599// =======================================================================
30f0ad28 600// function : ApplyVariables
601// purpose : Fetches uniform variables from proxy shader program
602// =======================================================================
603Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Context)& theCtx)
604{
605 if (myProxy.IsNull() || myProxy->Variables().IsEmpty())
606 {
607 return Standard_False;
608 }
609
610 for (Graphic3d_ShaderVariableList::Iterator anIter (myProxy->Variables()); anIter.More(); anIter.Next())
611 {
612 mySetterSelector.Set (theCtx, anIter.Value(), this);
613 }
614
615 myProxy->ClearVariables();
616 return Standard_True;
617}
618
619// =======================================================================
30f0ad28 620// function : GetUniformLocation
621// purpose : Returns location (index) of the specific uniform variable
622// =======================================================================
623GLint OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& theCtx,
624 const GLchar* theName) const
625{
626 return myProgramID != NO_PROGRAM
4e1523ef 627 ? theCtx->core20fwd->glGetUniformLocation (myProgramID, theName)
30f0ad28 628 : INVALID_LOCATION;
629}
630
631// =======================================================================
632// function : GetAttributeLocation
633// purpose : Returns location (index) of the generic vertex attribute
634// =======================================================================
635GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)& theCtx,
636 const GLchar* theName) const
637{
638 return myProgramID != NO_PROGRAM
4e1523ef 639 ? theCtx->core20fwd->glGetAttribLocation (myProgramID, theName)
30f0ad28 640 : INVALID_LOCATION;
641}
642
643// =======================================================================
644// function : GetStateLocation
645// purpose : Returns location of the OCCT state uniform variable
646// =======================================================================
647GLint OpenGl_ShaderProgram::GetStateLocation (const GLuint theVariable) const
648{
649 if (theVariable < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES)
650 {
651 return myStateLocations[theVariable];
652 }
653 return INVALID_LOCATION;
654}
655
656// =======================================================================
657// function : GetUniform
658// purpose : Returns the value of the integer uniform variable
659// =======================================================================
660Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
661 const GLchar* theName,
662 OpenGl_Vec4i& theValue) const
663{
664 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
665}
666
667// =======================================================================
668// function : GetUniform
669// purpose : Returns the value of the integer uniform variable
670// =======================================================================
671Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
672 GLint theLocation,
673 OpenGl_Vec4i& theValue) const
674{
675 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
676 {
677 return Standard_False;
678 }
679
4e1523ef 680 theCtx->core20fwd->glGetUniformiv (myProgramID, theLocation, theValue);
30f0ad28 681 return Standard_True;
682}
683
684// =======================================================================
685// function : GetUniform
686// purpose : Returns the value of the floating-point uniform variable
687// =======================================================================
688Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
689 const GLchar* theName,
690 OpenGl_Vec4& theValue) const
691{
692 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
693}
694
695// =======================================================================
696// function : GetUniform
697// purpose : Returns the value of the floating-point uniform variable
698// =======================================================================
699Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
700 GLint theLocation,
701 OpenGl_Vec4& theValue) const
702{
703 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
704 {
705 return Standard_False;
706 }
707
4e1523ef 708 theCtx->core20fwd->glGetUniformfv (myProgramID, theLocation, theValue);
30f0ad28 709 return Standard_True;
710}
711
712// =======================================================================
713// function : GetAttribute
714// purpose : Returns the integer vertex attribute
715// =======================================================================
716Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
717 const GLchar* theName,
718 OpenGl_Vec4i& theValue) const
719{
720 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
721}
722
723// =======================================================================
724// function : GetAttribute
725// purpose : Returns the integer vertex attribute
726// =======================================================================
727Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
728 GLint theIndex,
729 OpenGl_Vec4i& theValue) const
730{
731 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
732 {
733 return Standard_False;
734 }
735
4e1523ef 736 theCtx->core20fwd->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
30f0ad28 737 return Standard_True;
738}
739
740// =======================================================================
741// function : GetAttribute
742// purpose : Returns the floating-point vertex attribute
743// =======================================================================
744Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
745 const GLchar* theName,
746 OpenGl_Vec4& theValue) const
747{
748 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
749}
750
751// =======================================================================
752// function : GetAttribute
753// purpose : Returns the floating-point vertex attribute
754// =======================================================================
755Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
756 GLint theIndex,
757 OpenGl_Vec4& theValue) const
758{
759 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
760 {
761 return Standard_False;
762 }
763
4e1523ef 764 theCtx->core20fwd->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
30f0ad28 765 return Standard_True;
766}
767
768// =======================================================================
fc73a202 769// function : SetAttributeName
770// purpose :
771// =======================================================================
772Standard_Boolean OpenGl_ShaderProgram::SetAttributeName (const Handle(OpenGl_Context)& theCtx,
773 GLint theIndex,
774 const GLchar* theName)
775{
776 theCtx->core20fwd->glBindAttribLocation (myProgramID, theIndex, theName);
777 return Standard_True;
778}
b86bb3df 779
fc73a202 780// =======================================================================
781// function : SetAttribute
782// purpose :
783// =======================================================================
784Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
785 const GLchar* theName,
786 GLfloat theValue)
787{
788 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
789}
790
791// =======================================================================
792// function : SetAttribute
793// purpose :
794// =======================================================================
795Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
796 GLint theIndex,
797 GLfloat theValue)
798{
799 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
800 {
801 return Standard_False;
802 }
803
804 theCtx->core20fwd->glVertexAttrib1f (theIndex, theValue);
805 return Standard_True;
806}
807
808// =======================================================================
809// function : SetAttribute
810// purpose :
811// =======================================================================
812Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
813 const GLchar* theName,
814 const OpenGl_Vec2& theValue)
815{
816 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
817}
818
819// =======================================================================
820// function : SetAttribute
821// purpose :
822// =======================================================================
823Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
824 GLint theIndex,
825 const OpenGl_Vec2& theValue)
826{
827 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
828 {
829 return Standard_False;
830 }
831
832 theCtx->core20fwd->glVertexAttrib2fv (theIndex, theValue);
833 return Standard_True;
834}
835
836// =======================================================================
837// function : SetAttribute
838// purpose :
839// =======================================================================
840Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
841 const GLchar* theName,
842 const OpenGl_Vec3& theValue)
843{
844 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
845}
846
847// =======================================================================
848// function : SetAttribute
849// purpose :
850// =======================================================================
851Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
852 GLint theIndex,
853 const OpenGl_Vec3& theValue)
854{
855 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
856 {
857 return Standard_False;
858 }
859
860 theCtx->core20fwd->glVertexAttrib3fv (theIndex, theValue);
861 return Standard_True;
862}
863
864// =======================================================================
865// function : SetAttribute
866// purpose :
867// =======================================================================
868Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
869 const GLchar* theName,
870 const OpenGl_Vec4& theValue)
871{
872 return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
873}
874
875// =======================================================================
876// function : SetAttribute
877// purpose :
878// =======================================================================
879Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
880 GLint theIndex,
881 const OpenGl_Vec4& theValue)
882{
883 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
884 {
885 return Standard_False;
886 }
887
888 theCtx->core20fwd->glVertexAttrib4fv (theIndex, theValue);
889 return Standard_True;
890}
891
892// =======================================================================
30f0ad28 893// function : SetUniform
894// purpose : Specifies the value of the integer uniform variable
895// =======================================================================
896Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
897 const GLchar* theName,
898 GLint theValue)
899{
900 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
901}
902
903// =======================================================================
904// function : SetUniform
905// purpose : Specifies the value of the integer uniform variable
906// =======================================================================
907Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
908 GLint theLocation,
909 GLint theValue)
910{
911 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
912 {
913 return Standard_False;
914 }
915
4e1523ef 916 theCtx->core20fwd->glUniform1i (theLocation, theValue);
30f0ad28 917 return Standard_True;
918}
919
920// =======================================================================
921// function : SetUniform
47e9c178 922// purpose :
25ef750e 923// =======================================================================
924Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
925 const GLchar* theName,
47e9c178 926 const OpenGl_Vec2u& theValue)
25ef750e 927{
928 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
929}
930
931// =======================================================================
932// function : SetUniform
47e9c178 933// purpose :
25ef750e 934// =======================================================================
935Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
936 GLint theLocation,
47e9c178 937 const OpenGl_Vec2u& theValue)
25ef750e 938{
47e9c178 939 if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
25ef750e 940 {
941 return Standard_False;
942 }
943
944#if !defined(GL_ES_VERSION_2_0)
47e9c178 945 theCtx->core32->glUniform2uiv (theLocation, 1, theValue.GetData());
25ef750e 946 return Standard_True;
20aeeb7b 947#else
948 (void )theValue;
949 return Standard_False;
950#endif
25ef750e 951}
952
953// =======================================================================
954// function : SetUniform
47e9c178 955// purpose :
25ef750e 956// =======================================================================
957Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
958 const GLchar* theName,
959 const GLsizei theCount,
47e9c178 960 const OpenGl_Vec2u* theValue)
25ef750e 961{
962 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theCount, theValue);
963}
964
965// =======================================================================
966// function : SetUniform
47e9c178 967// purpose :
25ef750e 968// =======================================================================
969Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
970 GLint theLocation,
971 const GLsizei theCount,
47e9c178 972 const OpenGl_Vec2u* theValue)
25ef750e 973{
47e9c178 974 if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
25ef750e 975 {
976 return Standard_False;
977 }
978
979#if !defined(GL_ES_VERSION_2_0)
47e9c178 980 theCtx->core32->glUniform2uiv (theLocation, theCount, theValue->GetData());
25ef750e 981 return Standard_True;
20aeeb7b 982#else
983 (void )theCount;
984 (void )theValue;
985 return Standard_False;
986#endif
25ef750e 987}
988
989// =======================================================================
990// function : SetUniform
30f0ad28 991// purpose : Specifies the value of the floating-point uniform variable
992// =======================================================================
993Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
994 const GLchar* theName,
995 GLfloat theValue)
996{
997 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
998}
999
1000// =======================================================================
1001// function : SetUniform
1002// purpose : Specifies the value of the floating-point uniform variable
1003// =======================================================================
1004Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1005 GLint theLocation,
1006 GLfloat theValue)
1007{
1008 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1009 {
1010 return Standard_False;
1011 }
1012
4e1523ef 1013 theCtx->core20fwd->glUniform1f (theLocation, theValue);
30f0ad28 1014 return Standard_True;
1015}
1016
1017// =======================================================================
1018// function : SetUniform
1019// purpose : Specifies the value of the integer uniform 2D vector
1020// =======================================================================
1021Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1022 const GLchar* theName,
1023 const OpenGl_Vec2i& theValue)
1024{
1025 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1026}
1027
1028// =======================================================================
1029// function : SetUniform
1030// purpose : Specifies the value of the integer uniform 2D vector
1031// =======================================================================
1032Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1033 GLint theLocation,
1034 const OpenGl_Vec2i& theValue)
1035{
1036 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1037 {
1038 return Standard_False;
1039 }
1040
4e1523ef 1041 theCtx->core20fwd->glUniform2iv (theLocation, 1, theValue);
30f0ad28 1042 return Standard_True;
1043}
1044
1045// =======================================================================
1046// function : SetUniform
1047// purpose : Specifies the value of the integer uniform 3D vector
1048// =======================================================================
1049Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1050 const GLchar* theName,
1051 const OpenGl_Vec3i& theValue)
1052{
1053 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1054}
1055
1056// =======================================================================
1057// function : SetUniform
1058// purpose : Specifies the value of the integer uniform 3D vector
1059// =======================================================================
1060Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1061 GLint theLocation,
1062 const OpenGl_Vec3i& theValue)
1063{
1064 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1065 {
1066 return Standard_False;
1067 }
1068
4e1523ef 1069 theCtx->core20fwd->glUniform3iv (theLocation, 1, theValue);
30f0ad28 1070 return Standard_True;
1071}
1072
1073// =======================================================================
1074// function : SetUniform
1075// purpose : Specifies the value of the integer uniform 4D vector
1076// =======================================================================
1077Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1078 const GLchar* theName,
1079 const OpenGl_Vec4i& theValue)
1080{
1081 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1082}
1083
1084// =======================================================================
1085// function : SetUniform
1086// purpose : Specifies the value of the integer uniform 4D vector
1087// =======================================================================
1088Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1089 GLint theLocation,
1090 const OpenGl_Vec4i& theValue)
1091{
1092 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1093 {
1094 return Standard_False;
1095 }
1096
4e1523ef 1097 theCtx->core20fwd->glUniform4iv (theLocation, 1, theValue);
30f0ad28 1098 return Standard_True;
1099}
1100
1101// =======================================================================
1102// function : SetUniform
1103// purpose : Specifies the value of the floating-point uniform 2D vector
1104// =======================================================================
1105Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1106 const GLchar* theName,
1107 const OpenGl_Vec2& theValue)
1108{
1109 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1110}
1111
1112// =======================================================================
1113// function : SetUniform
1114// purpose : Specifies the value of the floating-point uniform 2D vector
1115// =======================================================================
1116Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1117 GLint theLocation,
1118 const OpenGl_Vec2& theValue)
1119{
1120 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1121 {
1122 return Standard_False;
1123 }
1124
4e1523ef 1125 theCtx->core20fwd->glUniform2fv (theLocation, 1, theValue);
30f0ad28 1126 return Standard_True;
1127}
1128
1129// =======================================================================
1130// function : SetUniform
1131// purpose : Specifies the value of the floating-point uniform 3D vector
1132// =======================================================================
1133Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1134 const GLchar* theName,
1135 const OpenGl_Vec3& theValue)
1136{
1137 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1138}
1139
1140// =======================================================================
1141// function : SetUniform
1142// purpose : Specifies the value of the floating-point uniform 3D vector
1143// =======================================================================
1144Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1145 GLint theLocation,
1146 const OpenGl_Vec3& theValue)
1147{
1148 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1149 {
1150 return Standard_False;
1151 }
1152
4e1523ef 1153 theCtx->core20fwd->glUniform3fv (theLocation, 1, theValue);
30f0ad28 1154 return Standard_True;
1155}
1156
1157// =======================================================================
1158// function : SetUniform
1159// purpose : Specifies the value of the floating-point uniform 4D vector
1160// =======================================================================
1161Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1162 const GLchar* theName,
1163 const OpenGl_Vec4& theValue)
1164{
1165 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1166}
1167
1168// =======================================================================
1169// function : SetUniform
1170// purpose : Specifies the value of the floating-point uniform 4D vector
1171// =======================================================================
1172Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1173 GLint theLocation,
1174 const OpenGl_Vec4& theValue)
1175{
1176 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1177 {
1178 return Standard_False;
1179 }
1180
4e1523ef 1181 theCtx->core20fwd->glUniform4fv (theLocation, 1, theValue);
30f0ad28 1182 return Standard_True;
1183}
1184
1185// =======================================================================
1186// function : SetUniform
1187// purpose : Specifies the value of the floating-point uniform 4x4 matrix
1188// =======================================================================
1189Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1190 const GLchar* theName,
25ef750e 1191 const OpenGl_Mat4& theValue,
1192 GLboolean theTranspose)
1193{
1194 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1195}
1196
1197// =======================================================================
1198// function : SetUniform
1199// purpose : Specifies the value of the floating-point uniform 4x4 matrix
1200// =======================================================================
1201Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1202 GLint theLocation,
1203 const OpenGl_Mat4& theValue,
1204 GLboolean theTranspose)
1205{
1206 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1207 {
1208 return Standard_False;
1209 }
1210
4e1523ef 1211 theCtx->core20fwd->glUniformMatrix4fv (theLocation, 1, GL_FALSE, theTranspose ? theValue.Transposed() : theValue);
25ef750e 1212 return Standard_True;
1213}
1214
1215// =======================================================================
1216// function : SetUniform
1217// purpose : Specifies the value of the floating-point uniform 4x4 matrix
1218// =======================================================================
1219Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1220 const GLchar* theName,
30f0ad28 1221 const OpenGl_Matrix& theValue,
1222 GLboolean theTranspose)
1223{
1224 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1225}
1226
1227// =======================================================================
1228// function : SetUniform
1229// purpose : Specifies the value of the floating-point uniform 4x4 matrix
1230// =======================================================================
1231Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1232 GLint theLocation,
1233 const OpenGl_Matrix& theValue,
1234 GLboolean theTranspose)
1235{
c827ea3a 1236 return SetUniform (theCtx, theLocation, OpenGl_Mat4::Map (*theValue.mat), theTranspose);
30f0ad28 1237}
1238
1239// =======================================================================
4fe9ad57 1240// function : SetUniform
1241// purpose : Specifies the value of the float uniform array
1242// =======================================================================
1243Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1244 GLint theLocation,
1245 GLuint theCount,
1246 const Standard_ShortReal* theData)
1247{
1248 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1249 {
1250 return Standard_False;
1251 }
1252
4e1523ef 1253 theCtx->core20fwd->glUniform1fv (theLocation, theCount, theData);
4fe9ad57 1254 return Standard_True;
1255}
1256
1257// =======================================================================
1258// function : SetUniform
1259// purpose : Specifies the value of the float2 uniform array
1260// =======================================================================
1261Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1262 GLint theLocation,
1263 GLuint theCount,
1264 const OpenGl_Vec2* theData)
1265{
1266 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1267 {
1268 return Standard_False;
1269 }
1270
4e1523ef 1271 theCtx->core20fwd->glUniform2fv (theLocation, theCount, theData[0].GetData());
4fe9ad57 1272 return Standard_True;
1273}
1274
1275// =======================================================================
1276// function : SetUniform
1277// purpose : Specifies the value of the float3 uniform array
1278// =======================================================================
1279Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1280 GLint theLocation,
1281 GLuint theCount,
1282 const OpenGl_Vec3* theData)
1283{
1284 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1285 {
1286 return Standard_False;
1287 }
1288
4e1523ef 1289 theCtx->core20fwd->glUniform3fv (theLocation, theCount, theData[0].GetData());
4fe9ad57 1290 return Standard_True;
1291}
1292
1293// =======================================================================
1294// function : SetUniform
1295// purpose : Specifies the value of the float4 uniform array
1296// =======================================================================
1297Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1298 GLint theLocation,
1299 GLuint theCount,
1300 const OpenGl_Vec4* theData)
1301{
1302 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1303 {
1304 return Standard_False;
1305 }
1306
4e1523ef 1307 theCtx->core20fwd->glUniform4fv (theLocation, theCount, theData[0].GetData());
4fe9ad57 1308 return Standard_True;
1309}
1310
1311// =======================================================================
1312// function : SetUniform
1313// purpose : Specifies the value of the integer uniform array
1314// =======================================================================
1315Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1316 GLint theLocation,
1317 GLuint theCount,
1318 const Standard_Integer* theData)
1319{
1320 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1321 {
1322 return Standard_False;
1323 }
1324
4e1523ef 1325 theCtx->core20fwd->glUniform1iv (theLocation, theCount, theData);
4fe9ad57 1326 return Standard_True;
1327}
1328
1329// =======================================================================
1330// function : SetUniform
1331// purpose : Specifies the value of the int2 uniform array
1332// =======================================================================
1333Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1334 GLint theLocation,
1335 GLuint theCount,
1336 const OpenGl_Vec2i* theData)
1337{
1338 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1339 {
1340 return Standard_False;
1341 }
1342
4e1523ef 1343 theCtx->core20fwd->glUniform2iv (theLocation, theCount, theData[0].GetData());
4fe9ad57 1344 return Standard_True;
1345}
1346
1347// =======================================================================
1348// function : SetUniform
1349// purpose : Specifies the value of the int3 uniform array
1350// =======================================================================
1351Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1352 GLint theLocation,
1353 GLuint theCount,
1354 const OpenGl_Vec3i* theData)
1355{
1356 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1357 {
1358 return Standard_False;
1359 }
1360
4e1523ef 1361 theCtx->core20fwd->glUniform3iv (theLocation, theCount, theData[0].GetData());
4fe9ad57 1362 return Standard_True;
1363}
1364
1365// =======================================================================
1366// function : SetUniform
1367// purpose : Specifies the value of the int4 uniform array
1368// =======================================================================
1369Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1370 GLint theLocation,
1371 GLuint theCount,
1372 const OpenGl_Vec4i* theData)
1373{
1374 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1375 {
1376 return Standard_False;
1377 }
1378
4e1523ef 1379 theCtx->core20fwd->glUniform4iv (theLocation, theCount, theData[0].GetData());
4fe9ad57 1380 return Standard_True;
1381}
1382
1383// =======================================================================
30f0ad28 1384// function : SetSampler
1385// purpose : Specifies the value of the sampler uniform variable
1386// =======================================================================
1387Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1388 const GLchar* theName,
cc8cbabe 1389 const Graphic3d_TextureUnit theTextureUnit)
30f0ad28 1390{
1391 return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit);
1392}
1393
1394// =======================================================================
1395// function : SetSampler
1396// purpose : Specifies the value of the sampler uniform variable
1397// =======================================================================
1398Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1399 GLint theLocation,
cc8cbabe 1400 const Graphic3d_TextureUnit theTextureUnit)
30f0ad28 1401{
1402 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1403 {
1404 return Standard_False;
1405 }
1406
4e1523ef 1407 theCtx->core20fwd->glUniform1i (theLocation, theTextureUnit);
30f0ad28 1408 return Standard_True;
1409}
1410
1411// =======================================================================
1412// function : Create
1413// purpose : Creates new empty shader program of specified type
1414// =======================================================================
1415Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx)
1416{
1417 if (myProgramID == NO_PROGRAM
4e1523ef 1418 && theCtx->core20fwd != NULL)
30f0ad28 1419 {
4e1523ef 1420 myProgramID = theCtx->core20fwd->glCreateProgram();
30f0ad28 1421 }
1422
1423 return myProgramID != NO_PROGRAM;
1424}
1425
1426// =======================================================================
1427// function : Release
1428// purpose : Destroys shader program
1429// =======================================================================
10b9c7df 1430void OpenGl_ShaderProgram::Release (OpenGl_Context* theCtx)
30f0ad28 1431{
1432 if (myProgramID == NO_PROGRAM)
1433 {
1434 return;
1435 }
1436
1437 Standard_ASSERT_RETURN (theCtx != NULL,
1438 "OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...",);
1439
1440 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
1441 {
fc73a202 1442 if (!anIter.Value().IsNull())
1443 {
1444 anIter.ChangeValue()->Release (theCtx);
1445 anIter.ChangeValue().Nullify();
1446 }
30f0ad28 1447 }
1448
4e1523ef 1449 if (theCtx->core20fwd != NULL
ec2eeb2d 1450 && theCtx->IsValid())
30f0ad28 1451 {
4e1523ef 1452 theCtx->core20fwd->glDeleteProgram (myProgramID);
30f0ad28 1453 }
1454
1455 myProgramID = NO_PROGRAM;
1456}