0027750: Visualization, V3d_View - remove unused functionality ZClipping and ZCueing
[occt.git] / src / OpenGl / OpenGl_ShaderProgram.cxx
index a0e027e..6f501d1 100755 (executable)
 #include <OpenGl_Context.hxx>
 #include <OpenGl_ShaderProgram.hxx>
 #include <OpenGl_ShaderManager.hxx>
+#include <OpenGl_ArbTexBindless.hxx>
 
-IMPLEMENT_STANDARD_HANDLE (OpenGl_ShaderProgram, OpenGl_Resource)
-IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderProgram, OpenGl_Resource)
+#include <OpenGl_GlCore32.hxx>
+
+#ifdef _WIN32
+  #include <malloc.h> // for alloca()
+#endif
+
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderProgram,OpenGl_Resource)
 
 OpenGl_VariableSetterSelector OpenGl_ShaderProgram::mySetterSelector = OpenGl_VariableSetterSelector();
 
@@ -47,7 +53,6 @@ Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] =
   "occProjectionMatrixInverseTranspose", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE
 
   "occClipPlaneEquations", // OpenGl_OCC_CLIP_PLANE_EQUATIONS
-  "occClipPlaneSpaces",    // OpenGl_OCC_CLIP_PLANE_SPACES
   "occClipPlaneCount",     // OpenGl_OCC_CLIP_PLANE_COUNT
 
   "occLightSourcesCount",  // OpenGl_OCC_LIGHT_SOURCE_COUNT
@@ -62,6 +67,7 @@ Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] =
   "occBackMaterial",       // OpenGl_OCCT_BACK_MATERIAL
   "occColor",              // OpenGl_OCCT_COLOR
 
+  "occTexTrsf2d",          // OpenGl_OCCT_TEXTURE_TRSF2D
   "occPointSize"           // OpenGl_OCCT_POINT_SIZE
 
 };
@@ -146,14 +152,18 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
    || !aDeclImplFile.Exists())
   {
     const TCollection_ExtendedString aMsg = "Error! Failed to load OCCT shader declarations file";
-    theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
-                         GL_DEBUG_TYPE_ERROR_ARB,
+    theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+                         GL_DEBUG_TYPE_ERROR,
                          0,
-                         GL_DEBUG_SEVERITY_HIGH_ARB,
+                         GL_DEBUG_SEVERITY_HIGH,
                          aMsg);
     return Standard_False;
   }
 
+  TCollection_AsciiString aHeader = !myProxy.IsNull() && !myProxy->Header().IsEmpty()
+                                  ? (myProxy->Header() + "\n")
+                                  : TCollection_AsciiString();
+
   TCollection_AsciiString aDeclarations;
   aDeclFile.Open (OSD_ReadOnly, OSD_Protection());
   aDeclFile.Read (aDeclarations, (int)aDeclFile.Size());
@@ -171,10 +181,10 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
     if (!anIter.Value()->IsDone())
     {
       const TCollection_ExtendedString aMsg = "Error! Failed to get shader source";
-      theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
-                           GL_DEBUG_TYPE_ERROR_ARB,
+      theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+                           GL_DEBUG_TYPE_ERROR,
                            0,
-                           GL_DEBUG_SEVERITY_HIGH_ARB,
+                           GL_DEBUG_SEVERITY_HIGH,
                            aMsg);
       return Standard_False;
     }
@@ -196,10 +206,10 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
     if (aShader.IsNull())
     {
       TCollection_ExtendedString aMsg = "Error! Unsupported shader type";
-      theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
-                           GL_DEBUG_TYPE_ERROR_ARB,
+      theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+                           GL_DEBUG_TYPE_ERROR,
                            0,
-                           GL_DEBUG_SEVERITY_HIGH_ARB,
+                           GL_DEBUG_SEVERITY_HIGH,
                            aMsg);
       return Standard_False;
     }
