为什么存在glVertexAttribPointer的不同变体?

时间:2015-01-18 21:12:57

标签: opengl

glVertexAttribPointer()
glVertexAttribIPointer()
glVertexAttribLPointer()

据我所知,可以使用glVertexAttribPointer代替其他两种。

如果是,为什么存在IL变体?

3 个答案:

答案 0 :(得分:14)

我在OpenGL Insights中了解到这一点

使用glVertexAttribPointer()时,所有内容都会被转换为浮点数。虽然glVertexAttribIPointer()只能暴露存储整数的顶点数组,而glVertexAttribLPointer()只能用于双精度。

正如此OpenGL.org page的引用所证实的那样:

  

对于glVertexAttribPointer,如果规范化设置为GL_TRUE,则为   表示以整数格式存储的值将映射到   范围[-1,1](对于有符号值)或[0,1](对于无符号值)   当它们被访问并转换为浮点时。除此以外,   值将直接转换为浮点值而不进行标准化。

     

对于glVertexAttribIPointer,只有整数类型GL_BYTE,   GL_UNSIGNED_BYTE,GL_SHORT,GL_UNSIGNED_SHORT,GL_INT,   接受GL_UNSIGNED_INT。值始终保留为整数   值。

     

glVertexAttribLPointer指定通用顶点属性的状态   与使用64位声明的着色器属性变量关联的数组   双精度元件。 type必须是GL_DOUBLE。指数,大小,   和stride的行为与glVertexAttribPointer和   glVertexAttribIPointer。

答案 1 :(得分:4)

不,他们不能互相使用。

传统上,GL的所有顶点属性都是浮点数。您可以输入整数数据的事实并没有改变 - 数据在运行中转换为浮点数。 normalized参数控制转换的完成方式,如果启用,则输入类型的范围映射到规范化的[0,1](对于无符号类型,也称为UNORM GL)或[ - 1,1](对于有符号类型,也称为SNORM),如果禁用,则该值直接转换为输入整数的最近浮点值。

由于这是原始API,因此在引入不同的属性数据类型(整数和双精度)时必须进行扩展。另请注意,属性指针独立于着色器,因此目标绑定着色器(如果有)无法确定目标值,因为稍后可能会与不同的着色器一起使用。因此,L变体的double/dvec变体ID属于I属性,而int/uint/ivec/uvec变量属于{{1}}属性。

答案 2 :(得分:0)

进行测试,您将了解其中的区别。

假设您正在使用以下顶点着色器进行变换反馈:

#version 450 core
layout(location = 0) in int input;
layout(xfb_offset = 0) out float output;

void main()
{
    output = sqrt(input);
}

这是您的“顶点数据”:

GLint data[] = { 1, 2, 3, 4, 5 };

然后,如果您设置像这样的顶点属性:

glVertexAttribPointer(0, 1, GL_INT, GL_FALSE, 0, nullptr);

您会得到错误和奇怪的结果。


如果您在顶点着色器中更改此行

output = sqrt(input);

output = sqrt(intBitsToFloat(input));

OR

在C ++代码中更改此行:

glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, nullptr);
                            ^^^^^^^^
                            does not match the real input type
                            but stops glVertexAttribPointer() converting them

它将起作用。但这不是自然的方法。


现在glVertexAttribIPointer()可以提供帮助:

--- glVertexAttribPointer(0, 1, GL_INT, GL_FALSE, 0, nullptr);
+++ glVertexAttribIPointer(0, 1, GL_INT, 0, nullptr);

那么您将获得正确的结果。

(我为此奋斗了整个下午,直到找到glVertexAttribIPointer()。)