正如标题所示,我正在尝试找出程序中出现错误的原因。glBindVertexArray()
在我的程序中绘制场景时创建一个 GL_INVALID_OPERATION,即使我事先已正确初始化它。
该程序在libQGLViewer库的帮助下使用 Qt 5.15 。它由同一屏幕上的多个 QGLViewer 实例组成,并使用底层Scene
类从多个 Qt 小部件中的相同缓冲区/纹理/VBO 中绘制相同的内容。
该类Scene
继承自QOpenGLFunction_4_0_Core
该类,使其兼容 OpenGL 4.0,因此能够使用 VAO/VBO。问题是:我有几个绘图函数,具体取决于请求绘图的小部件类型。以下是触发 draw 的代码概述:
// in viewer1.hpp :
class Viewer1 : public QGLViewer {
// ...
virtual void initGL() override; // Overrides QGLViewer's initGL function, similar to the QOpenGLWidget function of the same name
virtual void draw() override; // Overrides QGLViewer's draw function
protected:
Scene* scene;
// ...
}
// In viewer2.hpp :
class Viewer2 : public QGLViewer {
// ...
virtual void initGL() override; // Overrides QGLViewer's initGL function, similar to the QOpenGLWidget function of the same name
virtual void draw() override; // Overrides QGLViewer's draw function
protected:
Scene* scene;
// ...
}
// In scene.hpp :
void GetOpenGLError(); // <- Checks OpenGL error(s) and prints them, clearing the error state
class Scene : public QOpenGLFunctions_4_0_Core {
// ...
void initScene();
void drawFromViewer1(GLfloat* vMat, GLfloat* pMat);
void drawFromViewer2(GLfloat* vMat, GLfloat* pMat);
protected:
bool isInitialized;
GLuint vaoHandle;
// I have a special technique of volumetric drawing with difficult
// requirements which cannot be handled with the other VAO :
GLuint vaoHandle_volumetric;
// other opengl 'handles' (OpenGL names/IDs) to VBOs, textures ...
}
在我的initGL()
函数中,它唯一做的一件事就是调用该initScene()
函数,该函数检查场景是否已经使用Scene::isInitialized
布尔成员初始化(或开始初始化)(因此场景没有初始化两次)。在initScene()
函数中,我调用this->initializeOpenGLFunctions()
以将 Qt 提供的 OpenGL 函数指针初始化为正确的值,这将允许我稍后在不同的查看器中绘制场景。说到这里,下面是不同绘制函数的代码概述:
void Scene::initScene() {
// ...
glGenVertexArrays(1, &this->vaoHandle);
GetOpenGLError(); // <- Prints nothing
glBindVertexArray(this->vaoHandle);
GetOpenGLError(); // <- Prints nothing
if (glIsVertexArray(this->vaoHandle) == GL_FALSE) {
throw std::runtime_error("VAO error in initScene()"); // <- doesn't get triggered
}
// Specify VAO state and pointers (...)
// ...
}
void Scene::drawFromViewer1(GLfloat* vMat, GLfloat* pMat) {
// Set the uniforms for the draw
glBindVertexArray(this->vaoHandle);
GetOpenGLError(); // <- Prints GL_INVALID_OPERATION !!!
// Draw after binding index buffer ...
// ...
}
void Scene::drawFromViewer2(GLfloat* vMat, GLfloat* pMat) {
// Set the uniforms for the draw
glBindVertexArray(this->vaoHandle);
GetOpenGLError(); // <- Prints GL_INVALID_OPERATION !!!
// Draw after binding index buffer ...
// ...
}
没有意义的是,在 VAO 的创建/规范时,句柄是有效的,但在绘图时不再有效!
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
我在创建QMainWindow
/之前确实调用了QApplication
,以便 OpenGL 查看器共享相同的上下文,但这并没有改变任何东西,每次绑定 VAO 时,操作总是返回GL_INVALID_OPERATION
,根据 OpenGL 规范,只有在之前调用glGenVertexArrays()
/没有创建 VAO glBindVertexArrays()
!
我断断续续地尝试了几天来解决这个问题,但我似乎无法解决它。有没有人有过调试 OpenGL/Qt 程序的经验?在帮助论坛上使用 Qt 的最新桌面 OpenGL 版本的人似乎并不多……