关于glVertexAttrib ...函数的困惑

时间:2018-08-07 07:21:29

标签: opengl

经过大量搜索,我仍然对glVertexAttrib...函数(glVertexAttrib1dglVertexAttrib1f等)的用途及其用途感到困惑。

通过阅读this questiondocumentation,我目前的理解是,它们的目的是以某种方式将顶点属性设置为常量(即,不使用数组缓冲区)。但是文档还讨论了它们如何与“通用顶点属性”进行交互,这些属性定义如下:

  

通用属性定义为四个组成数组的值。该数组的第一个条目编号为0,并且数组的大小由与实现相关的常量GL_MAX_VERTEX_ATTRIBS指定。可以通过glVertexAttrib调用修改该数组的各个元素,该调用指定要修改的元素的索引以及该元素的值。

它说它们都是“四分量值”,但是完全有可能比顶点属性中的分量多或少。

这到底是什么意思?这仅适用于vec4类型吗? “通用顶点属性”的索引是什么?明确的解释可能是我真正需要的。

1 个答案:

答案 0 :(得分:3)

在OpenGL中,顶点被指定为一组顶点属性。随着可编程plepleine的问世,您有责任编写自己的顶点处理功能。顶点着色器确实处理一个顶点,并获取此特定顶点的属性作为输入。

这些顶点属性称为通用顶点属性,因为它们的含义完全由您作为应用程序程序员定义(与传统的固定功能管道相反,在传统的固定功能管道中,属性集完全由GL)。

OpenGL规范要求实现者支持至少16个不同的顶点属性。因此,每个顶点属性都可以通过其 index 从0到15进行标识(或您的实现允许的任何限制,请参见glGet(GL_MAX_VERTEX_ATTRIBS,...))。

概念上将顶点属性视为四维向量。当您在着色器中使用的少于vec4时,其他元素将被忽略。如果您指定少于四个元素,则矢量始终填充到(0,0,0,1)中,这对于RGBA颜色矢量以及同质的顶点坐标都是有意义的。

尽管您可以声明mat类型的顶点属性,但这将被映射到许多连续的顶点属性索引。

顶点属性数据可以来自一个顶点数组(如今,它们必须位于一个Vertex Buffer Object中,可能直接位于VRAM中,在旧式GL中,它们也可能来自普通客户端地址空间)或来自该属性的当前值。 您可以通过glEnableVertexAttribArray启用从属性数组的获取。如果启用了您在顶点着色器中访问的特定属性的顶点数组,GPU将从该文件中获取第 i 个元素在处理顶点 i 时。对于您访问的所有其他属性,您将获得该数组的当前值

当前值可以通过glVertexAttrib[1234]*系列GL函数进行设置。在绘制调用期间无法更改它们,因此它们在整个绘制调用期间保持不变 ,就像统一变量一样。

值得注意的重要一点是,默认情况下,顶点属性始终是浮点,因此您必须在顶点中声明in float / vec2 / vec3 / vec4着色器可以访问它们。例如,使用glVertexAttrib4ubv或使用GL_UNISGNED_BYTE作为glVertexAttribPointertype参数来设置当前值不会改变此设置。数据将自动转换为浮点数。

如今,GL确实支持其他两种属性数据类型:32位整数和64位双精度浮点值。您必须在着色器中分别将它们声明为int / ivec*uint / uvec*double / dvec*,并且您必须在设置数组指针或当前值时使用完全独立的函数:glVertexAttribIPointerglVertexAttribI*用于有符号/无符号整数和 glVertexAttribLPointerglVertexAttribL*代表双打(“长浮点数”)。