我试图写一个非常简单的游戏引擎来学习它们内部的工作方式,我已经到了这样的地步,我有一个“客户端”应用程序向引擎发送工作。到目前为止,这是可行的,但我遇到的问题是,我的测试三角形只有在我从“主”函数绑定缓冲区时才能呈现(或者在创建缓冲区的地方)
甚至当缓冲区被抽象并且具有相同的函数和相同的成员值(使用clion的调试器验证),但它们 * 仍然 * 必须绑定在创建它们的函数中时,情况也是如此
例如,我有这样的代码来创建缓冲区并设置它们的数据
...
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);
...
其中vertices是6个浮点数的c数组,索引为3个无符号整型数
然后将缓冲区传递到“上下文”以存储用于稍后使用以下代码进行渲染
...
context.addBuffer(vertexBuffer);
context.addBuffer(indexBuffer);
context.setNumVertices(3);
context.setNumIndices(3);
context.
...
其调用:buffer.bind()
Task& task = m_tasks.back();
task.buffers.push_back(std::move(buffer));
这同样有效。缓冲区被正确存储,当代码到达这里时缓冲区仍然存在,没有任何错误。
- 然后 * 到达缓冲区所在的绘图部分:绑定、绘制,然后解除绑定,如下所示
...
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();
}
...
约束和解除约束是这些功能
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);
}
如果我从“doWork”函数调用buffer.bind(),在这个函数中绘制缓冲区,什么都不会呈现,但是如果我从main函数调用buffer.bind(),我会在屏幕中间得到一个白色三角形
即使当我绑定然后解除绑定缓冲区从主缓冲区封装,这是问题,它仍然没有绘制。只有当缓冲区是绑定和 * 保持 * 绑定从主函数,这是绘制
完整代码的粘贴框(无标题)
pastebin
有没有人知道 * 为什么 * 会发生这种情况,即使你不知道如何修复它。这是与缓冲区寿命有关,还是与将缓冲区移动到向量中有关?只是buffer.bind()
不工作,上传数据从上下文工作,只是没有绑定它
1条答案
按热度按时间vbopmzt11#
在调用
glVertexAttribPointer
之前,您似乎没有将顶点缓冲区绑定到GL_ARRAY_BUFFER
缓冲区绑定点。glVertexAttribPointer
使用绑定到GL_ARRAY_BUFFER
的缓冲区,以便知道哪个缓冲区是该通用顶点属性的顶点属性源。因此,您应该在呼叫
glVertexAttribPointer
之前系结vertexBuffer。