mat3 or mat4 uniform

Is there any way to set mat3 or mat4 uniform into my custom fragment shader?
Graphic3d_ShaderProgram::PushVariable supports only a limited set of types :(

gkv311 n's picture

Not without patching OCCT as far as I can see:

OpenGl_VariableSetterSelector::OpenGl_VariableSetterSelector()
{
  // Note: Add new variable setters here
  mySetterList = OpenGl_HashMapInitializer::CreateListOf<size_t, OpenGl_SetterInterface*>
    (Graphic3d_UniformValueTypeID<int>::ID,          new OpenGl_VariableSetter<int>())
    (Graphic3d_UniformValueTypeID<float>::ID,        new OpenGl_VariableSetter<float>())
    (Graphic3d_UniformValueTypeID<OpenGl_Vec2>::ID,  new OpenGl_VariableSetter<OpenGl_Vec2>())
    (Graphic3d_UniformValueTypeID<OpenGl_Vec3>::ID,  new OpenGl_VariableSetter<OpenGl_Vec3>())
    (Graphic3d_UniformValueTypeID<OpenGl_Vec4>::ID,  new OpenGl_VariableSetter<OpenGl_Vec4>())
    (Graphic3d_UniformValueTypeID<OpenGl_Vec2i>::ID, new OpenGl_VariableSetter<OpenGl_Vec2i>())
    (Graphic3d_UniformValueTypeID<OpenGl_Vec3i>::ID, new OpenGl_VariableSetter<OpenGl_Vec3i>())
    (Graphic3d_UniformValueTypeID<OpenGl_Vec4i>::ID, new OpenGl_VariableSetter<OpenGl_Vec4i>());
}

I suggest defining as set of vec3/vec4 uniforms instead and pack them into mat3/mat4 within the shader, if you are not willing to make modifications in OCCT.

in vec3 uMat0;
in vec3 uMat1;
in vec3 uMat2;
...
void main() {
  mat3 aMat = mat3(uMat0, uMat1, uMat2);
  ...
}

Make sure to check row or column-major order expectations.

Ivan Poberezhnyk's picture

Please add a PushVariable override in version 8 for mat4. It will save a lot of effort making custom shaders.

gkv311 n's picture
Subject: [PATCH] Visualization, Graphic3d_ShaderProgram - add mat3/mat4 types
 to PushVariable()

---
 src/Graphic3d/Graphic3d_ShaderProgram.hxx  |  6 ++++++
 src/Graphic3d/Graphic3d_ShaderVariable.cxx |  2 ++
 src/Graphic3d/Graphic3d_ShaderVariable.hxx | 18 ++++++++++++++++++
 src/OpenGl/OpenGl_ShaderProgram.cxx        | 20 ++++++++++++++++++++
 src/OpenGl/OpenGl_ShaderProgram.hxx        | 17 +++++++++++++++++
 5 files changed, 63 insertions(+)

diff --git a/src/Graphic3d/Graphic3d_ShaderProgram.hxx b/src/Graphic3d/Graphic3d_ShaderProgram.hxx
index 5432d1eb8c..c5cb2d398a 100755
--- a/src/Graphic3d/Graphic3d_ShaderProgram.hxx
+++ b/src/Graphic3d/Graphic3d_ShaderProgram.hxx
@@ -194,6 +194,12 @@ public:
   //! Pushes vec4 uniform.
   Standard_Boolean PushVariableVec4  (const TCollection_AsciiString& theName, const Graphic3d_Vec4& theValue)  { return PushVariable (theName, theValue); }

+  //! Pushes mat3 uniform.
+  Standard_Boolean PushVariableMat3  (const TCollection_AsciiString& theName, const NCollection_Mat3<float>& theValue) { return PushVariable (theName, theValue); }
+
+  //! Pushes mat4 uniform.
+  Standard_Boolean PushVariableMat4  (const TCollection_AsciiString& theName, const Graphic3d_Mat4& theValue)  { return PushVariable (theName, theValue); }
+
   //! Pushes int uniform.
   Standard_Boolean PushVariableInt   (const TCollection_AsciiString& theName, const int theValue)              { return PushVariable (theName, theValue); }

diff --git a/src/Graphic3d/Graphic3d_ShaderVariable.cxx b/src/Graphic3d/Graphic3d_ShaderVariable.cxx
index f76f6649ca..71356ba809 100755
--- a/src/Graphic3d/Graphic3d_ShaderVariable.cxx
+++ b/src/Graphic3d/Graphic3d_ShaderVariable.cxx
@@ -24,6 +24,8 @@ template struct Graphic3d_UniformValue<Standard_ShortReal>;
 template struct Graphic3d_UniformValue<Graphic3d_Vec2>;
 template struct Graphic3d_UniformValue<Graphic3d_Vec3>;
 template struct Graphic3d_UniformValue<Graphic3d_Vec4>;
+template struct Graphic3d_UniformValue<NCollection_Mat3<float>>;
+template struct Graphic3d_UniformValue<Graphic3d_Mat4>;
 template struct Graphic3d_UniformValue<Graphic3d_Vec2i>;
 template struct Graphic3d_UniformValue<Graphic3d_Vec3i>;
 template struct Graphic3d_UniformValue<Graphic3d_Vec4i>;
diff --git a/src/Graphic3d/Graphic3d_ShaderVariable.hxx b/src/Graphic3d/Graphic3d_ShaderVariable.hxx
index df6f27942e..7b7dfc115f 100755
--- a/src/Graphic3d/Graphic3d_ShaderVariable.hxx
+++ b/src/Graphic3d/Graphic3d_ShaderVariable.hxx
@@ -17,6 +17,8 @@
 #define _Graphic3d_ShaderVariable_HeaderFile

 #include <Graphic3d_Vec.hxx>
+#include <Graphic3d_Mat4.hxx>
+#include <NCollection_Mat3.hxx>
 #include <Standard_Transient.hxx>
 #include <TCollection_AsciiString.hxx>

@@ -67,6 +69,16 @@ struct Graphic3d_UniformValueTypeID<Graphic3d_Vec4> {
   static const Standard_Size ID = __LINE__;
 };

+template<>
+struct Graphic3d_UniformValueTypeID<NCollection_Mat3<float>> {
+  static const Standard_Size ID = __LINE__;
+};
+
+template<>
+struct Graphic3d_UniformValueTypeID<Graphic3d_Mat4> {
+  static const Standard_Size ID = __LINE__;
+};
+
 template<>
 struct Graphic3d_UniformValueTypeID<Graphic3d_Vec2i> {
   static const Standard_Size ID = __LINE__;
@@ -120,6 +132,12 @@ typedef Graphic3d_UniformValue<Graphic3d_Vec3> Graphic3d_UniformVec3;
 //! Floating-point uniform 4D vector.
 typedef Graphic3d_UniformValue<Graphic3d_Vec4> Graphic3d_UniformVec4;

+//! Floating-point uniform 3x3 matrix.
+typedef Graphic3d_UniformValue<NCollection_Mat3<float>> Graphic3d_UniformMat3;
+
+//! Floating-point uniform 4x4 matrix.
+typedef Graphic3d_UniformValue<Graphic3d_Mat4> Graphic3d_UniformMat4;
+
 //! Describes custom uniform shader variable.
 class Graphic3d_ShaderVariable : public Standard_Transient
 {
diff --git a/src/OpenGl/OpenGl_ShaderProgram.cxx b/src/OpenGl/OpenGl_ShaderProgram.cxx
index 85ec01d4aa..691e9ee0b0 100755
--- a/src/OpenGl/OpenGl_ShaderProgram.cxx
+++ b/src/OpenGl/OpenGl_ShaderProgram.cxx
@@ -120,6 +120,8 @@ OpenGl_VariableSetterSelector::OpenGl_VariableSetterSelector()
     (Graphic3d_UniformValueTypeID<OpenGl_Vec2>::ID,  new OpenGl_VariableSetter<OpenGl_Vec2>())
     (Graphic3d_UniformValueTypeID<OpenGl_Vec3>::ID,  new OpenGl_VariableSetter<OpenGl_Vec3>())
     (Graphic3d_UniformValueTypeID<OpenGl_Vec4>::ID,  new OpenGl_VariableSetter<OpenGl_Vec4>())
+    (Graphic3d_UniformValueTypeID<NCollection_Mat3<float>>::ID, new OpenGl_VariableSetter<NCollection_Mat3<float>>())
+    (Graphic3d_UniformValueTypeID<OpenGl_Mat4>::ID,  new OpenGl_VariableSetter<OpenGl_Mat4>())
     (Graphic3d_UniformValueTypeID<OpenGl_Vec2i>::ID, new OpenGl_VariableSetter<OpenGl_Vec2i>())
     (Graphic3d_UniformValueTypeID<OpenGl_Vec3i>::ID, new OpenGl_VariableSetter<OpenGl_Vec3i>())
     (Graphic3d_UniformValueTypeID<OpenGl_Vec4i>::ID, new OpenGl_VariableSetter<OpenGl_Vec4i>());
@@ -1198,6 +1200,24 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
   return Standard_True;
 }

+// =======================================================================
+// function : SetUniform
+// purpose  : Specifies the value of the floating-point uniform 3x3 matrix
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&  theCtx,
+                                                   GLint                          theLocation,
+                                                   const NCollection_Mat3<float>& theValue,
+                                                   GLboolean                      theTranspose)
+{
+  if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
+  {
+    return Standard_False;
+  }
+
+  theCtx->core20fwd->glUniformMatrix3fv (theLocation, 1, GL_FALSE, theTranspose ? theValue.Transposed().GetData() : theValue.GetData());
+  return Standard_True;
+}
+
 // =======================================================================
 // function : SetUniform
 // purpose  : Specifies the value of the floating-point uniform 4x4 matrix
diff --git a/src/OpenGl/OpenGl_ShaderProgram.hxx b/src/OpenGl/OpenGl_ShaderProgram.hxx
index 92d74e54ef..340cd0ceae 100755
--- a/src/OpenGl/OpenGl_ShaderProgram.hxx
+++ b/src/OpenGl/OpenGl_ShaderProgram.hxx
@@ -510,6 +510,23 @@ public:
                                                GLuint                         theCount,
                                                const NCollection_Mat3<float>* theData);

+  //! Specifies the value of the float uniform 3x3 matrix.
+  //! Wrapper for glUniformMatrix3fv()
+  bool SetUniform (const Handle(OpenGl_Context)&  theCtx,
+                   const GLchar*                  theName,
+                   const NCollection_Mat3<float>& theValue,
+                   GLboolean                      theTranspose = GL_FALSE)
+  {
+    return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
+  }
+
+  //! Specifies the value of the float uniform 3x3 matrix.
+  //! Wrapper for glUniformMatrix3fv()
+  Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)&  theCtx,
+                                               GLint                          theLocation,
+                                               const NCollection_Mat3<float>& theValue,
+                                               GLboolean                      theTranspose = GL_FALSE);
+
   //! Specifies the value of the float uniform 4x4 matrix.
   //! Wrapper for glUniformMatrix4fv()
   bool SetUniform (const Handle(OpenGl_Context)& theCtx,
-- 
2.43.0