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