I'm trying to write a very barebones game engine to learn how they work internally and I've gotten to the point where I have a "client" app sending work to the engine. This works so far but the problem I am having is that my test triangle only renders when I bind the buffer from the "main" function (or wherever the buffers were created)
This is even the case when the buffers are abstracted and have the same function with the same member values (validated using clion's debugger) but they still have to be bound in the function that created them
for example I have this code to create the buffers and set their data
...
Venlette::Graphics::Buffer vertexBuffer;
Venlette::Graphics::Buffer indexBuffer;
vertexBuffer.setTarget(GL_ARRAY_BUFFER);
indexBuffer.setTarget(GL_ELEMENT_ARRAY_BUFFER);
vertexBuffer.setData(vertices, sizeof(vertices));
indexBuffer.setData(indices, sizeof(indices));
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float)*2, nullptr);
...
where vertices is a c array of 6 floats and indices being 3 unsigned int's
the buffers are then passed to a "context" to be stored for rendering later using the following code
...
context.addBuffer(vertexBuffer);
context.addBuffer(indexBuffer);
context.setNumVertices(3);
context.setNumIndices(3);
context.
...
which calls: addBuffer
Task& task = m_tasks.back();
task.buffers.push_back(std::move(buffer));
this again, works. The buffers are stored correctly, the buffers still exist when the code reaches here and nothing is wrong.
then it gets to the drawing part where the buffers are: bound, drawn, then unbound, as shown
...
for (auto& buffer : task.buffers) {
buffer.upload();
buffer.bind();
}
glDrawElements(GL_TRIANGLES, task.numIndices, GL_UNSIGNED_INT, nullptr);
for (auto& buffer : task.buffers) {
buffer.unbind();
}
...
bind and unbind being these functions
void Buffer::bind() const noexcept {
if (m_id == -1) return;
glBindBuffer(m_target, m_id);
spdlog::info("bind() -{}-{}-", m_id, m_target);
}
void Buffer::unbind() const noexcept {
if (m_id == -1) return;
glBindBuffer(m_target, 0);
spdlog::info("unbind() -{}-{}-", m_id, m_target);
}
but this is where nothing works. If I call buffer.bind() from the "doWork" function where the buffers are drawn, nothing renders, but if I call buffer.bind() from the main function I get a white triangle in the middle of the screen
Even when I bound then unbound the buffers from the main buffer encase that was the issue it still doesn't draw. Only when the buffers are bound and remain bound from the main function, that is draws
a pastebin of the full code (no headers)
Does anyone know why this happens, even if you don't know how to fix it. is it something to do with buffer lifetime, or with moving the buffer into the vector?
it is just buffer.bind()
that doesn't work, uploading data works from the context, just not binding it
CodePudding user response:
You seem to not bind the vertex buffer to the GL_ARRAY_BUFFER
buffer binding point before calling glVertexAttribPointer
.
glVertexAttribPointer
uses the buffer bound to GL_ARRAY_BUFFER
in order to know which buffer is the vertex attribute source for that generic vertex attribute.
So, you should bind the vertexBuffer before calling glVertexAttribPointer
.