Alright, so I am having a pretty tenacious issue setting up my OpenGL code. I'm trying to refactor my graphics code into a renderer object, but I can't seem to get to the bottom of a tricky GL_INVALID_OPERATION error (code 1282).
I start by creating a mesh object that initializes a loosely defined collection of OpenGL objects, and manages their lifespan in an attempt at RAII style:
struct OpenGLMesh
{
OpenGLMesh(OpenGLRenderer& renderer,
int shader_index,
const char* fpath);
~OpenGLMesh();
GLuint vbo_;
GLuint ebo_;
GLuint texture_;
std::vector<float> vertices_;
std::vector<unsigned int> indices_;
GLuint shader_id_;
GLuint mvp_id_;
};
OpenGLMesh::OpenGLMesh(OpenGLRenderer& renderer, int shader_index, const char* fpath)
{
glGenBuffers(1, &vbo_);
glGenBuffers(1, &ebo_);
glGenTextures(1, &texture_);
renderer.loadTexture(*this, fpath);
const std::vector<GLuint>& shaders = renderer.getShaders();
shader_id_ = shaders.at(shader_index);
mvp_id_ = glGetUniformLocation(shader_id_, "MVP");
}
OpenGLMesh::~OpenGLMesh()
{
glDeleteBuffers(1, &vbo_);
glDeleteBuffers(1, &ebo_);
glDeleteTextures(1, &texture_);
}
At the same time I have a renderer object that owns the majority of the initialization and rendering functions. For example, the loadTexture function in the above constructor is part of the my OpenGLRenderer class:
OpenGLRenderer::OpenGLRenderer()
{
glGenVertexArrays(1, &vao_); // allocate + assign a VAO to our handle
shaders_.push_back(loadShaders("shaders/texture.vert", "shaders/texture.frag"));
}
OpenGLRenderer::~OpenGLRenderer()
{
std::vector<GLuint>::iterator it;
for (it = shaders_.begin(); it != shaders_.end(); ++it)
{
glDeleteProgram(*it);
}
glDeleteVertexArrays(1, &vao_);
}
My first concern is that compartmentalization of these function calls may have somehow invalidated some part of my OpenGL setup calls. However, the error doesn't make an appearance until I attempt to bind my mesh's VBO.
Below is the code from a stripped down test module I built to debug this issue:
// create the renderer object
OpenGLRenderer renderer;
// create and store a mesh object
std::vector<OpenGLMesh> meshes;
meshes.push_back(OpenGLMesh(renderer, 0, "./assets/dune_glitch.png"));
// SDL Event handling loop
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArray(vao_);
glBindBuffer(GL_ARRAY_BUFFER, mesh.vbo_);
printOpenGLError(); // prints out error code 1282
I've verified that it is definitely this line that breaks every time, although it doesn't seem to send a kill signal until the next iteration of the loop.
I haven't been able to find any insight on this problem - seems like glBindBuffer doesn't normally generate this kind of error. I've also made sure that the mesh.vbo_ ID still points to the same location.
For some reason, my application's stack trace doesn't play well with GDB, so I haven't been able to look at the trace as much as I would normally want to. Any advice would be a help, from debugging tips to possible sources of failure - thanks in advance!
(This is my first real post, let me know if I messed anything up!)