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