Visualization, Graphic3d_ShaderProgram - add mat3/mat4 types to PushVariable (#1112)

Port of commit 1e1584357 adapted to the new source layout
and modern NCollection_Mat3/NCollection_Mat4 types.

- Graphic3d_ShaderVariable: register NCollection_Mat3<float> and
  NCollection_Mat4<float> type IDs; add template instantiations
  and Graphic3d_UniformMat3/Graphic3d_UniformMat4 typedefs.
- Graphic3d_ShaderProgram: add PushVariableMat3() and PushVariableMat4()
  convenience methods.
- OpenGl_ShaderProgram: add single-value SetUniform() for mat3
  (wrapping glUniformMatrix3fv); register mat3/mat4 in
  OpenGl_VariableSetterSelector so custom uniforms are dispatched.
- ViewerTest (vshader command): add -vec2, -vec3, -vec4, -mat3, -mat4
  argument parsing for setting custom uniform variables from Draw Harness.
- Add Draw Harness test exercising the new uniform types.
This commit is contained in:
Kirill Gavrilov
2026-02-23 18:16:45 +00:00
committed by dpasukhi
parent e8012824d6
commit be39f6f6be
7 changed files with 199 additions and 1 deletions

View File

@@ -25,6 +25,8 @@
#include <V3d_View.hxx>
#include <V3d_Viewer.hxx>
#include <NCollection_Mat3.hxx>
#include <NCollection_Mat4.hxx>
#include <Standard_Transient.hxx>
#include <TCollection_AsciiString.hxx>
#include <NCollection_DoubleMap.hxx>
@@ -296,6 +298,59 @@ static int VShaderProg(Draw_Interpretor&, int theArgNb, const char** theArgVec)
TCollection_AsciiString aName = theArgVec[++anArgIter];
aProgram->PushVariableFloat(aName, float(Draw::Atof(theArgVec[++anArgIter])));
}
else if (!aProgram.IsNull() && anArg == "-vec2" && anArgIter + 3 < theArgNb)
{
const TCollection_AsciiString aName = theArgVec[++anArgIter];
const NCollection_Vec2<float> aVec(float(Draw::Atof(theArgVec[anArgIter + 1])),
float(Draw::Atof(theArgVec[anArgIter + 2])));
anArgIter += 2;
aProgram->PushVariableVec2(aName, aVec);
}
else if (!aProgram.IsNull() && anArg == "-vec3" && anArgIter + 4 < theArgNb)
{
const TCollection_AsciiString aName = theArgVec[++anArgIter];
const NCollection_Vec3<float> aVec(float(Draw::Atof(theArgVec[anArgIter + 1])),
float(Draw::Atof(theArgVec[anArgIter + 2])),
float(Draw::Atof(theArgVec[anArgIter + 3])));
anArgIter += 3;
aProgram->PushVariableVec3(aName, aVec);
}
else if (!aProgram.IsNull() && anArg == "-vec4" && anArgIter + 5 < theArgNb)
{
const TCollection_AsciiString aName = theArgVec[++anArgIter];
const NCollection_Vec4<float> aVec(float(Draw::Atof(theArgVec[anArgIter + 1])),
float(Draw::Atof(theArgVec[anArgIter + 2])),
float(Draw::Atof(theArgVec[anArgIter + 3])),
float(Draw::Atof(theArgVec[anArgIter + 4])));
anArgIter += 4;
aProgram->PushVariableVec4(aName, aVec);
}
else if (!aProgram.IsNull() && anArg == "-mat3" && anArgIter + 10 < theArgNb)
{
const TCollection_AsciiString aName = theArgVec[++anArgIter];
NCollection_Mat3<float> aMat;
for (int aRowIter = 0; aRowIter < 3; ++aRowIter)
{
for (int aColIter = 0; aColIter < 3; ++aColIter)
{
aMat.SetValue(aRowIter, aColIter, float(Draw::Atof(theArgVec[++anArgIter])));
}
}
aProgram->PushVariableMat3(aName, aMat);
}
else if (!aProgram.IsNull() && anArg == "-mat4" && anArgIter + 17 < theArgNb)
{
const TCollection_AsciiString aName = theArgVec[++anArgIter];
NCollection_Mat4<float> aMat;
for (int aRowIter = 0; aRowIter < 4; ++aRowIter)
{
for (int aColIter = 0; aColIter < 4; ++aColIter)
{
aMat.SetValue(aRowIter, aColIter, float(Draw::Atof(theArgVec[++anArgIter])));
}
}
aProgram->PushVariableMat4(aName, aMat);
}
else if (!aProgram.IsNull() && aProgram->ShaderObjects().IsEmpty()
&& (anArg == "-off" || anArg == "off"))
{
@@ -1175,6 +1230,8 @@ vshader name -vert VertexShader -frag FragmentShader [-geom GeometryShader]
[-header VersionHeader]
[-tessControl TessControlShader -tessEval TessEvaluationShader]
[-uniform Name FloatValue]
[-vec2 Name X Y] [-vec3 Name X Y Z] [-vec4 Name X Y Z W]
[-mat3 Name V1..V9] [-mat4 Name V1..V16]
[-defaultSampler {0|1}]=1
Assign custom GLSL program to presentation aspects.
)" /* [vshader] */);

