0026122: Visualization, TKOpenGl - clipping and capping is broken when ffp is disable...
[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   "occTexTrsf2d",          // OpenGl_OCCT_TEXTURE_TRSF2D
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 highp int;\n"
232                                        : "precision mediump float;\n"
233                                          "precision mediump int;\n");
234         aSource = aHeader + aPrefix + aSource;
235       #else
236         aSource = aHeader + aSource;
237       #endif
238         break;
239       }
240     }
241
242     if (!aShader->LoadSource (theCtx, aSource))
243     {
244       const TCollection_ExtendedString aMsg = "Error! Failed to set shader source";
245       theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
246                            GL_DEBUG_TYPE_ERROR_ARB,
247                            0,
248                            GL_DEBUG_SEVERITY_HIGH_ARB,
249                            aMsg);
250       aShader->Release (theCtx.operator->());
251       return Standard_False;
252     }
253
254     if (!aShader->Compile (theCtx))
255     {
256       TCollection_AsciiString aLog;
257       aShader->FetchInfoLog (theCtx, aLog);
258       if (aLog.IsEmpty())
259       {
260         aLog = "Compilation log is empty.";
261       }
262       theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
263                            GL_DEBUG_TYPE_ERROR_ARB,
264                            0,
265                            GL_DEBUG_SEVERITY_HIGH_ARB,
266                            TCollection_ExtendedString ("Failed to compile shader object. Compilation log:\n") + aLog);
267       aShader->Release (theCtx.operator->());
268       return Standard_False;
269     }
270     else if (theCtx->caps->glslWarnings)
271     {
272       TCollection_AsciiString aLog;
273       aShader->FetchInfoLog (theCtx, aLog);
274       if (!aLog.IsEmpty()
275        && !aLog.IsEqual ("No errors.\n"))
276       {
277         theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
278                              GL_DEBUG_TYPE_PORTABILITY_ARB,
279                              0,
280                              GL_DEBUG_SEVERITY_LOW_ARB,
281                              TCollection_ExtendedString ("Shader compilation log:\n") + aLog);
282       }
283     }
284
285     if (!AttachShader (theCtx, aShader))
286     {
287       aShader->Release (theCtx.operator->());
288       return Standard_False;
289     }
290   }
291
292   // bind locations for pre-defined Vertex Attributes
293   SetAttributeName (theCtx, Graphic3d_TOA_POS,   "occVertex");
294   SetAttributeName (theCtx, Graphic3d_TOA_NORM,  "occNormal");
295   SetAttributeName (theCtx, Graphic3d_TOA_UV,    "occTexCoord");
296   SetAttributeName (theCtx, Graphic3d_TOA_COLOR, "occVertColor");
297
298   if (!Link (theCtx))
299   {
300     TCollection_AsciiString aLog;
301     FetchInfoLog (theCtx, aLog);
302     if (aLog.IsEmpty())
303     {
304       aLog = "Linker log is empty.";
305     }
306     theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
307                          GL_DEBUG_TYPE_ERROR_ARB,
308                          0,
309                          GL_DEBUG_SEVERITY_HIGH_ARB,
310                          TCollection_ExtendedString ("Failed to link program object! Linker log:\n") + aLog);
311     return Standard_False;
312   }
313   else if (theCtx->caps->glslWarnings)
314   {
315     TCollection_AsciiString aLog;
316     FetchInfoLog (theCtx, aLog);
317     if (!aLog.IsEmpty()
318      && !aLog.IsEqual ("No errors.\n"))
319     {
320       theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
321                            GL_DEBUG_TYPE_PORTABILITY_ARB,
322                            0,
323                            GL_DEBUG_SEVERITY_LOW_ARB,
324                            TCollection_ExtendedString ("GLSL linker log:\n") + aLog);
325     }
326   }
327
328   return Standard_True;
329 }
330
331 // =======================================================================
332 // function : ~OpenGl_ShaderProgram
333 // purpose  : Releases resources of shader program
334 // =======================================================================
335 OpenGl_ShaderProgram::~OpenGl_ShaderProgram()
336 {
337   Release (NULL);
338 }
339
340 // =======================================================================
341 // function : AttachShader
342 // purpose  : Attaches shader object to the program object
343 // =======================================================================
344 Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context)&      theCtx,
345                                                      const Handle(OpenGl_ShaderObject)& theShader)
346 {
347   if (myProgramID == NO_PROGRAM || theShader.IsNull())
348   {
349     return Standard_False;
350   }
351
352   for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
353   {
354     if (theShader == anIter.Value())
355     {
356       return Standard_False;
357     }
358   }
359
360   myShaderObjects.Append (theShader);
361   theCtx->core20fwd->glAttachShader (myProgramID, theShader->myShaderID);
362   return Standard_True;
363 }
364
365 // =======================================================================
366 // function : DetachShader
367 // purpose  : Detaches shader object to the program object
368 // =======================================================================
369 Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context)&      theCtx,
370                                                      const Handle(OpenGl_ShaderObject)& theShader)
371 {
372   if (myProgramID == NO_PROGRAM
373    || theShader.IsNull())
374   {
375     return Standard_False;
376   }
377
378   OpenGl_ShaderList::Iterator anIter (myShaderObjects);
379   while (anIter.More())
380   {
381     if (theShader == anIter.Value())
382     {
383       myShaderObjects.Remove (anIter);
384       break;
385     }
386
387     anIter.Next();
388   }
389
390   if (!anIter.More())
391   {
392     return Standard_False;
393   }
394
395   theCtx->core20fwd->glDetachShader (myProgramID, theShader->myShaderID);
396   return Standard_True;
397 }
398
399 // =======================================================================
400 // function : Link
401 // purpose  : Links the program object
402 // =======================================================================
403 Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx)
404 {
405   if (myProgramID == NO_PROGRAM)
406   {
407     return Standard_False;
408   }
409
410   GLint aStatus = GL_FALSE;
411   theCtx->core20fwd->glLinkProgram (myProgramID);
412   theCtx->core20fwd->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
413   if (aStatus == GL_FALSE)
414   {
415     return Standard_False;
416   }
417
418   for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
419   {
420     myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]);
421   }
422   return Standard_True;
423 }
424
425 // =======================================================================
426 // function : FetchInfoLog
427 // purpose  : Fetches information log of the last link operation
428 // =======================================================================
429 Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
430                                                      TCollection_AsciiString&      theOutput)
431 {
432   if (myProgramID == NO_PROGRAM)
433   {
434     return Standard_False;
435   }
436
437   GLint aLength = 0;
438   theCtx->core20fwd->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
439   if (aLength > 0)
440   {
441     GLchar* aLog = (GLchar*) alloca (aLength);
442     memset (aLog, 0, aLength);
443     theCtx->core20fwd->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
444     theOutput = aLog;
445   }
446   return Standard_True;
447 }
448
449 // =======================================================================
450 // function : ApplyVariables
451 // purpose  : Fetches uniform variables from proxy shader program
452 // =======================================================================
453 Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Context)& theCtx)
454 {
455   if (myProxy.IsNull() || myProxy->Variables().IsEmpty())
456   {
457     return Standard_False;
458   }
459
460   for (Graphic3d_ShaderVariableList::Iterator anIter (myProxy->Variables()); anIter.More(); anIter.Next())
461   {
462     mySetterSelector.Set (theCtx, anIter.Value(), this);
463   }
464
465   myProxy->ClearVariables();
466   return Standard_True;
467 }
468
469 // =======================================================================
470 // function : ActiveState
471 // purpose  : Returns index of last modification for specified state type
472 // =======================================================================
473 Standard_Size OpenGl_ShaderProgram::ActiveState (const OpenGl_UniformStateType theType) const
474 {
475   if (theType < MaxStateTypes)
476   {
477     return myCurrentState[theType];
478   }
479   return 0;
480 }
481
482 // =======================================================================
483 // function : UpdateState
484 // purpose  : Updates index of last modification for specified state type
485 // =======================================================================
486 void OpenGl_ShaderProgram::UpdateState (const OpenGl_UniformStateType theType,
487                                         const Standard_Size           theIndex)
488 {
489   if (theType < MaxStateTypes)
490   {
491     myCurrentState[theType] = theIndex;
492   }
493 }
494
495 // =======================================================================
496 // function : GetUniformLocation
497 // purpose  : Returns location (index) of the specific uniform variable
498 // =======================================================================
499 GLint OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& theCtx,
500                                                 const GLchar*                 theName) const
501 {
502   return myProgramID != NO_PROGRAM
503        ? theCtx->core20fwd->glGetUniformLocation (myProgramID, theName)
504        : INVALID_LOCATION;
505 }
506
507 // =======================================================================
508 // function : GetAttributeLocation
509 // purpose  : Returns location (index) of the generic vertex attribute
510 // =======================================================================
511 GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)& theCtx,
512                                                   const GLchar*                 theName) const
513 {
514   return myProgramID != NO_PROGRAM
515        ? theCtx->core20fwd->glGetAttribLocation (myProgramID, theName)
516        : INVALID_LOCATION;
517 }
518
519 // =======================================================================
520 // function : GetStateLocation
521 // purpose  : Returns location of the OCCT state uniform variable
522 // =======================================================================
523 GLint OpenGl_ShaderProgram::GetStateLocation (const GLuint theVariable) const
524 {
525   if (theVariable < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES)
526   {
527     return myStateLocations[theVariable];
528   }
529   return INVALID_LOCATION;
530 }
531
532 // =======================================================================
533 // function : GetUniform
534 // purpose  : Returns the value of the integer uniform variable
535 // =======================================================================
536 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
537                                                    const GLchar*                 theName,
538                                                    OpenGl_Vec4i&                 theValue) const
539 {
540   return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
541 }
542
543 // =======================================================================
544 // function : GetUniform
545 // purpose  : Returns the value of the integer uniform variable
546 // =======================================================================
547 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
548                                                    GLint                         theLocation,
549                                                    OpenGl_Vec4i&                 theValue) const
550 {
551   if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
552   {
553     return Standard_False;
554   }
555
556   theCtx->core20fwd->glGetUniformiv (myProgramID, theLocation, theValue);
557   return Standard_True;
558 }
559
560 // =======================================================================
561 // function : GetUniform
562 // purpose  : Returns the value of the floating-point uniform variable
563 // =======================================================================
564 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
565                                                    const GLchar*                 theName,
566                                                    OpenGl_Vec4&                  theValue) const
567 {
568   return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
569 }
570
571 // =======================================================================
572 // function : GetUniform
573 // purpose  : Returns the value of the floating-point uniform variable
574 // =======================================================================
575 Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
576                                                    GLint                         theLocation,
577                                                    OpenGl_Vec4&                  theValue) const
578 {
579   if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
580   {
581     return Standard_False;
582   }
583
584   theCtx->core20fwd->glGetUniformfv (myProgramID, theLocation, theValue);
585   return Standard_True;
586 }
587
588 // =======================================================================
589 // function : GetAttribute
590 // purpose  : Returns the integer vertex attribute
591 // =======================================================================
592 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
593                                                      const GLchar*                 theName,
594                                                      OpenGl_Vec4i&                 theValue) const
595 {
596   return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
597 }
598
599 // =======================================================================
600 // function : GetAttribute
601 // purpose  : Returns the integer vertex attribute
602 // =======================================================================
603 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
604                                                      GLint                         theIndex,
605                                                      OpenGl_Vec4i&                 theValue) const
606 {
607   if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
608   {
609     return Standard_False;
610   }
611
612   theCtx->core20fwd->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
613   return Standard_True;
614 }
615
616 // =======================================================================
617 // function : GetAttribute
618 // purpose  : Returns the floating-point vertex attribute
619 // =======================================================================
620 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
621                                                      const GLchar*                 theName,
622                                                      OpenGl_Vec4&                  theValue) const
623 {
624   return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
625 }
626
627 // =======================================================================
628 // function : GetAttribute
629 // purpose  : Returns the floating-point vertex attribute
630 // =======================================================================
631 Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
632                                                      GLint                         theIndex,
633                                                      OpenGl_Vec4&                  theValue) const
634 {
635   if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
636   {
637     return Standard_False;
638   }
639
640   theCtx->core20fwd->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
641   return Standard_True;
642 }
643
644 // =======================================================================
645 // function : SetAttributeName
646 // purpose  :
647 // =======================================================================
648 Standard_Boolean OpenGl_ShaderProgram::SetAttributeName (const Handle(OpenGl_Context)& theCtx,
649                                                          GLint                         theIndex,
650                                                          const GLchar*                 theName)
651 {
652   theCtx->core20fwd->glBindAttribLocation (myProgramID, theIndex, theName);
653   return Standard_True;
654 }
655
656 // =======================================================================
657 // function : SetAttribute
658 // purpose  :
659 // =======================================================================
660 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
661                                                      const GLchar*                 theName,
662                                                      GLfloat                       theValue)
663 {
664   return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
665 }
666
667 // =======================================================================
668 // function : SetAttribute
669 // purpose  :
670 // =======================================================================
671 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
672                                                      GLint                         theIndex,
673                                                      GLfloat                       theValue)
674 {
675   if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
676   {
677     return Standard_False;
678   }
679
680   theCtx->core20fwd->glVertexAttrib1f (theIndex, theValue);
681   return Standard_True;
682 }
683
684 // =======================================================================
685 // function : SetAttribute
686 // purpose  :
687 // =======================================================================
688 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
689                                                      const GLchar*                 theName,
690                                                      const OpenGl_Vec2&            theValue)
691 {
692   return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
693 }
694
695 // =======================================================================
696 // function : SetAttribute
697 // purpose  :
698 // =======================================================================
699 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
700                                                      GLint                         theIndex,
701                                                      const OpenGl_Vec2&            theValue)
702 {
703   if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
704   {
705     return Standard_False;
706   }
707
708   theCtx->core20fwd->glVertexAttrib2fv (theIndex, theValue);
709   return Standard_True;
710 }
711
712 // =======================================================================
713 // function : SetAttribute
714 // purpose  :
715 // =======================================================================
716 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
717                                                      const GLchar*                 theName,
718                                                      const OpenGl_Vec3&            theValue)
719 {
720   return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
721 }
722
723 // =======================================================================
724 // function : SetAttribute
725 // purpose  :
726 // =======================================================================
727 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
728                                                      GLint                         theIndex,
729                                                      const OpenGl_Vec3&            theValue)
730 {
731   if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
732   {
733     return Standard_False;
734   }
735
736   theCtx->core20fwd->glVertexAttrib3fv (theIndex, theValue);
737   return Standard_True;
738 }
739
740 // =======================================================================
741 // function : SetAttribute
742 // purpose  :
743 // =======================================================================
744 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
745                                                      const GLchar*                 theName,
746                                                      const OpenGl_Vec4&            theValue)
747 {
748   return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
749 }
750
751 // =======================================================================
752 // function : SetAttribute
753 // purpose  :
754 // =======================================================================
755 Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx,
756                                                      GLint                         theIndex,
757                                                      const OpenGl_Vec4&            theValue)
758 {
759   if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
760   {
761     return Standard_False;
762   }
763
764   theCtx->core20fwd->glVertexAttrib4fv (theIndex, theValue);
765   return Standard_True;
766 }
767
768 // =======================================================================
769 // function : SetUniform
770 // purpose  : Specifies the value of the integer uniform variable
771 // =======================================================================
772 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
773                                                    const GLchar*                 theName,
774                                                    GLint                         theValue)
775 {
776   return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
777 }
778
779 // =======================================================================
780 // function : SetUniform
781 // purpose  : Specifies the value of the integer uniform variable
782 // =======================================================================
783 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
784                                                    GLint                         theLocation,
785                                                    GLint                         theValue)
786 {
787   if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
788   {
789     return Standard_False;
790   }
791
792   theCtx->core20fwd->glUniform1i (theLocation, theValue);
793   return Standard_True;
794 }
795
796 // =======================================================================
797 // function : SetUniform
798 // purpose  :
799 // =======================================================================
800 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
801                                                    const GLchar*                 theName,
802                                                    const OpenGl_Vec2u&           theValue)
803 {
804   return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
805 }
806
807 // =======================================================================
808 // function : SetUniform
809 // purpose  :
810 // =======================================================================
811 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
812                                                    GLint                         theLocation,
813                                                    const OpenGl_Vec2u&           theValue)
814 {
815   if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
816   {
817     return Standard_False;
818   }
819
820 #if !defined(GL_ES_VERSION_2_0)
821   theCtx->core32->glUniform2uiv (theLocation, 1, theValue.GetData());
822 #endif
823
824   return Standard_True;
825 }
826
827 // =======================================================================
828 // function : SetUniform
829 // purpose  :
830 // =======================================================================
831 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
832                                                    const GLchar*                 theName,
833                                                    const GLsizei                 theCount,
834                                                    const OpenGl_Vec2u*           theValue)
835 {
836   return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theCount, theValue);
837 }
838
839 // =======================================================================
840 // function : SetUniform
841 // purpose  :
842 // =======================================================================
843 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
844                                                    GLint                         theLocation,
845                                                    const GLsizei                 theCount,
846                                                    const OpenGl_Vec2u*           theValue)
847 {
848   if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
849   {
850     return Standard_False;
851   }
852
853 #if !defined(GL_ES_VERSION_2_0)
854   theCtx->core32->glUniform2uiv (theLocation, theCount, theValue->GetData());
855 #endif
856
857   return Standard_True;
858 }
859
860 // =======================================================================
861 // function : SetUniform
862 // purpose  : Specifies the value of the floating-point uniform variable
863 // =======================================================================
864 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
865                                                    const GLchar*                 theName,
866                                                    GLfloat                       theValue)
867 {
868   return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
869 }
870
871 // =======================================================================
872 // function : SetUniform
873 // purpose  : Specifies the value of the floating-point uniform variable
874 // =======================================================================
875 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
876                                                    GLint                         theLocation,
877                                                    GLfloat                       theValue)
878 {
879   if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
880   {
881     return Standard_False;
882   }
883
884   theCtx->core20fwd->glUniform1f (theLocation, theValue);
885   return Standard_True;
886 }
887
888 // =======================================================================
889 // function : SetUniform
890 // purpose  : Specifies the value of the integer uniform 2D vector
891 // =======================================================================
892 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
893                                                    const GLchar*                 theName,
894                                                    const OpenGl_Vec2i&           theValue)
895 {
896   return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
897 }
898
899 // =======================================================================
900 // function : SetUniform
901 // purpose  : Specifies the value of the integer uniform 2D vector
902 // =======================================================================
903 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
904                                                    GLint                         theLocation,
905                                                    const OpenGl_Vec2i&           theValue)
906 {
907   if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
908   {
909     return Standard_False;
910   }
911
912   theCtx->core20fwd->glUniform2iv (theLocation, 1, theValue);
913   return Standard_True;
914 }
915
916 // =======================================================================
917 // function : SetUniform
918 // purpose  : Specifies the value of the integer uniform 3D vector
919 // =======================================================================
920 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
921                                                    const GLchar*                 theName,
922                                                    const OpenGl_Vec3i&           theValue)
923 {
924   return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
925 }
926
927 // =======================================================================
928 // function : SetUniform
929 // purpose  : Specifies the value of the integer uniform 3D vector
930 // =======================================================================
931 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
932                                                    GLint                         theLocation,
933                                                    const OpenGl_Vec3i&           theValue)
934 {
935   if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
936   {
937     return Standard_False;
938   }
939
940   theCtx->core20fwd->glUniform3iv (theLocation, 1, theValue);
941   return Standard_True;
942 }
943
944 // =======================================================================
945 // function : SetUniform
946 // purpose  : Specifies the value of the integer uniform 4D vector
947 // =======================================================================
948 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
949                                                    const GLchar*                 theName,
950                                                    const OpenGl_Vec4i&           theValue)
951 {
952   return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
953 }
954
955 // =======================================================================
956 // function : SetUniform
957 // purpose  : Specifies the value of the integer uniform 4D vector
958 // =======================================================================
959 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
960                                                    GLint                         theLocation,
961                                                    const OpenGl_Vec4i&           theValue)
962 {
963   if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
964   {
965     return Standard_False;
966   }
967
968   theCtx->core20fwd->glUniform4iv (theLocation, 1, theValue);
969   return Standard_True;
970 }
971
972 // =======================================================================
973 // function : SetUniform
974 // purpose  : Specifies the value of the floating-point uniform 2D vector
975 // =======================================================================
976 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
977                                                    const GLchar*                 theName,
978                                                    const OpenGl_Vec2&            theValue)
979 {
980   return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
981 }
982
983 // =======================================================================
984 // function : SetUniform
985 // purpose  : Specifies the value of the floating-point uniform 2D vector
986 // =======================================================================
987 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
988                                                    GLint                         theLocation,
989                                                    const OpenGl_Vec2&            theValue)
990 {
991   if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
992   {
993     return Standard_False;
994   }
995
996   theCtx->core20fwd->glUniform2fv (theLocation, 1, theValue);
997   return Standard_True;
998 }
999
1000 // =======================================================================
1001 // function : SetUniform
1002 // purpose  : Specifies the value of the floating-point uniform 3D vector
1003 // =======================================================================
1004 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1005                                                    const GLchar*                 theName,
1006                                                    const OpenGl_Vec3&            theValue)
1007 {
1008   return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1009 }
1010
1011 // =======================================================================
1012 // function : SetUniform
1013 // purpose  : Specifies the value of the floating-point uniform 3D vector
1014 // =======================================================================
1015 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1016                                                    GLint                         theLocation,
1017                                                    const OpenGl_Vec3&            theValue)
1018 {
1019   if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1020   {
1021     return Standard_False;
1022   }
1023
1024   theCtx->core20fwd->glUniform3fv (theLocation, 1, theValue);
1025   return Standard_True;
1026 }
1027
1028 // =======================================================================
1029 // function : SetUniform
1030 // purpose  : Specifies the value of the floating-point uniform 4D vector
1031 // =======================================================================
1032 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1033                                                    const GLchar*                 theName,
1034                                                    const OpenGl_Vec4&            theValue)
1035 {
1036   return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
1037 }
1038
1039 // =======================================================================
1040 // function : SetUniform
1041 // purpose  : Specifies the value of the floating-point uniform 4D vector
1042 // =======================================================================
1043 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1044                                                    GLint                         theLocation,
1045                                                    const OpenGl_Vec4&            theValue)
1046 {
1047   if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1048   {
1049     return Standard_False;
1050   }
1051
1052   theCtx->core20fwd->glUniform4fv (theLocation, 1, theValue);
1053   return Standard_True;
1054 }
1055
1056 // =======================================================================
1057 // function : SetUniform
1058 // purpose  : Specifies the value of the floating-point uniform 4x4 matrix
1059 // =======================================================================
1060 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1061                                                    const GLchar*                 theName,
1062                                                    const OpenGl_Mat4&            theValue,
1063                                                    GLboolean                     theTranspose)
1064 {
1065   return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1066 }
1067
1068 // =======================================================================
1069 // function : SetUniform
1070 // purpose  : Specifies the value of the floating-point uniform 4x4 matrix
1071 // =======================================================================
1072 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1073                                                    GLint                         theLocation,
1074                                                    const OpenGl_Mat4&            theValue,
1075                                                    GLboolean                     theTranspose)
1076 {
1077   if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1078   {
1079     return Standard_False;
1080   }
1081
1082   theCtx->core20fwd->glUniformMatrix4fv (theLocation, 1, GL_FALSE, theTranspose ? theValue.Transposed() : theValue);
1083   return Standard_True;
1084 }
1085
1086 // =======================================================================
1087 // function : SetUniform
1088 // purpose  : Specifies the value of the floating-point uniform 4x4 matrix
1089 // =======================================================================
1090 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1091                                                    const GLchar*                 theName,
1092                                                    const OpenGl_Matrix&          theValue,
1093                                                    GLboolean                     theTranspose)
1094 {
1095   return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
1096 }
1097
1098 // =======================================================================
1099 // function : SetUniform
1100 // purpose  : Specifies the value of the floating-point uniform 4x4 matrix
1101 // =======================================================================
1102 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1103                                                    GLint                         theLocation,
1104                                                    const OpenGl_Matrix&          theValue,
1105                                                    GLboolean                     theTranspose)
1106 {
1107   return SetUniform (theCtx, theLocation, OpenGl_Mat4::Map (*theValue.mat), theTranspose);
1108 }
1109
1110 // =======================================================================
1111 // function : SetUniform
1112 // purpose  : Specifies the value of the float uniform array
1113 // =======================================================================
1114 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1115                                                    GLint                         theLocation,
1116                                                    GLuint                        theCount,
1117                                                    const Standard_ShortReal*     theData)
1118 {
1119   if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1120   {
1121     return Standard_False;
1122   }
1123
1124   theCtx->core20fwd->glUniform1fv (theLocation, theCount, theData);
1125   return Standard_True;
1126 }
1127
1128 // =======================================================================
1129 // function : SetUniform
1130 // purpose  : Specifies the value of the float2 uniform array
1131 // =======================================================================
1132 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1133                                                    GLint                         theLocation,
1134                                                    GLuint                        theCount,
1135                                                    const OpenGl_Vec2*            theData)
1136 {
1137   if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1138   {
1139     return Standard_False;
1140   }
1141
1142   theCtx->core20fwd->glUniform2fv (theLocation, theCount, theData[0].GetData());
1143   return Standard_True;
1144 }
1145
1146 // =======================================================================
1147 // function : SetUniform
1148 // purpose  : Specifies the value of the float3 uniform array
1149 // =======================================================================
1150 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1151                                                    GLint                         theLocation,
1152                                                    GLuint                        theCount,
1153                                                    const OpenGl_Vec3*            theData)
1154 {
1155   if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1156   {
1157     return Standard_False;
1158   }
1159
1160   theCtx->core20fwd->glUniform3fv (theLocation, theCount, theData[0].GetData());
1161   return Standard_True;
1162 }
1163
1164 // =======================================================================
1165 // function : SetUniform
1166 // purpose  : Specifies the value of the float4 uniform array
1167 // =======================================================================
1168 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1169                                                    GLint                         theLocation,
1170                                                    GLuint                        theCount,
1171                                                    const OpenGl_Vec4*            theData)
1172 {
1173   if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1174   {
1175     return Standard_False;
1176   }
1177
1178   theCtx->core20fwd->glUniform4fv (theLocation, theCount, theData[0].GetData());
1179   return Standard_True;
1180 }
1181
1182 // =======================================================================
1183 // function : SetUniform
1184 // purpose  : Specifies the value of the integer uniform array
1185 // =======================================================================
1186 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1187                                                    GLint                         theLocation,
1188                                                    GLuint                        theCount,
1189                                                    const Standard_Integer*       theData)
1190 {
1191   if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1192   {
1193     return Standard_False;
1194   }
1195
1196   theCtx->core20fwd->glUniform1iv (theLocation, theCount, theData);
1197   return Standard_True;
1198 }
1199
1200 // =======================================================================
1201 // function : SetUniform
1202 // purpose  : Specifies the value of the int2 uniform array
1203 // =======================================================================
1204 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1205                                                    GLint                         theLocation,
1206                                                    GLuint                        theCount,
1207                                                    const OpenGl_Vec2i*           theData)
1208 {
1209   if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1210   {
1211     return Standard_False;
1212   }
1213
1214   theCtx->core20fwd->glUniform2iv (theLocation, theCount, theData[0].GetData());
1215   return Standard_True;
1216 }
1217
1218 // =======================================================================
1219 // function : SetUniform
1220 // purpose  : Specifies the value of the int3 uniform array
1221 // =======================================================================
1222 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1223                                                    GLint                         theLocation,
1224                                                    GLuint                        theCount,
1225                                                    const OpenGl_Vec3i*           theData)
1226 {
1227   if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1228   {
1229     return Standard_False;
1230   }
1231
1232   theCtx->core20fwd->glUniform3iv (theLocation, theCount, theData[0].GetData());
1233   return Standard_True;
1234 }
1235
1236 // =======================================================================
1237 // function : SetUniform
1238 // purpose  : Specifies the value of the int4 uniform array
1239 // =======================================================================
1240 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1241                                                    GLint                         theLocation,
1242                                                    GLuint                        theCount,
1243                                                    const OpenGl_Vec4i*           theData)
1244 {
1245   if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1246   {
1247     return Standard_False;
1248   }
1249
1250   theCtx->core20fwd->glUniform4iv (theLocation, theCount, theData[0].GetData());
1251   return Standard_True;
1252 }
1253
1254 // =======================================================================
1255 // function : SetSampler
1256 // purpose  : Specifies the value of the sampler uniform variable
1257 // =======================================================================
1258 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1259                                                    const GLchar*                 theName,
1260                                                    const GLenum                  theTextureUnit)
1261 {
1262   return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit);
1263 }
1264
1265 // =======================================================================
1266 // function : SetSampler
1267 // purpose  : Specifies the value of the sampler uniform variable
1268 // =======================================================================
1269 Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1270                                                    GLint                         theLocation,
1271                                                    const GLenum                  theTextureUnit)
1272 {
1273   if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1274   {
1275     return Standard_False;
1276   }
1277
1278   theCtx->core20fwd->glUniform1i (theLocation, theTextureUnit);
1279   return Standard_True;
1280 }
1281
1282 // =======================================================================
1283 // function : Create
1284 // purpose  : Creates new empty shader program of specified type
1285 // =======================================================================
1286 Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx)
1287 {
1288   if (myProgramID == NO_PROGRAM
1289    && theCtx->core20fwd != NULL)
1290   {
1291     myProgramID = theCtx->core20fwd->glCreateProgram();
1292   }
1293
1294   return myProgramID != NO_PROGRAM;
1295 }
1296
1297 // =======================================================================
1298 // function : Release
1299 // purpose  : Destroys shader program
1300 // =======================================================================
1301 void OpenGl_ShaderProgram::Release (OpenGl_Context* theCtx)
1302 {
1303   if (myProgramID == NO_PROGRAM)
1304   {
1305     return;
1306   }
1307
1308   Standard_ASSERT_RETURN (theCtx != NULL,
1309     "OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...",);
1310
1311   for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
1312   {
1313     if (!anIter.Value().IsNull())
1314     {
1315       anIter.ChangeValue()->Release (theCtx);
1316       anIter.ChangeValue().Nullify();
1317     }
1318   }
1319
1320   if (theCtx->core20fwd != NULL
1321    && theCtx->IsValid())
1322   {
1323     theCtx->core20fwd->glDeleteProgram (myProgramID);
1324   }
1325
1326   myProgramID = NO_PROGRAM;
1327 }