【问题标题】:How to use glVertexAttrib如何使用 glVertexAttrib
【发布时间】:2015-03-02 20:35:43
【问题描述】:

对于我的着色器,我不想为所有绘制调用启用所有属性。例如,在一次绘制调用中,我想为存储在顶点缓冲区中的每个顶点使用不同的颜色。所以我使用glEnableVertexAttribArrayglVertexAttribPointer绑定缓冲区,效果很好。

但是我不能使用glVertexAttrib 方法来获取恒定颜色。我误解了这些方法吗? Can you tell if a vertex attribute is enabled from within a vertex shader? 这么说

如果一个属性被禁用,它的值来自常规的 OpenGL 状态。即 glVertexAttrib 函数设置的状态

但是当我禁用glDisableVertexAttribArray 并使用glVertexAttrib 将其设置为常量时,它不会呈现任何内容。如果我尝试在着色器中使用该属性,它只会呈现黑色。

我错过了什么?

编辑:

我的代码是这样的(它有一些抽象,但 gl 函数的调用顺序是这样的)

    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glEnableVertexAttribArray(position);
    glVertexAttribPointer(position, 3, GL_FLOAT, false, sizeof(Vertex), 0);
    glEnableVertexAttribArray(normal);
    glVertexAttribPointer(normal, 3, GL_FLOAT, true, sizeof(Vertex), (void*)(sizeof(Vec3)));
    glEnableVertexAttribArray(color);
    glVertexAttribPointer(color, 4, GL_FLOAT, false, sizeof(Vertex), (void*)(sizeof(Vec3)+sizeof(Vec3)));

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);

    glDrawElements(
        GL_TRIANGLES,
        (edgeCount - 1)*(edgeCount - 1) * 6,
        GL_UNSIGNED_INT,
        (void*)0
        );

但是,当我替换 glEnableVertexAttribArray(color); glVertexAttribPointer(color, 4, GL_FLOAT, false, sizeof(Vertex), (void*)(sizeof(Vec3)+sizeof(Vec3)));

glDisableVertexAttribArray(color);
glVertexAttrib4f(color, 1.0f, 0.0, 0.0, 1.0);

它不起作用。

【问题讨论】:

  • 好吧,那不应该发生。但是,您确定正确使用它吗?请提供代码的相关部分。
  • @derhass 编辑了我的问题
  • 好吧。它应该工作。至少基于您到目前为止提供的那个小代码 sn-p。您应该注意的一件事是,每当您使用启用相应的属性指针。但是您的代码似乎直接在绘图调用之前设置了所需的值,并且这应该绝对有效。我正在使用此功能,到目前为止,在许多不同的实现和平台上都没有错误报告。
  • 看起来问题出在属性位置“0”上,我添加了另一个属性 color2 并将其分配给位置 1,我可以毫无问题地对其进行编辑。奇怪
  • 哦,这样的东西应该避免使用属性位置 0。这将别名为glVertex3f (...) 之类的命令。一些驱动程序特别愚蠢,并且在禁用属性 0 时不喜欢绘制任何东西,这只是处理该特定通用属性的一团糟。

标签: c++ opengl


【解决方案1】:

看起来我的问题是颜色属性的位置为 0,如果未启用该位置,则不会呈现任何内容。

我将位置属性移动到位置 0 (layout(location = 0) attribute vec3 aVertexPosition;),现在我可以安全地启用或禁用颜色属性

【讨论】:

  • 在核心 GL >= 3.2 中,当属性 0 被禁用时,它也应该可以工作。在旧版 GL
  • @derhass:它没有违反规范中的任何内容,但是我遇到的驱动程序数量在使用顶点属性 0 时表现不佳因为位置以外的东西是有关的。 AMD、NV 和 Intel all 似乎都对不成立的属性 0 做出了这样或那样的假设(即使在核心配置文件中)。最有趣的来自 OpenGL 超级圣经中的第一个着色器,一些老司机看到没有启用的顶点属性数组,会跳过除GL_POINTS 之外的所有图元。
  • 作为记录,可以使用glBindAttribLocation 来解决问题。如果要编写没有位置布局属性的 GLSL 1.5 规范,这可能会很有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多