代码之家  ›  专栏  ›  技术社区  ›  arsenbonbon

将uint属性传递给GLSL

  •  6
  • arsenbonbon  · 技术社区  · 13 年前

    我正试图将一堆连续的无符号整数作为属性传递给我的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); 在顶点着色器中,我认为它应该绘制一些东西。

    2 回复  |  直到 13 年前
        1
  •  35
  •   Andon M. Coleman    13 年前

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

    glVertexAttribPointer (...) 用于浮点顶点属性。它很乐意采用整数数据类型的值,但最终该值将转换为浮点值。这就是为什么它有一个参数来控制浮点规范化。启用规范化后,将使用类型的范围调整您传递的整数值,使其适合规范化浮点范围: [-1.0, 1.0] (签字)或 [0.0, 1.0] (未签名);禁用时,将有效地将整数视为强制转换为 GLfloat .

    在您的情况下,您不希望出现上述两种行为。在顶点着色器中,顶点属性一开始不是浮点类型,因此让OpenGL将顶点数组数据转换为浮点将产生无意义的结果。

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


    综上所述:

    1. glVertexAttribPointer(…) 适用于将数据提供给浮点顶点属性(即。 vec<N> , mat4 , float ),并将为您进行数据类型转换。

    2. glVertexAttribIPointer(…) 是专门为整数属性设计的(即。 ivec<N> , {u}int ).

        2
  •  2
  •   fintelia    13 年前

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

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