@@ -215,7 +225,7 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
     {
       case Graphic3d_TOS_VERTEX:
       {
-        aSource = TCollection_AsciiString ("#define VERTEX_SHADER\n") + aSource;
+        aSource = aHeader + TCollection_AsciiString ("#define VERTEX_SHADER\n") + aSource;
         break;
       }
       case Graphic3d_TOS_FRAGMENT:
@@ -223,8 +233,12 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
       #if defined(GL_ES_VERSION_2_0)
         TCollection_AsciiString aPrefix (theCtx->hasHighp
                                        ? "precision highp float;\n"
-                                       : "precision mediump float;\n");
-        aSource = aPrefix + aSource;
+                                         "precision highp int;\n"
+                                       : "precision mediump float;\n"
+                                         "precision mediump int;\n");
+        aSource = aHeader + aPrefix + aSource;
+      #else
+        aSource = aHeader + aSource;
       #endif
         break;
       }
@@ -233,10 +247,10 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
     if (!aShader->LoadSource (theCtx, aSource))
     {
       const TCollection_ExtendedString aMsg = "Error! Failed to set shader source";
-      theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
-                           GL_DEBUG_TYPE_ERROR_ARB,
+      theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+                           GL_DEBUG_TYPE_ERROR,
                            0,
-                           GL_DEBUG_SEVERITY_HIGH_ARB,
+                           GL_DEBUG_SEVERITY_HIGH,
                            aMsg);
       aShader->Release (theCtx.operator->());
       return Standard_False;
@@ -250,10 +264,10 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
       {
         aLog = "Compilation log is empty.";
       }
-      theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
-                           GL_DEBUG_TYPE_ERROR_ARB,
+      theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+                           GL_DEBUG_TYPE_ERROR,
                            0,
-                           GL_DEBUG_SEVERITY_HIGH_ARB,
+                           GL_DEBUG_SEVERITY_HIGH,
                            TCollection_ExtendedString ("Failed to compile shader object. Compilation log:\n") + aLog);
       aShader->Release (theCtx.operator->());
       return Standard_False;
@@ -265,10 +279,10 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
       if (!aLog.IsEmpty()
        && !aLog.IsEqual ("No errors.\n"))
       {
-        theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
-                             GL_DEBUG_TYPE_PORTABILITY_ARB,
+        theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+                             GL_DEBUG_TYPE_PORTABILITY,
                              0,
-                             GL_DEBUG_SEVERITY_LOW_ARB,
+                             GL_DEBUG_SEVERITY_LOW,
                              TCollection_ExtendedString ("Shader compilation log:\n") + aLog);
       }
     }
@@ -286,6 +300,16 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
   SetAttributeName (theCtx, Graphic3d_TOA_UV,    "occTexCoord");
   SetAttributeName (theCtx, Graphic3d_TOA_COLOR, "occVertColor");
 
+  // bind custom Vertex Attributes
+  if (!myProxy.IsNull())
+  {
+    for (Graphic3d_ShaderAttributeList::Iterator anAttribIter (myProxy->VertexAttributes());
+         anAttribIter.More(); anAttribIter.Next())
+    {
+      SetAttributeName (theCtx, anAttribIter.Value()->Location(), anAttribIter.Value()->Name().ToCString());
+    }
+  }
+
   if (!Link (theCtx))
   {
     TCollection_AsciiString aLog;
@@ -294,10 +318,10 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
     {
       aLog = "Linker log is empty.";
     }
-    theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
-                         GL_DEBUG_TYPE_ERROR_ARB,
+    theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+                         GL_DEBUG_TYPE_ERROR,
                          0,
-                         GL_DEBUG_SEVERITY_HIGH_ARB,
+                         GL_DEBUG_SEVERITY_HIGH,
                          TCollection_ExtendedString ("Failed to link program object! Linker log:\n") + aLog);
     return Standard_False;
   }
@@ -308,14 +332,27 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
     if (!aLog.IsEmpty()
      && !aLog.IsEqual ("No errors.\n"))
     {
-      theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
-                           GL_DEBUG_TYPE_PORTABILITY_ARB,
+      theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+                           GL_DEBUG_TYPE_PORTABILITY,
                            0,
-                           GL_DEBUG_SEVERITY_LOW_ARB,
+                           GL_DEBUG_SEVERITY_LOW,
                            TCollection_ExtendedString ("GLSL linker log:\n") + aLog);
     }
   }
 
