Search code examples
c++openglglfwglm-math

Quad Object not rendering onto screen


#include<iostream>
#include<glad/glad.h>
#include<GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"layout (location = 1) in vec3 aColour;"
"out vec3 vertexColour;\n"
"void main()\n"
"{\n"
"gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"vertexColour = aColour;\n"
"}\0";

const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"in vec3 vertexColour;\n"
"void main()\n"
"{\n"
"   FragColor = vec4(vertexColour,1.0f);\n"
"}\n\0";

// renderable classes 
class Render {

};

class Quad : public Render {
    public:
        unsigned int VAO;
        unsigned int VBO;
        unsigned int IBO;
    
        float vertices[24] = {
            -0.5f, -0.5f, 0.0f,  0.0f, 0.0f, 0.0f,               // bottom left   index -- 0
         0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 0.0f,               // bottom right   index -- 1
         -0.5f,  0.5f, 0.0f,  0.0f, 0.0f, 0.0f,               // top left      index -- 2
         0.5f, 0.5f, 0.0f,    0.0f, 0.0f, 0.0f,               // top right     index -- 3
        };
        unsigned int indices[6] = {
            0,1,2,
            1,3,2
        };

        void constructVAO() {
            glGenVertexArrays(1, &VAO);
            glBindVertexArray(0);

            constructVBO();  // Bind the VBO
            constructIBO();  // Bind the IBO
            // position VAO
            glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
            glEnableVertexAttribArray(0);
            // colour VAO
            glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
            glEnableVertexAttribArray(1);
        };

        
        void constructVBO() {
            glGenBuffers(1, &VBO);
            glBindBuffer(GL_ARRAY_BUFFER, VBO);
            glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
        };
        void constructIBO() {
            glGenBuffers(1, &IBO);
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
            glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
        }

        void quadForge() {
            constructVBO();
            constructIBO();
            constructVAO();
        }
};

int main() {

    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    GLFWwindow* window = glfwCreateWindow(1920, 1080, "test", NULL, NULL);
    glfwMakeContextCurrent(window);
    gladLoadGL();
    glViewport(0, 0, 1920, 1080);
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    
    unsigned int vertexShader;
    vertexShader = glCreateShader(GL_VERTEX_SHADER); 
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);

    unsigned int fragmentShader;
    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);

    unsigned int shaderProgram;
    shaderProgram = glCreateProgram();

    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);


    Quad quad1;
    quad1.quadForge();

    glfwSwapBuffers(window);
    while (!glfwWindowShouldClose(window)) {
        glfwPollEvents();
        glClear(GL_COLOR_BUFFER_BIT);
        glUseProgram(shaderProgram);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);


        glfwSwapBuffers(window); 

    }


    glfwDestroyWindow(window);
    glfwTerminate();

}

I've created a quad class and initialised an object to render. However, it simply doesn't render anything on the screen but was prior to putting it into an object

I do have these warnings

Severity    Code    Description Project File    Line    Suppression State
Warning C26495  Variable 'Quad::IBO' is uninitialized. Always initialize a member variable (type.6).    OpenGLProject   C:\\Users\\intel\\source\\repos\\OpenGLProject\\main.cpp    79  
Warning C26495  Variable 'Quad::VAO' is uninitialized. Always initialize a member variable (type.6).    OpenGLProject   C:\\Users\\intel\\source\\repos\\OpenGLProject\\main.cpp    79  
Warning C26495  Variable 'Quad::VBO' is uninitialized. Always initialize a member variable (type.6).    OpenGLProject   C:\\Users\\intel\\source\\repos\\OpenGLProject\\main.cpp    79  

(although the variables are initialised)

I've tried to first to actually return the VAO's from the function and then assign them but these all gave back no results


Solution

    1. Warning

      Since uninitialized variables are used, the compiler gives a proper warning. The compiler does not know, that the functions will actually initialize them.

    2. Compile and Link status

      You don't check whether the shaders gets compiled nor that the linkage of the program is successful. I am not 100% sure if that's of concern but there is a \n missing at the end of line 3 in the vertex shader source.

      If either compilation or linkage are not of success, the shader info log or program info log will tell you what went wrong.

      Also of importance: glDebugMessageCallback (OpenGL 4.3+)

    3. Redundant function calls

      quadForge gets invoked, which invokes constructVBO, constructIBO and constructVAO, but the latter also invokes the previous functions (vbo, ibo). Seems redundant, no?

    4. zero vertex array object

      In the constructVAO function, you generate a vertex array object name, but instead of using the generated vertex array object name, you use the special vertex array object name zero (0), which is usually used to break the existing binding.

      So, instead of glBindVertexArray(0) use glBindVertexArray(VAO)