有
glVertexAttribPointer()
glVertexAttribIPointer()
glVertexAttribLPointer()
据我所知,可以使用glVertexAttribPointer
代替其他两种。
如果是,为什么存在I
和L
变体?
答案 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()
。)