+  // set uniform defaults
+  const GLint aLocSampler   = GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER);
+  const GLint aLocTexEnable = GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE);
+  if (aLocSampler   != INVALID_LOCATION
+   || aLocTexEnable != INVALID_LOCATION)
+  {
+    const Handle(OpenGl_ShaderProgram)& anOldProgram = theCtx->ActiveProgram();
+    theCtx->core20fwd->glUseProgram (myProgramID);
+    SetUniform (theCtx, aLocSampler,   0); // GL_TEXTURE0
+    SetUniform (theCtx, aLocTexEnable, 0); // Off
+    theCtx->core20fwd->glUseProgram (!anOldProgram.IsNull() ? anOldProgram->ProgramId() : OpenGl_ShaderProgram::NO_PROGRAM);
+  }
+
   return Standard_True;
 }
 
@@ -349,7 +386,7 @@ Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context
   }
 
   myShaderObjects.Append (theShader);
-  theCtx->core20->glAttachShader (myProgramID, theShader->myShaderID);
+  theCtx->core20fwd->glAttachShader (myProgramID, theShader->myShaderID);
   return Standard_True;
 }
 
@@ -383,7 +420,7 @@ Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context
     return Standard_False;
   }
 
-  theCtx->core20->glDetachShader (myProgramID, theShader->myShaderID);
+  theCtx->core20fwd->glDetachShader (myProgramID, theShader->myShaderID);
   return Standard_True;
 }
 
@@ -399,8 +436,8 @@ Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCt
   }
 
   GLint aStatus = GL_FALSE;
-  theCtx->core20->glLinkProgram (myProgramID);
-  theCtx->core20->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
+  theCtx->core20fwd->glLinkProgram (myProgramID);
+  theCtx->core20fwd->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
   if (aStatus == GL_FALSE)
   {
     return Standard_False;
@@ -426,12 +463,12 @@ Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context
   }
 
   GLint aLength = 0;
-  theCtx->core20->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
+  theCtx->core20fwd->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
   if (aLength > 0)
   {
     GLchar* aLog = (GLchar*) alloca (aLength);
     memset (aLog, 0, aLength);
-    theCtx->core20->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
+    theCtx->core20fwd->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
     theOutput = aLog;
   }
   return Standard_True;
@@ -491,7 +528,7 @@ GLint OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& th
                                                 const GLchar*                 theName) const
 {
   return myProgramID != NO_PROGRAM
-       ? theCtx->core20->glGetUniformLocation (myProgramID, theName)
+       ? theCtx->core20fwd->glGetUniformLocation (myProgramID, theName)
        : INVALID_LOCATION;
 }
 
@@ -503,7 +540,7 @@ GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)&
                                                   const GLchar*                 theName) const
 {
   return myProgramID != NO_PROGRAM
-       ? theCtx->core20->glGetAttribLocation (myProgramID, theName)
+       ? theCtx->core20fwd->glGetAttribLocation (myProgramID, theName)
        : INVALID_LOCATION;
 }
 
@@ -544,7 +581,7 @@ Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glGetUniformiv (myProgramID, theLocation, theValue);
+  theCtx->core20fwd->glGetUniformiv (myProgramID, theLocation, theValue);
   return Standard_True;
 }
 
@@ -572,7 +609,7 @@ Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glGetUniformfv (myProgramID, theLocation, theValue);
+  theCtx->core20fwd->glGetUniformfv (myProgramID, theLocation, theValue);
   return Standard_True;
 }
 
@@ -600,7 +637,7 @@ Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context
     return Standard_False;
   }
 
-  theCtx->core20->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
+  theCtx->core20fwd->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
   return Standard_True;
 }
 
@@ -628,7 +665,7 @@ Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context
     return Standard_False;
   }
 
-  theCtx->core20->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
+  theCtx->core20fwd->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
   return Standard_True;
 }
 
