【问题标题】:Direct State Access (DSA) is Failing, but pre 4.3 OpenGL works直接状态访问 (DSA) 失败,但 4.3 之前的 OpenGL 有效
【发布时间】:2021-04-07 16:39:32
【问题描述】:

我目前有一个 OpenGL 项目,其中我使用 GLFW 来创建窗口和上下文,并使用 GLAD 来加载 OpenGL 函数。我使用的 GLAD 版本是 OpenGL 4.6,兼容配置文件,具有所有扩展(包括 ARB_direct_state_access)。

我当前的显卡设置是

OpenGL Version: 4.6.0 NVIDIA 457.09
GLSL Version: 4.60 NVIDIA
Renderer: GeForce GTX 970/PCIe/SSE2
Vendor: NVIDIA Corporation

当我运行以下非 DSA 代码时,它运行良好。

// Create vertex array object and bind it
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

// Create an index buffer object and use the data in the indices vector
GLuint ibo;
glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicies.size()*sizeof(GLint), indicies.data(), GL_STATIC_DRAW);

// Create a array buffer object and use the positional data which has x,y,z components
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, positions.size()*sizeof(GLfloat), positions.data(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);

但是,当我尝试将此代码转换为 DSA 格式并运行它时,程序会打开一个窗口,然后在没有有用的调试信息的情况下终止。

GLuint vao;
glGenVertexArrays(1, &vao);

GLuint vbo;
glCreateBuffers(1, &vbo);
glNamedBufferStorage(vbo, positions.size()*sizeof(GLfloat), positions.data(), GL_DYNAMIC_STORAGE_BIT);
glVertexArrayVertexBuffer(vao, 0, vbo, 0, 0);
glEnableVertexArrayAttrib(vao, 0);
glVertexArrayAttribFormat(vao, 0, 3, GL_FLOAT, GL_FALSE, 0);
glVertexArrayAttribBinding(vao, 0, 0);

GLuint ibo;
glCreateBuffers(1, &ibo);
glNamedBufferStorage(ibo, sizeof(GLint)*indicies.size(), indicies.data(), GL_DYNAMIC_STORAGE_BIT);
glVertexArrayElementBuffer(vao, ibo);

在这两种情况下,我都会在绘制之前绑定顶点数组对象

glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, indicies.size(), GL_UNSIGNED_INT, 0);

为什么我的 DSA 类代码不起作用?

【问题讨论】:

    标签: c++ opengl glfw glad direct-state-access


    【解决方案1】:

    当您使用 glVertexArrayVertexBuffer 时,您必须指定 stride 参数。当 stride 为 0 时,通用顶点属性被理解为紧密打包的特殊情况,如使用 glVertexAttribPointer 时,在使用 glVertexArrayVertexBuffer 时不适用。

    glVertexArrayVertexBuffer(vao, 0, vbo, 0, 0);

    glVertexArrayVertexBuffer(vao, 0, vbo, 0, 3*sizeof(float));
    

    stride为0不会报错,但不代表有意义。

    【讨论】:

    • 哇,我觉得我永远不会捕捉到这样的细节。非常感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多