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