@@ -643,7 +680,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetAttributeName (const Handle(OpenGl_Con
   theCtx->core20fwd->glBindAttribLocation (myProgramID, theIndex, theName);
   return Standard_True;
 }
-  
+
 // =======================================================================
 // function : SetAttribute
 // purpose  :
@@ -780,10 +817,79 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform1i (theLocation, theValue);
+  theCtx->core20fwd->glUniform1i (theLocation, theValue);
   return Standard_True;
 }
 
+// =======================================================================
+// function : SetUniform
+// purpose  :
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   const GLchar*                 theName,
+                                                   const OpenGl_Vec2u&           theValue)
+{
+  return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
+}
+
+// =======================================================================
+// function : SetUniform
+// purpose  :
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   GLint                         theLocation,
+                                                   const OpenGl_Vec2u&           theValue)
+{
+  if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
+  {
+    return Standard_False;
+  }
+
+#if !defined(GL_ES_VERSION_2_0)
+  theCtx->core32->glUniform2uiv (theLocation, 1, theValue.GetData());
+  return Standard_True;
+#else
+  (void )theValue;
+  return Standard_False;
+#endif
+}
+
+// =======================================================================
+// function : SetUniform
+// purpose  :
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   const GLchar*                 theName,
+                                                   const GLsizei                 theCount,
+                                                   const OpenGl_Vec2u*           theValue)
+{
+  return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theCount, theValue);
+}
+
+// =======================================================================
+// function : SetUniform
+// purpose  :
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   GLint                         theLocation,
+                                                   const GLsizei                 theCount,
+                                                   const OpenGl_Vec2u*           theValue)
+{
+  if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
+  {
+    return Standard_False;
+  }
+
+#if !defined(GL_ES_VERSION_2_0)
+  theCtx->core32->glUniform2uiv (theLocation, theCount, theValue->GetData());
+  return Standard_True;
+#else
+  (void )theCount;
+  (void )theValue;
+  return Standard_False;
+#endif
+}
+
 // =======================================================================
 // function : SetUniform
 // purpose  : Specifies the value of the floating-point uniform variable
@@ -808,7 +914,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform1f (theLocation, theValue);
+  theCtx->core20fwd->glUniform1f (theLocation, theValue);
   return Standard_True;
 }
 
@@ -836,7 +942,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform2iv (theLocation, 1, theValue);
+  theCtx->core20fwd->glUniform2iv (theLocation, 1, theValue);
   return Standard_True;
 }
 
@@ -864,7 +970,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform3iv (theLocation, 1, theValue);
+  theCtx->core20fwd->glUniform3iv (theLocation, 1, theValue);
   return Standard_True;
 }
 
@@ -892,7 +998,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform4iv (theLocation, 1, theValue);
+  theCtx->core20fwd->glUniform4iv (theLocation, 1, theValue);
   return Standard_True;
 }
 
@@ -920,7 +1026,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform2fv (theLocation, 1, theValue);
+  theCtx->core20fwd->glUniform2fv (theLocation, 1, theValue);
   return Standard_True;
 }
 
@@ -948,7 +1054,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform3fv (theLocation, 1, theValue);
+  theCtx->core20fwd->glUniform3fv (theLocation, 1, theValue);
   return Standard_True;
 }
 
@@ -976,7 +1082,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform4fv (theLocation, 1, theValue);
+  theCtx->core20fwd->glUniform4fv (theLocation, 1, theValue);
   return Standard_True;
 }
 
@@ -986,7 +1092,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
 // =======================================================================
 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
                                                    const GLchar*                 theName,
-                                                   const OpenGl_Matrix&          theValue,
+                                                   const OpenGl_Mat4&            theValue,
                                                    GLboolean                     theTranspose)
 {
   return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
@@ -998,7 +1104,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
 // =======================================================================
 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
                                                    GLint                         theLocation,
-                                                   const OpenGl_Matrix&          theValue,
+                                                   const OpenGl_Mat4&            theValue,
                                                    GLboolean                     theTranspose)
 {
   if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
@@ -1006,7 +1112,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniformMatrix4fv (theLocation, 1, theTranspose, *theValue.mat);
+  theCtx->core20fwd->glUniformMatrix4fv (theLocation, 1, GL_FALSE, theTranspose ? theValue.Transposed() : theValue);
   return Standard_True;
 }
 