View File

@@ -135,7 +135,11 @@ OpenGl_VariableSetterSelector::OpenGl_VariableSetterSelector()
Graphic3d_UniformValueTypeID<NCollection_Vec3<int>>::ID,
new OpenGl_VariableSetter<NCollection_Vec3<int>>())(
Graphic3d_UniformValueTypeID<NCollection_Vec4<int>>::ID,
new OpenGl_VariableSetter<NCollection_Vec4<int>>());
new OpenGl_VariableSetter<NCollection_Vec4<int>>())(
Graphic3d_UniformValueTypeID<NCollection_Mat3<float>>::ID,
new OpenGl_VariableSetter<NCollection_Mat3<float>>())(
Graphic3d_UniformValueTypeID<NCollection_Mat4<float>>::ID,
new OpenGl_VariableSetter<NCollection_Mat4<float>>());
}
// =======================================================================
@@ -1267,6 +1271,26 @@ bool OpenGl_ShaderProgram::SetUniform(const occ::handle<OpenGl_Context>& theCtx,
return true;
}
//=================================================================================================
bool OpenGl_ShaderProgram::SetUniform(const occ::handle<OpenGl_Context>& theCtx,
GLint theLocation,
const NCollection_Mat3<float>& theValue,
GLboolean theTranspose)
{
if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
{
return false;
}
theCtx->core20fwd->glUniformMatrix3fv(theLocation,
1,
GL_FALSE,
theTranspose ? theValue.Transposed().GetData()
: theValue.GetData());
return true;
}
// =======================================================================
// function : SetUniform
// purpose : Specifies the value of the floating-point uniform 4x4 matrix

View File

