我正在尝试在我的程序中使用基本着色器加载,但是在加载之后,我得到一个未处理的异常弹出框。我已经创建了一个基类来完成加载通用着色器的所有常见部分。在基类中,我有一个受保护的虚函数和公共函数来处理OpenGL属性。以下是两个基本的例子:
class ShaderProgram // Base class
{
public:
...
protected:
void bindAttribute(GLuint attribNumber, const char* variableName);
virtual void bindAttributes() = 0; // needed for different shaders
private:
GLuint programID;
void loadShaders(const char* vertFile, const char* fragFile);
}
class BasicShader : public ShaderProgram // derived class
{
public:
...
protected:
void bindAttributes() { bindAttribute(0, "position"); }
...
}
现在在loadShaders()
内:
programID = glCreateProgram();
glAttachShader(programID, vertexShaderID);
glAttachShader(programID, fragmentShaderID);
glLinkProgram(programID);
bindAttributes(); // Unhandled Exception pointing here
我尝试运行时遇到此错误。但如果我将bindAttributes()
替换为glBindAttribLocation(programID, 0, "position")
中调用的bindAttribute()
,程序将按预期运行。有关导致此错误的原因的任何想法?
答案 0 :(得分:2)
我发现loadShaders()
对ShaderProgram
是私有的。根据您描述的症状和解决方法,我怀疑您从类的构造函数中调用它。
如果是这种情况,那是因为在构造过程中使用了纯虚函数。更具体地说,从基类BasicShader
派生的类ShaderProgram
的构建过程是这样的:
ShaderProgram
的基础对象。此时对象只是ShaderProgramm
。虚拟
您可以在其构造函数中调用的函数仍然是基类中定义的函数。 BasicShader
的虚函数将生效。 因此,如果您从loadShaders()
的构造函数中调用ShaderProgramm
,它将最终尝试在它仍然是纯虚函数(即未定义)时调用bindAttributes()
。
标准10.4 / 6:可以从构造函数中调用成员函数 (或析构函数)抽象类;制作虚拟的效果 直接或间接地为对象调用纯虚函数 从这样的构造函数(或析构函数)创建(或销毁) 未定义。
有两种解决方案:
loadShaders()
的构造函数而不是BasicShader
的构造函数中调用ShaderProgram
。这要求您使功能受保护而不是私有。 如果我的假设是错误的并且您没有从构造函数中调用loadShaders()
,请将代码发布到您调用的位置,以及其参数的初始化,并且我将更新回答。