非 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_debugglGetError 未报告任何错误消息始终返回 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 代码不工作的主要内容,如果未能解决你的问题,请参考以下文章

glReadPixels 的 OpenGL DSA 等效项

源代码防泄密-DSA数据安全隔离

RSA/DSA 密钥的工作原理

使用GO代码实现 百度联盟媒体平台的DSA签名

使用GO代码实现 百度联盟媒体平台的DSA签名

iOS端使用DSA加密