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