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