@@ -496,6 +496,23 @@ public:
GLuint theCount,
const NCollection_Mat3<float>* theData);
//! Specifies the value of the float uniform 3x3 matrix.
//! Wrapper for glUniformMatrix3fv()
bool SetUniform(const occ::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 bool SetUniform(const occ::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 occ::handle<OpenGl_Context>& theCtx,

View File

@@ -244,6 +244,20 @@ public:
return PushVariable(theName, theValue);
}
//! Pushes mat3 uniform.
bool PushVariableMat3(const TCollection_AsciiString& theName,
const NCollection_Mat3<float>& theValue)
{
return PushVariable(theName, theValue);
}
//! Pushes mat4 uniform.
bool PushVariableMat4(const TCollection_AsciiString& theName,
const NCollection_Mat4<float>& theValue)
{
return PushVariable(theName, theValue);
}
public:
//! The path to GLSL programs determined from CSF_ShadersDirectory or CASROOT environment
//! variables.

View File

@@ -26,6 +26,8 @@ template struct Graphic3d_UniformValue<NCollection_Vec4<float>>;
template struct Graphic3d_UniformValue<NCollection_Vec2<int>>;
template struct Graphic3d_UniformValue<NCollection_Vec3<int>>;
template struct Graphic3d_UniformValue<NCollection_Vec4<int>>;
template struct Graphic3d_UniformValue<NCollection_Mat3<float>>;
template struct Graphic3d_UniformValue<NCollection_Mat4<float>>;
// =======================================================================
// function : ~Graphic3d_ValueInterface

View File

@@ -24,6 +24,7 @@
#include <NCollection_Vec4.hxx>
#include <NCollection_Mat3.hxx>
#include <NCollection_Mat4.hxx>
#include <Standard_Transient.hxx>
#include <TCollection_AsciiString.hxx>
@@ -101,6 +102,18 @@ struct Graphic3d_UniformValueTypeID<NCollection_Vec4<int>>
static const size_t ID = __LINE__;
};
template <>
struct Graphic3d_UniformValueTypeID<NCollection_Mat3<float>>
{
static const size_t ID = __LINE__;
};
template <>
struct Graphic3d_UniformValueTypeID<NCollection_Mat4<float>>
{
static const size_t ID = __LINE__;
};
//! Describes specific value of custom uniform variable.
template <class T>
struct Graphic3d_UniformValue : public Graphic3d_ValueInterface
@@ -142,6 +155,12 @@ typedef Graphic3d_UniformValue<NCollection_Vec3<float>> Graphic3d_UniformVec3;
//! Floating-point uniform 4D vector.
typedef Graphic3d_UniformValue<NCollection_Vec4<float>> Graphic3d_UniformVec4;
//! Floating-point uniform 3x3 matrix.
typedef Graphic3d_UniformValue<NCollection_Mat3<float>> Graphic3d_UniformMat3;
//! Floating-point uniform 4x4 matrix.
typedef Graphic3d_UniformValue<NCollection_Mat4<float>> Graphic3d_UniformMat4;
//! Describes custom uniform shader variable.
class Graphic3d_ShaderVariable : public Standard_Transient
{

View File

@@ -0,0 +1,65 @@
puts "========"
puts "Test custom uniform variables: -vec2, -vec3, -vec4, -mat3, -mat4"
puts "========"
pload MODELING VISUALIZATION
# draw a box
box b 1 2 3
vclear
vclose ALL
vinit View1
vsetdispmode 1
vaxo
vdisplay b
vfit
vrotate 0.2 0.0 0.0
set aGlslVer "#version 110"
if { [vdriver -default] == "TKOpenGles" } { set aGlslVer "#version 300 es" }
# vertex shader applying a mat4 uniform transform and passing a vec4 color to fragment
set aShaderVert "
uniform mat4 uModelTrsf;
uniform mat3 uNormTrsf;
uniform vec4 uColor;
uniform vec3 uLightDir;
uniform vec2 uScale;
THE_SHADER_OUT vec4 vColor;
THE_SHADER_OUT vec3 vNormal;
void main() {
vec4 aPos = uModelTrsf * occVertex;
aPos.xy *= uScale;
vNormal = normalize(uNormTrsf * occNormal.xyz);
vColor = uColor;
gl_Position = occProjectionMatrix * occWorldViewMatrix * aPos;
}"
# fragment shader using the passed color and simple diffuse lighting
set aShaderFrag "
uniform vec3 uLightDir;
THE_SHADER_IN vec4 vColor;
THE_SHADER_IN vec3 vNormal;
void main() {
float aNdotL = max(dot(normalize(vNormal), normalize(uLightDir)), 0.2);
occSetFragColor(vec4(vColor.rgb * aNdotL, vColor.a));
}"
# identity mat4 (row-major: 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1)
# identity mat3 (row-major: 1 0 0 0 1 0 0 0 1)
vshaderprog b -vert $aShaderVert -frag $aShaderFrag -header "$aGlslVer" \
-mat4 uModelTrsf 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 \
-mat3 uNormTrsf 1 0 0 0 1 0 0 0 1 \
-vec4 uColor 0.2 0.6 1.0 1.0 \
-vec3 uLightDir 0.0 0.0 1.0 \
-vec2 uScale 1.0 1.0
vdump $::imagedir/${::casename}_identity.png
# apply a non-identity mat4 (translation by 0.5 in X)
vshaderprog b -vert $aShaderVert -frag $aShaderFrag -header "$aGlslVer" \
-mat4 uModelTrsf 1 0 0 0.5 0 1 0 0 0 0 1 0 0 0 0 1 \
-mat3 uNormTrsf 1 0 0 0 1 0 0 0 1 \
-vec4 uColor 1.0 0.4 0.2 1.0 \
-vec3 uLightDir 1.0 1.0 1.0 \
-vec2 uScale 0.8 0.8
vdump $::imagedir/${::casename}_translated.png