3
votes

is it possible to create a c++ custom matrix class such that we can pass instances of this class to glUniformMatrix? in other words passing instances of this class to the vertex shader.

i ask this question because when i did a computer graphics course we were given a code skeleton for opengl and glsl shader programming. in the code skeleton we had a custom c++ matrix class named mat4. this class contained lots of methods and user defined constructors. but still instances of mat4 used as parameters to glUniformMatrix and this instances were correctly converted to type mat4 in the vertex shader.

in the future i want to use GLM library to create an interface between opengl code to vertex/fragment shaders, but i want to understand the rules and semantics of what data types can be passed to glUniformMatrix, such that instances of this types will be correctly converted to uniform mat4 in the vertex shader.

i think that the key to this behavior is defining operators

operator GLfloat* (); 
operator const GLfloat* () const;

that return static_cast<const GLfloat*>(...) to the begining of the matrix data structure such that it will point to all the matrix in column wise fashion. is this in broad strokes how the GLM library works?

1
Were you using the code from Angel's graphics textbook? It uses the mechanism you describe in the post to allow you to simply pass the name of the variable into glUniformMatrix. Generally speaking, C++ zealots don't like those methods, but they are useful in this type of situation. GLM doesn't use the same mechanism, but you could always derive from those classes to add those methods if you need. Personally, I like the conversion operators, since the other methods rely on exposing the classes' implementation.radical7
i remember that i found angels code in a Google search and it looked the same as the code in our computer graphics course code. i think that the course staff used Angels code and tweaked it to match the course conventions.DontCareBear

1 Answers

3
votes

The various glUniformMatrx*fv() functions expect the matrix is a series of GLfloat values (16 for mat4), consecutively laid out in memory, so passing a pointer to a C/C++ one- or two-dimensional array of floats will work.

GLM uses the following two variants

glm::mat4 m;
glUniform4fv(location, 1, GL_FALSE, &m[0][0]);
// or
glUniform4fv(location, 1, GL_FALSE, glm::value_ptr(m));

They explicitely avoided to implement some mechanism to hide that operation, altough it would be easy to implement.