非 DSA 工作时 OpenGL DSA 代码不工作
Posted
技术标签:
【中文标题】非 DSA 工作时 OpenGL DSA 代码不工作【英文标题】:OpenGL DSA code not working while non-DSA works 【发布时间】:2021-07-13 00:25:56 【问题描述】:这是工作代码:
glGenVertexArrays(1, &_vao);
glBindVertexArray(_vao);
glGenBuffers(1, &_vbo);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
auto vertexCount = _vertices.size();
auto vertexSize = sizeof(Vertex);
auto totalSize = vertexCount * vertexSize;
glBufferData(GL_ARRAY_BUFFER, totalSize, _vertices.data(), GL_STATIC_DRAW);
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, vertexSize, (GLvoid*)offsetof(Vertex, position));
glEnableVertexAttribArray(4);
glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, vertexSize, (GLvoid*)offsetof(Vertex, normal));
glEnableVertexAttribArray(5);
glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, vertexSize, (GLvoid*)offsetof(Vertex, color));
glEnableVertexAttribArray(6);
glVertexAttribPointer(7, 2, GL_FLOAT, GL_FALSE, vertexSize, (GLvoid*)offsetof(Vertex, uv));
glEnableVertexAttribArray(7);
glVertexAttribIPointer(8, 1, GL_SHORT, vertexSize, (GLvoid*)offsetof(Vertex, texIndex));
glEnableVertexAttribArray(8);
if (_indices.size() > 0)
glGenBuffers(1, &_ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, _indices.size() * sizeof(GLuint), _indices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
这是 DSA 版本,奇怪的是,它不起作用。
glCreateVertexArrays(1, &_vao);
auto vertexCount = _vertices.size();
auto vertexSize = sizeof(Vertex);
auto totalSize = vertexCount * vertexSize;
glCreateBuffers(1, &_vbo);
glNamedBufferData(_vbo, totalSize, _vertices.data(), GL_STATIC_DRAW);
glVertexArrayVertexBuffer(_vao, 0, _vbo, 0, vertexSize);
glEnableVertexArrayAttrib(_vao, 4);
glEnableVertexArrayAttrib(_vao, 5);
glEnableVertexArrayAttrib(_vao, 6);
glEnableVertexArrayAttrib(_vao, 7);
glEnableVertexArrayAttrib(_vao, 8);
glVertexArrayAttribBinding(_vao, 4, 0);
glVertexArrayAttribBinding(_vao, 5, 0);
glVertexArrayAttribBinding(_vao, 6, 0);
glVertexArrayAttribBinding(_vao, 7, 0);
glVertexArrayAttribBinding(_vao, 8, 0);
glVertexArrayAttribFormat(_vao, 4, 3, GL_FLOAT, GL_FALSE, offsetof(Vertex, position));
glVertexArrayAttribFormat(_vao, 5, 3, GL_FLOAT, GL_FALSE, offsetof(Vertex, normal));
glVertexArrayAttribFormat(_vao, 6, 4, GL_FLOAT, GL_FALSE, offsetof(Vertex, color));
glVertexArrayAttribFormat(_vao, 7, 2, GL_FLOAT, GL_FALSE, offsetof(Vertex, uv));
glVertexArrayAttribIFormat(_vao, 8, 1, GL_SHORT, offsetof(Vertex, texIndex));
if (_indices.size() > 0)
glCreateBuffers(1, &_ebo);
glNamedBufferData(_ebo, _indices.size() * sizeof(_indices[0]), _indices.data(), GL_STATIC_DRAW);
glVertexArrayElementBuffer(_vao, _ebo);
用第二个代码替换第一个代码会使渲染不产生任何输出。 KHR_debug
和 glGetError
未报告任何错误消息始终返回 0。
【问题讨论】:
将绑定索引从 0 更改为 5 会使 DSA 版本工作,更加混乱。除了这里,我没有对 0 做任何绑定。 【参考方案1】:找到解决方案,我正在实例化我的几何。我在做
VBO vbo;
glCreateBuffers(1, &vbo);
glNamedBufferData(vbo, defaultSize * m4s, nullptr, GL_DYNAMIC_DRAW);
for (auto& mesh : model.lock()->_meshes)
glVertexArrayVertexBuffer(mesh._vao, 1, vbo, 0, m4s);
glEnableVertexArrayAttrib(mesh._vao, 0);
glEnableVertexArrayAttrib(mesh._vao, 1);
glEnableVertexArrayAttrib(mesh._vao, 2);
glEnableVertexArrayAttrib(mesh._vao, 3);
glVertexArrayAttribBinding(mesh._vao, 0, 1);
glVertexArrayAttribBinding(mesh._vao, 1, 1);
glVertexArrayAttribBinding(mesh._vao, 2, 1);
glVertexArrayAttribBinding(mesh._vao, 3, 1);
glVertexArrayAttribFormat(mesh._vao, 0, 4, GL_FLOAT, GL_FALSE, v4s * 0);
glVertexArrayAttribFormat(mesh._vao, 1, 4, GL_FLOAT, GL_FALSE, v4s * 1);
glVertexArrayAttribFormat(mesh._vao, 2, 4, GL_FLOAT, GL_FALSE, v4s * 2);
glVertexArrayAttribFormat(mesh._vao, 3, 4, GL_FLOAT, GL_FALSE, v4s * 3);
glVertexArrayBindingDivisor(mesh._vao, 0, 1);
glVertexArrayBindingDivisor(mesh._vao, 1, 1);
glVertexArrayBindingDivisor(mesh._vao, 2, 1);
glVertexArrayBindingDivisor(mesh._vao, 3, 1);
看到最后 4 个 gl 调用了吗?这就是问题所在。我以为第二个参数是顶点属性索引(2.param 到 glEnableVertexArrayAttrib),而实际上它是缓冲区绑定索引(2.param 到 glVertexArrayVertexBuffer)。删除带有 0、2 和 3 的行可以解决问题。
【讨论】:
以上是关于非 DSA 工作时 OpenGL DSA 代码不工作的主要内容,如果未能解决你的问题,请参考以下文章