Bilal Shafi
Bilal Shafi

Reputation: 167

OpenGL is incorrectly passing vertices the vertex shader

Problem: Opengl is converting the integer array, I passed into a vertex array object, into a float array for some reason.

When I try to use the vertices as an ivec2 in my vertex shader I get some weird numbers as outputs, however if I use vec2 instead I get the expected output.

Code:

VertexShader:

#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);
}

Passing the Vertex Array:

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);

Output:

The first picture is what happens when I use ivec2 (the bad output). The second picture is what happes when I use vec2 (the expected output). What happens when I use ivec2 What happens when I use vec2 (The correct output)

If you need to know anything else please ask it in the comments.

Upvotes: 1

Views: 723

Answers (1)

Rabbid76
Rabbid76

Reputation: 210878

For vertex attributes with an integral data it has to be used glVertexAttribIPointer (focus on the I), to define an array of generic vertex attribute data.

This means, that if you use the ivec2 data type for the attribute in the vertex shader:

in ivec2 aPos;

then you have to use glVertexAttribIPointer wehan you define the array of generic vertex attribute data.

Change your code like this, to solve the issue:

// glVertexAttribIPointer instead of glVertexAttribPointer
glVertexAttribIPointer(0, 2, GL_INT, GL_FALSE, 2 * sizeof(GLint), (void*)0);

See OpenGL 4.6 API Compatibility Profile Specification; 10.2. CURRENT VERTEX ATTRIBUTE VALUES; page m389:

When values for a vertex shader attribute variable are sourced from an enabled generic vertex attribute array, the array must be specified by a command compatible with the data type of the variable. The values loaded into a shader attribute variable bound to generic attribute index are undefined if the array for index was not specified by:

  • VertexAttribFormat, for floating-point base type attributes;
  • VertexAttribIFormat with type BYTE, SHORT, or INT for signed integer base type attributes; or
  • VertexAttribIFormat with type UNSIGNED_BYTE, UNSIGNED_SHORT, or UNSIGNED_INT for unsigned integer base type attributes.

Upvotes: 5

Related Questions