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