As the title suggests, I'm trying to find the cause of a bug in my program. glBindVertexArray()
creates a GL_INVALID_OPERATION when drawing a scene in my program, even though I have properly initialized it beforehand.
The program uses Qt 5.15, with the help of the libQGLViewer library. It is composed of multiple QGLViewer instances on the same screen, and uses an underlying Scene
class in order to draw the same content from the same buffers/textures/VBOs in multiple Qt widgets.
The Scene
class inherits from the QOpenGLFunction_4_0_Core
class, making it OpenGL 4.0 compliant and thus able to use VAOs/VBOs. Here's the problem : I have a couple of draw functions, depending on the type of widget asking for the draw. Here's an overview of the code that triggers a 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 ...
}
In my initGL()
functions, one of the only thing it does is call the initScene()
function, which checks if the scene has been initialized (or began to be initialized) already using the Scene::isInitialized
boolean member (so the scene is not initialized twice). In the initScene()
function, I call this->initializeOpenGLFunctions()
in order to have the OpenGL function pointers provided by Qt initialized to the right values, which will later allow me to draw the scene in the different viewers. Speaking of which, here's the overview of the code for the different draw functions :
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 ...
// ...
}
What doesn't make sense is the fact that at the VAO's creation/specification time, the handle is valid, but it is not anymore when drawing !
I did call QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
before the creation of my QMainWindow
/QApplication
in order for the OpenGL viewers to share the same context, but this hasn't changed anything, everytime the VAO is bound, the operation always returns GL_INVALID_OPERATION
which according to the OpenGL spec can only happen when the VAO hasn't been created with a previous call to glGenVertexArrays()
/glBindVertexArrays()
!
I have tried for a few days on and off to get this problem fixed, but I cannot seem to get it fixed. Has anyone had experience debugging OpenGL/Qt programs like that before ? There doesn't seem to be a whole lot of people who use recent desktop OpenGL versions with Qt on help forums ...