5

我试图将一堆连续的无符号整数作为属性传递给我的 GLSL 着色器。

到目前为止,我想出了

s_number = glGetAttribLocation(shader, "number");

numberData = new GLuint[dotAmount];
for (GLuint i = 0; i < dotAmount; i++) {
    numberData[i] = i;
}

glGenBuffers(1, &vertBuf);
glBindBuffer(GL_ARRAY_BUFFER, vertBuf);

glBufferData(
        GL_ARRAY_BUFFER,
        sizeof(dotAmount),
        numberData,
        GL_STATIC_DRAW
);

渲染函数是

glUseProgram(shader);

[..]

glEnableVertexAttribArray(s_number);
glBindBuffer(GL_ARRAY_BUFFER, vertBuf);

glVertexAttribPointer(
        s_number,
        1,
        GL_UNSIGNED_INT,
        GL_FALSE,
        0,
        BUFFER_OFFSET(0)
);

glDrawArrays(GL_POINTS, 0, dotAmount);

我尝试像这样在顶点着色器中使用数字:

attribute uint number;

(名称“vertBuf”实际上有点误导,因为它不是我想要传递的顶点数据)我使用的是 OpenGL 3 和着色器版本 1.3。

我想要实现的是,我希望着色器被执行dotAmount多次。定位是在着色器中以数学方式完成的。但我得到的只是一个空白屏幕......

我很确定问题不在于着色器。我想绘制点,如果我放入gl_Position = vec4(0.0, 0.0, 0.0, 0.0);顶点着色器,我认为它应该绘制一些东西。

4

2 回答 2

33

您使用错误的 API 调用来指定顶点属性指针。

glVertexAttribPointer (...)用于浮点顶点属性。它很乐意接受整数数据类型的值,但最终该值将转换为浮点数。这就是为什么它有一个参数来控制浮点归一化。启用规范化后,您传递的整数值会使用类型的范围进行调整,以使其适合规范化的浮点范围:(有[-1.0, 1.0]符号)或[0.0, 1.0](无符号);禁用时,整数被有效地视为好像它被强制转换为 a GLfloat

在您的情况下,您不需要上述任何行为。在您的顶点着色器中,您的顶点属性一开始就不是浮点类型,因此让 OpenGL 将您的顶点数组数据转换为浮点数将产生毫无意义的结果。

您需要做的是使用glVertexAttribIPointer (...). 注意这个函数如何缺少用于标准化的布尔值?它会将您的整数顶点数据完全不变地传递给您的顶点着色器,这正是您想要的。


总之:

  1. glVertexAttribPointer (...)有利于为浮点顶点属性(即vec<N>, mat4, float)提供数据,并且会为您进行数据类型转换。

  2. glVertexAttribIPointer (...)专为整数属性(即ivec<N>{u}int)而设计。

于 2013-09-20T22:40:58.647 回答
2

尝试将片段着色器更改为gl_FragColor = vec4(1,0,0,1);这将确保输出颜色使片段可见。

另外,您应该有gl_Position = vec4(0, 0, 0, 1);(原因是 gl_Position 必须在齐次坐标中,这意味着前三个分量将除以第四个。)

于 2013-09-20T15:35:55.780 回答