Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opengl 为什么GLVertexAttributePointer存在不同的变体?_Opengl - Fatal编程技术网

Opengl 为什么GLVertexAttributePointer存在不同的变体?

Opengl 为什么GLVertexAttributePointer存在不同的变体?,opengl,Opengl,有 glVertexAttribPointer() glVertexAttribIPointer() glVertexAttribLPointer() 据我所知,glvertexattributepointer可以代替其他两个 如果是这样,为什么存在I和L变体?我在OpenGL Insights中读到了这一点 使用glvertexattributepointer()时,所有内容都转换为浮点。而glvertexattributepointer()只能公开存储整数的顶点数组,而glvertexat

glVertexAttribPointer()
glVertexAttribIPointer()
glVertexAttribLPointer()
据我所知,
glvertexattributepointer
可以代替其他两个


如果是这样,为什么存在
I
L
变体?

我在OpenGL Insights中读到了这一点

使用
glvertexattributepointer()
时,所有内容都转换为浮点。而
glvertexattributepointer()
只能公开存储整数的顶点数组,而
glvertexattributepointer()
仅用于双精度

经对此的报价确认:

对于GlvertexAttributePointer,如果规范化​ 是否设置为GL_TRUE​, 信息技术 指示以整数格式存储的值要映射到 范围[-1,1](用于有符号值)或[0,1](用于无符号值) 当它们被访问并转换为浮点时。否则,, 值将直接转换为浮点数,无需进行规范化

对于glVertexAttribIPointer,只有整数类型为GLU字节​, 无符号字节​, 格卢肖特​, GL_无符号_短​, 格卢因​, 无符号整数​ 被接受。值始终保留为整数 价值观

glVertexAttribLPointer指定通用顶点属性的状态 与64位声明的着色器属性变量关联的数组 双精度组件。类型​ 必须是GL_DOUBLE​. 指数​, 大小​, 大步​ 按照GLVERTEXAttributePointer和 glVertexAttribIPointer


不,它们不能互相替代

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


因为这是最初的API,所以当引入不同的属性数据类型(整数和双精度)时,必须对其进行扩展。还请注意,属性指针独立于着色器,因此当前绑定的着色器(如果有)无法确定目标值,因为这可能会在以后与不同的着色器一起使用。因此,
L
变量id用于
double/dvec
属性,而
I
变量用于
int/uint/ivec/uvec
属性。

进行测试,您将了解差异

假设使用以下顶点着色器执行变换反馈:

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

void main()
{
    output = sqrt(input);
}
这是你的“顶点数据”:

然后,如果按如下方式设置顶点属性:

glVertexAttribPointer(0, 1, GL_INT, GL_FALSE, 0, nullptr);
你会得到错误和奇怪的结果


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

output = sqrt(input);

在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);
然后你会得到正确的结果

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

顺便说一句,这个命名约定(大写字母)在API的不同部分共享(
glTexParameterIiv(…)
)。I表示数据是整数,L表示双精度浮点。否则,在没有这些后缀的情况下,您通常可以假定,不管您传递的是哪种输入数据类型,数据都将在管道中的某个位置转换为单精度浮点。
glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, nullptr);
                            ^^^^^^^^
                            does not match the real input type
                            but stops glVertexAttribPointer() converting them
--- glVertexAttribPointer(0, 1, GL_INT, GL_FALSE, 0, nullptr);
+++ glVertexAttribIPointer(0, 1, GL_INT, 0, nullptr);