必须在着色器中使用glUniform/glVertexAttribPointer类型匹配声明类型吗?

Gru*_*rig 3 opengl glsl

GLSL代码和传递数据的本机代码之间的类型必须匹配到什么程度?

例如,假设我有着色器代码:

uniform float uFloat;
uniform int uInt;
in float aFloat;
in int aInt;
Run Code Online (Sandbox Code Playgroud)

和本机伪代码(我遗漏了很多无聊的东西):

glUniform1i(glUniformLocation("uFloat"), 10)
glUniform1f(glUniformLocation("uInt"), 1.414)
glBufferData(int[1, 2, 3, ...])
glVertexAttribPointer(glAttribLocation("aFloat"), 0, GL_INT)
glBufferData(float[1.1, 2.2, 3.3, ...])
glVertexAttribPointer(glAttribLocation("aInt"), 0, GL_FLOAT)
Run Code Online (Sandbox Code Playgroud)

因此,请注意客户端代码中的类型匹配,但它们与着色器代码中的声明类型不匹配.

我要问的是,您是在逻辑层面还是在位表示方面告诉着色器值?

(我知道我似乎应该能够测试这个,但很难调试着色器,我觉得我的行为不一致,所以我只是在寻找确定的信息.)

Col*_*Two 6

type用于glVertexAttribPointer指定缓冲区内数据类型的参数.如果它是整数类型,则在读取顶点时,GPU会自动将值转换为浮点值,或者将它们直接转换为浮点值(如果normalized是)GL_FALSE,或者将它们除以整数类型的最大值如果normalized是的话GL_TRUE.

但是,glVertexAttribPointer仅适用于in float输入(即使您传递整数缓冲区类型),但在最后一行,您正在使用它in int.为此,你必须使用glVertexAttribIPointer(注意I).虽然它有一个type参数,但它不接受浮点格式,如GL_FLOAT; 您不能将浮点值的缓冲区传递给整数顶点属性.

(也有glVertexAttribLPointerdoubleS,但那些不经常使用.)

制服更严格; 您必须使用适当的glUniform为您所使用的类型功能(例如,glUniform1iint类型和glUniform1ffloat类型),否则你会得到一个GL_INVALID_OPERATION错误.