Search code examples
c++openglglslshader

Deforming a shape when resizing an OpenGL window


I draw an object using a shader program and a VAO
But when I deform the window, my figure also deforms. My vertex shader doesn't do anything, the fragment shader only sets the color orange.

vertshader.vert

#version 330 core
layout (location = 0) in vec3 aPos;
 
void main()
{
    gl_Position = vec4(aPos, 1.0);
}

gl init function

float vertexes_normalized[12] =
                 {-0.5, 0.5, 0,
                   0.5, 0.5, 0,
                   0.5, -0.5, 0,
                  -0.5, -0.5, 0};

glClearColor(0.0, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-this->width() / 2, this->width() / 2, -this->height() / 2, this->height() / 2);
glViewport(0, 0, this->width(), this->height());

//Compile shader program
unsigned int shaderProgram = makeShaderProgram(":/glshaders/vertshader.vert", ":/glshaders/fragshader.frag");
if(!shaderProgram) {
    qDebug("[ERROR]initializeGL: makeShaderProgram failed!");
    return;
}
gShaderProgram = shaderProgram;

//Vertex buffer object
unsigned int VBO = 0;
//Allocate 1 buffer
glGenBuffers(1, &VBO);
//Linking a buffer object to an OpenGL buffer
glBindBuffer(GL_ARRAY_BUFFER, VBO);
//Copying vertex data from the array to VBO
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexes_normalized), vertexes_normalized, GL_STATIC_DRAW);
gVBO = VBO;

//Configuring the interpretation of the vertex buffer data
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);

glUseProgram(shaderProgram);

In the drawing function, I just do:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_POLYGON, 0, 4);

I also have a function that is called during window resizing

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-newW / 2, newW / 2, -newH / 2, newH / 2);
glViewport(0, 0, newW, newH);

This is what I get when I run the program for the first time

First

However here is what happens if I resize the window

Two

If I use a regular render using glBegin(); glVertex(); glEnd(); without a shader program, then everything works fine and the shape does not deform when the window changes.

How can I achieve the same using VBO and VAO?


Solution

  • You mix the deprecated OpenGL matrices with "modern" OpenGL. gluOrtho2D has no effect when you use a shader program. You must use a matrix Uniform variable.


    Add a Uniform variable of type mat4 to the shader program and multiply the vertex coordinates by the matrix:

    #version 330 core
    layout (location = 0) in vec3 aPos;
     
    uniform mat4 projection;
    
    void main()
    {
        gl_Position = projection * vec4(aPos, 1.0);
    }
    

    Get the location index of the uniform after the shader program is linked (after glLinkProgram) with glGetUniformLocation:

    GLint projection_loc = glGetUniformLocation(shaderProgram, "projection");
    

    Specify and Orthographic projection matrix. A option is to use the OpenGL Mathematics (GLM) library and to set the orthographic projection with glm::ortho:

    glm::mat4 projection = glm::ortho(-this->width() / 2, this->width() / 2, -this->height() / 2, this->height() / 2);
    

    Set the value of the uniform variable after installing the program (after glUseProgram) with glUniformMatrix4fv:

    glUniformMatrix4fv(projection_loc , 1, GL_FALE, glm::value_ptr(projection));