0
\$\begingroup\$

Creating the VAO for a simple cube within a function in the main file results in the cube being rendered properly:

GLuint createCube()
{
    GLuint VBO;
    GLuint VAO;
    GLuint EAO;
    GLfloat vertexData[] = {
        0.5f, -0.5f, -0.5f,
        0.5f, -0.5f, 0.5f,
        -0.5f, -0.5f, 0.5f,
        -0.5f, -0.5f, -0.5f,
        0.5f, 0.5f, -0.5f,
        0.5f, 0.5f, 0.5f,
        -0.5f, 0.5f, 0.5f,
        -0.5f, 0.5f, -0.5f,

    };
    GLuint elementData[] = {
        2-1, 3-1, 4-1,
        8-1, 7-1, 6-1,
        5-1, 6-1, 2-1,
        6-1, 7-1, 3-1,
        3-1, 7-1, 8-1,
        1-1, 4-1, 8-1,
        1-1, 2-1, 4-1,
        5-1, 8-1, 6-1,
        1-1, 5-1, 2-1,
        2-1, 6-1, 3-1,
        4-1, 3-1, 8-1,
        5-1, 1-1, 8-1,

    };

    // make and bind the VAO
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    // make and bind the VBO
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);

    // make and bind the eao
    glGenBuffers(1, &EAO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EAO);

    //put data into VBO and EAO
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elementData), elementData, GL_STATIC_DRAW);


    // connect the xyz to the "vert" attribute of the vertex shader
    glEnableVertexAttribArray(render.get_shader()->attrib("vert"));
    glVertexAttribPointer(render.get_shader()->attrib("vert"), 3, GL_FLOAT, GL_FALSE, 0, NULL);

    // unbind the VAO, EAO, VBO

    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    return VAO;
}

working code

However when I move the exact same code for creating the VAO for the cube to another class, a white 2d square renders and a uniform within my vertex shader called MVP gets removed (optimized out?) and the vertex shader doesn't run at all:

class cube
{
public:
    cube(Render rendrer)
    {
        GLuint VBO;
        GLuint EAO;
        GLfloat vertexData[] = {
            0.5f, -0.5f, -0.5f,
            0.5f, -0.5f, 0.5f,
            -0.5f, -0.5f, 0.5f,
            -0.5f, -0.5f, -0.5f,
            0.5f, 0.5f, -0.5f,
            0.5f, 0.5f, 0.5f,
            -0.5f, 0.5f, 0.5f,
            -0.5f, 0.5f, -0.5f,

        };
        GLuint elementData[] = {
            2-1, 3-1, 4-1,
            8-1, 7-1, 6-1,
            5-1, 6-1, 2-1,
            6-1, 7-1, 3-1,
            3-1, 7-1, 8-1,
            1-1, 4-1, 8-1,
            1-1, 2-1, 4-1,
            5-1, 8-1, 6-1,
            1-1, 5-1, 2-1,
            2-1, 6-1, 3-1,
            4-1, 3-1, 8-1,
            5-1, 1-1, 8-1,

        };

        // make and bind the VAO
        glGenVertexArrays(1, &VAO);
        glBindVertexArray(VAO);

        // make and bind the VBO
        glGenBuffers(1, &VBO);
        glBindBuffer(GL_ARRAY_BUFFER, VBO);

        // make and bind the eao
        glGenBuffers(1, &EAO);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EAO);

        //put data into VBO and EAO
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elementData), elementData, GL_STATIC_DRAW);


        // connect the xyz to the "vert" attribute of the vertex shader
        glEnableVertexAttribArray(rendrer.get_shader()->attrib("vert"));
        glVertexAttribPointer(rendrer.get_shader()->attrib("vert"), 3, GL_FLOAT, GL_FALSE, 0, NULL);

        // unbind the VAO, EAO, VBO

        glBindVertexArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    }
    GLuint get_VAO() const
    {
        return VAO;
    }
private:
    GLuint VAO;
};

VAO creation within a class

Here is my vertex shader:

#version 430

in vec3 vert;
uniform mat4 MVP; // gets removed

out vec3 vertout;

void main(void)
{
    vertout = vert;
    gl_Position = MVP*vec4(vert, 1.0);
}

Here is my fragment shader:

#version 430 
//doesn't run at all
in vec3 vertout;
out vec4 outcolor;

void main(void)
{

    outcolor = mix(vec4(1,0,0,1),vec4(0,1,0,1),dot(vertout, vertout));
}

Here is my full code:

#include <iostream>
#include <Systems/UI/ui.h>
#include <Systems/Render/render.h>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/transform.hpp>
using namespace std;

UI ui(500,500,"Simple game"); // init SDL2 and create opengl context
Render render("/home/a/Desktop/Game/Game/ShaderCode/shadercode"); //object that handles rendering VAOs

int eventHandler()
{
    SDL_Event evnt;
    if(SDL_PollEvent(&evnt)){
        switch (evnt.type) {
        case SDL_QUIT:
            return false;
            break;
        default:
            break;
        }
    }
    return true;
}

