OpenGL 错误地将顶点传递给顶点着色器

Bil*_*afi 1 opengl shader glsl

问题:由于某种原因,Opengl 正在将整数数组(我传递给顶点数组对象)转换为浮点数组。

当我尝试在我的顶点着色器中使用顶点作为 ivec2 时,我得到一些奇怪的数字作为输出,但是如果我使用 vec2 代替,我会得到预期的输出。

代码:

顶点着色器:

#version 430 core
//                         \/ This is what I'm reffering to when talking about ivec2 and vec2
layout (location = 0) in ivec2 aPos;

uniform uvec2 window;

void main()
{
    float xPos = float(aPos.x)/float(window.x);
    float yPos = float(aPos.y)/float(window.y);

    gl_Position = vec4(xPos, yPos, 1.0f, 1.0f);
}
Run Code Online (Sandbox Code Playgroud)

传递顶点数组:

GLint vertices[] =
{
    -50,  50,
     50,  50,
     50, -50,
    -50, -50
};

GLuint VBO, VAO;

glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);  //  \/ I'm passing it as an int
glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 2 * sizeof(GLint), (void*)0);
glEnableVertexAttribArray(0);

glUseProgram(sprite2DProgram);
glUniform2ui(glGetUniformLocation(sprite2DProgram, "window"), 640, 480);
Run Code Online (Sandbox Code Playgroud)

输出:

第一张图片是当我使用 ivec2(错误的输出)时会发生什么。第二张图是我使用 vec2(预期输出)时发生的情况。 当我使用 ivec2 时会发生什么 当我使用 vec2 时会发生什么(正确的输出)

如果您还需要了解任何其他信息,请在评论中提问。

Rab*_*d76 5

对于具有积分数据的顶点属性,必须使用它glVertexAttribIPointer(关注I)来定义通用顶点属性数据数组。

这意味着,如果您ivec2在顶点着色器中使用属性的数据类型:

in ivec2 aPos;
Run Code Online (Sandbox Code Playgroud)

那么你必须使用glVertexAttribIPointerwehan 来定义通用顶点属性数据的数组。

像这样更改代码以解决问题:

// glVertexAttribIPointer instead of glVertexAttribPointer
glVertexAttribIPointer(0, 2, GL_INT, GL_FALSE, 2 * sizeof(GLint), (void*)0);
Run Code Online (Sandbox Code Playgroud)

请参阅OpenGL 4.6 API 兼容性配置文件规范;10.2. 当前顶点属性值;第 m389 页

当顶点着色器属性变量的值源自启用的通用顶点属性数组时,该数组必须由与变量数据类型兼容的命令指定。如果未指定索引数组,则加载到绑定到通用属性索引的着色器属性变量中的值未定义:

  • VertexAttribFormat,用于浮点基类型属性;
  • VertexAttribIFormat 类型为 BYTE、SHORT 或 INT,用于有符号整数基类型属性;或者
  • VertexAttribIFormat 类型为 UNSIGNED_BYTE、UNSIGNED_SHORT 或 UNSIGNED_INT,用于无符号整数基类型属性。