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