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