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