将glUniform函数作为参数传递(C ++)

时间:2016-10-11 17:14:19

标签: c++ opengl glew

我目前正在编写一个openGL着色器类。我没有使用函数来设置每个统一类型,而是试图将统一函数(例如glUniform1f)作为参数传递。

我目前的尝试看起来像这样:

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

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

但是,我经常遇到转换错误,如:

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

是否可以按预期工作?

由于

注意:如果这很重要,我正在使用GLEW和glfw

2 个答案:

答案 0 :(得分:3)

来自OpenGL加载库的函数指针(特别是那些返回直接从DLL加载的函数的函数)有时会使用与常规函数指针不同的调用约定进行注释。

此类函数指针可互换。

有两种方法可以解决这个问题。您可以使用不同的OpenGL加载库,它处理使用标准调用约定的函数指针(实质上,隐藏它加载的实际指针)。例如,在my glLoadGen loader中,如果使用func_cpp生成器样式,则所有函数都将是常规C ++函数。

否则,您必须更改在接口中声明函数指针的方式,以匹配加载程序的工作方式。例如,如果您正在使用GLEW,则必须执行以下操作:

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

答案 1 :(得分:1)

你也可以在functor的类型上模板化函数,免于处理函数指针语法,调用约定等。这个版本将接受所有可以用文档参数调用的东西(无论是函数,函数对象, lambda等)。它同时也是主要的优势和劣势。希望在下一版本的C ++标准中引入通过概念的类型限制。

template <typename F, typename T1>
// requires: F callable with parameter types GLint, T1
void Shader::setUniform(F fnc, const GLchar* name, const T1 value1) {
    fnc(getUniformLocation(name), value1);
}

int main() {
    ...
    shader.setUniform(glUniform1f, "foo", 3.14f);
}

我同意评论,这并没有太大变化,因为用户仍然键入函数名称和所有参数。 更多&#34;面向对象&#34;方法可能是为制服引入模板化的类,并根据参数类型对其进行专门化(没有多少)。