Levy Ehrstein Levy Ehrstein - 1 month ago 18
C++ Question

Passing glUniform functions as parameter (C++)

I am currently writing a openGL shader class. Instead of heaving functions to set each uniform type, i'm trying to pass the uniform function (eg. glUniform1f) as a parameter.

my current try looks something like this:

template <typename T1>
void Shader::setUniform(void (* fnc)(GLint, T1), const GLchar *name, const T1 value1)
{
fnc(getUniformLocation(name), value1);
}


called with

shader.setUniform<GLfloat>(*glUniform1f, "test", 5);


however, I'm constantly getting conversion errors like:

cannot convert argument 1 from 'void (__stdcall *)(GLint,GLfloat)' to 'void (__cdecl *)(GLint,GLfloat)'


Is it possible to get this working as intended?

Thanks

Note: I'm using GLEW and glfw if this is important

Answer

Function pointers from OpenGL loading libraries (particularly those which return functions loaded directly from the DLL) will sometimes be annotated with a different calling convention from regular function pointers.

Such function pointers are not inter-convertible.

There are two ways to handle this. You could use a different OpenGL loading library, one which deals in function pointers that use the standard calling conventions (essentially, hiding the actual pointers it loads). For example, in my glLoadGen loader, if you use the func_cpp generator style, all functions will be regular C++ functions.

Otherwise, you will have to change how your function pointer is declared in your interface to match how your loader works. For example, if you're using GLEW, you would have to do something like this:

void Shader::setUniform(void (GLAPIENTRY* fnc)(GLint, T1), const GLchar *name, const T1 value1)