@@ -1016,7 +1122,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
 // =======================================================================
 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
                                                    const GLchar*                 theName,
-                                                   const Tmatrix3&               theValue,
+                                                   const OpenGl_Matrix&          theValue,
                                                    GLboolean                     theTranspose)
 {
   return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
@@ -1028,16 +1134,10 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
 // =======================================================================
 Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
                                                    GLint                         theLocation,
-                                                   const Tmatrix3&               theValue,
+                                                   const OpenGl_Matrix&          theValue,
                                                    GLboolean                     theTranspose)
 {
-  if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
-  {
-    return Standard_False;
-  }
-
-  theCtx->core20->glUniformMatrix4fv (theLocation, 1, theTranspose, *theValue);
-  return Standard_True;
+  return SetUniform (theCtx, theLocation, OpenGl_Mat4::Map (*theValue.mat), theTranspose);
 }
 
 // =======================================================================
@@ -1054,7 +1154,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform1fv (theLocation, theCount, theData);
+  theCtx->core20fwd->glUniform1fv (theLocation, theCount, theData);
   return Standard_True;
 }
 
@@ -1072,7 +1172,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform2fv (theLocation, theCount, theData[0].GetData());
+  theCtx->core20fwd->glUniform2fv (theLocation, theCount, theData[0].GetData());
   return Standard_True;
 }
 
@@ -1090,7 +1190,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform3fv (theLocation, theCount, theData[0].GetData());
+  theCtx->core20fwd->glUniform3fv (theLocation, theCount, theData[0].GetData());
   return Standard_True;
 }
 
@@ -1108,7 +1208,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform4fv (theLocation, theCount, theData[0].GetData());
+  theCtx->core20fwd->glUniform4fv (theLocation, theCount, theData[0].GetData());
   return Standard_True;
 }
 
@@ -1126,7 +1226,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform1iv (theLocation, theCount, theData);
+  theCtx->core20fwd->glUniform1iv (theLocation, theCount, theData);
   return Standard_True;
 }
 
@@ -1144,7 +1244,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform2iv (theLocation, theCount, theData[0].GetData());
+  theCtx->core20fwd->glUniform2iv (theLocation, theCount, theData[0].GetData());
   return Standard_True;
 }
 
@@ -1162,7 +1262,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform3iv (theLocation, theCount, theData[0].GetData());
+  theCtx->core20fwd->glUniform3iv (theLocation, theCount, theData[0].GetData());
   return Standard_True;
 }
 
@@ -1180,7 +1280,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform4iv (theLocation, theCount, theData[0].GetData());
+  theCtx->core20fwd->glUniform4iv (theLocation, theCount, theData[0].GetData());
   return Standard_True;
 }
 
@@ -1208,7 +1308,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform1i (theLocation, theTextureUnit);
+  theCtx->core20fwd->glUniform1i (theLocation, theTextureUnit);
   return Standard_True;
 }
 
@@ -1219,9 +1319,9 @@ Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)&
 Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx)
 {
   if (myProgramID == NO_PROGRAM
-   && theCtx->core20 != NULL)
+   && theCtx->core20fwd != NULL)
   {
-    myProgramID = theCtx->core20->glCreateProgram();
+    myProgramID = theCtx->core20fwd->glCreateProgram();
   }
 
   return myProgramID != NO_PROGRAM;
@@ -1250,10 +1350,10 @@ void OpenGl_ShaderProgram::Release (OpenGl_Context* theCtx)
     }
   }
 
-  if (theCtx->core20 != NULL
+  if (theCtx->core20fwd != NULL
    && theCtx->IsValid())
   {
-    theCtx->core20->glDeleteProgram (myProgramID);
+    theCtx->core20fwd->glDeleteProgram (myProgramID);
   }
 
   myProgramID = NO_PROGRAM;