//function init of VAO
GLuint createCube()
{
    GLuint VBO;
    GLuint VAO;
    GLuint EAO;
    GLfloat vertexData[] = {
        0.5f, -0.5f, -0.5f,
        0.5f, -0.5f, 0.5f,
        -0.5f, -0.5f, 0.5f,
        -0.5f, -0.5f, -0.5f,
        0.5f, 0.5f, -0.5f,
        0.5f, 0.5f, 0.5f,
        -0.5f, 0.5f, 0.5f,
        -0.5f, 0.5f, -0.5f,

    };
    GLuint elementData[] = {
        2-1, 3-1, 4-1,
        8-1, 7-1, 6-1,
        5-1, 6-1, 2-1,
        6-1, 7-1, 3-1,
        3-1, 7-1, 8-1,
        1-1, 4-1, 8-1,
        1-1, 2-1, 4-1,
        5-1, 8-1, 6-1,
        1-1, 5-1, 2-1,
        2-1, 6-1, 3-1,
        4-1, 3-1, 8-1,
        5-1, 1-1, 8-1,

    };

    // make and bind the VAO
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    // make and bind the VBO
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);

    // make and bind the eao
    glGenBuffers(1, &EAO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EAO);

    //put data into VBO and EAO
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elementData), elementData, GL_STATIC_DRAW);


    // connect the xyz to the "vert" attribute of the vertex shader
    glEnableVertexAttribArray(render.get_shader()->attrib("vert"));
    glVertexAttribPointer(render.get_shader()->attrib("vert"), 3, GL_FLOAT, GL_FALSE, 0, NULL);

    // unbind the VAO, EAO, VBO

    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    return VAO;
}

//class init of VAO
class cube
{
public:
    cube(Render rendrer)
    {
        GLuint VBO;
        GLuint EAO;
        GLfloat vertexData[] = {
            0.5f, -0.5f, -0.5f,
            0.5f, -0.5f, 0.5f,
            -0.5f, -0.5f, 0.5f,
            -0.5f, -0.5f, -0.5f,
            0.5f, 0.5f, -0.5f,
            0.5f, 0.5f, 0.5f,
            -0.5f, 0.5f, 0.5f,
            -0.5f, 0.5f, -0.5f,

        };
        GLuint elementData[] = {
            2-1, 3-1, 4-1,
            8-1, 7-1, 6-1,
            5-1, 6-1, 2-1,
            6-1, 7-1, 3-1,
            3-1, 7-1, 8-1,
            1-1, 4-1, 8-1,
            1-1, 2-1, 4-1,
            5-1, 8-1, 6-1,
            1-1, 5-1, 2-1,
            2-1, 6-1, 3-1,
            4-1, 3-1, 8-1,
            5-1, 1-1, 8-1,

        };

        // make and bind the VAO
        glGenVertexArrays(1, &VAO);
        glBindVertexArray(VAO);

        // make and bind the VBO
        glGenBuffers(1, &VBO);
        glBindBuffer(GL_ARRAY_BUFFER, VBO);

        // make and bind the eao
        glGenBuffers(1, &EAO);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EAO);

        //put data into VBO and EAO
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elementData), elementData, GL_STATIC_DRAW);


        // connect the xyz to the "vert" attribute of the vertex shader
        glEnableVertexAttribArray(rendrer.get_shader()->attrib("vert"));
        glVertexAttribPointer(rendrer.get_shader()->attrib("vert"), 3, GL_FLOAT, GL_FALSE, 0, NULL);

        // unbind the VAO, EAO, VBO

        glBindVertexArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    }
    GLuint get_VAO() const
    {
        return VAO;
    }
private:
    GLuint VAO;
};

glm::mat4 createMVP()
{
    glm::mat4 Projection = glm::perspective(45.0f, 1.0f / 1.0f, 0.1f, 100.0f);
    glm::mat4 View       = glm::lookAt(
        glm::vec3(4,3,3), 
        glm::vec3(0,0,0), 
        glm::vec3(0,1,0)
    );
    glm::mat4 Model      = glm::mat4(1.0f);
    glm::mat4 MVP        = Projection * View * Model;
    return MVP;
}

int main()
{

    // create cube via class
    cube cube_object(render);
    GLuint class_VAO = cube_object.get_VAO();

    //create cube via function
    //GLuint function_VAO = createCube();

    // mvp matrix
    glm::mat4 MVP = createMVP();

    bool running = true;
    while(running){
        running = eventHandler();

        //render.draw(function_VAO,36,MVP); // works

        render.draw(class_VAO,36,MVP); //doesnt work

        ui.swapBuffer();
    }

    return 0;
}

Does creating a VAO within a class cause these problems? Or is it something else?

\$\endgroup\$
1
  • \$\begingroup\$ "Does creating a VAO within a class cause these problems?" OpenGL is completely and absolutely neutral to all programming languages and programming language features. The bug is most definitely because of something you've done. e.g., are you sure you want to be copying your Render instance into your cube class? That seems suspect. \$\endgroup\$ Jul 19 '15 at 17:47
0
\$\begingroup\$

You're passing the Render instance to your cube class by value. This is probably copying or reinitializing a bunch of state.

Remember that you can make classes non-copyable for cases like this. I always make systems/module classes like that non-copyable to avoid bugs like these. For things like your cube you'll also have problems (you'll end up deleting your VAO twice if you make a copy of the class). I think you're also leaking your VBO and your IBO.

For the future, no, being in a class itself cannot be the problem. A C++ class is just a way of organizing code; they're practically syntactical sugar for C structs and functions.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.