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