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