Initialization and convex fill error! Amateur hour!

Yo talented fellas!

I hope you can help me : )
I using Nanogui and NanoVG for my application. There I have inherited the screen for my viewport object and have implemented the virtual draw functions.
Everything seems to work nice in my demo application like this.

namespace sintonic {

    // Default constructor
    Viewport::Viewport(const Vector2i size, const std::string caption, bool resize, bool fullscreen) : Screen(size, caption, resize, fullscreen) {


    };

    void Viewport::drawAll() {
        glClearColor(mBackground[0], mBackground[1], mBackground[2], 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

        initGL();
        drawContents();
        drawWidgets();

        glfwSwapBuffers(mGLFWWindow);
    }

    void Viewport::drawContents() {
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    }

    void Viewport::initGL() {
        // Temporary triangle for GL
        GLfloat vertices[] = {
                0.5f,  0.5f, 0.0f,  // Top Right
                0.5f, -0.5f, 0.0f,  // Bottom Right
                -0.5f, -0.5f, 0.0f,  // Bottom Left
                -0.5f,  0.5f, 0.0f   // Top Left
        };
        GLuint indices[] = {  // Note that we start from 0!
                0, 1, 3,  // First Triangle
                1, 2, 3   // Second Triangle
        };

// Build and compile our shader program
        // Vertex shader
        GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
        glCompileShader(vertexShader);
        // Check for compile time errors
        GLint success;
        GLchar infoLog[512];
        glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
        if (!success)
        {
            glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
            std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED
" << infoLog << std::endl;
        }
        // Fragment shader
        GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
        glCompileShader(fragmentShader);
        // Check for compile time errors
        glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
        if (!success)
        {
            glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
            std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED
" << infoLog << std::endl;
        }
        // Link shaders
        GLuint shaderProgram = glCreateProgram();
        glAttachShader(shaderProgram, vertexShader);
        glAttachShader(shaderProgram, fragmentShader);
        glLinkProgram(shaderProgram);
        // Check for linking errors
        glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
        if (!success) {
            glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
            std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED
" << infoLog << std::endl;
        }

        GLuint VBO, VAO, EBO;
        glGenVertexArrays(1, &VAO);
        glGenBuffers(1, &VBO);
        glGenBuffers(1, &EBO);
        // Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s).
        glBindVertexArray(VAO);

        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
        glEnableVertexAttribArray(0);

        glBindBuffer(GL_ARRAY_BUFFER, 0); // Note that this is allowed, the call to glVertexAttribPointer registered VBO as the currently bound vertex buffer object so afterwards we can safely unbind

        glBindVertexArray(0); // Unbind VAO (it's always a good thing to unbind any buffer/array to prevent strange bugs), remember: do NOT unbind the EBO, keep it bound to this VAO

        // Draw our first triangle
        glUseProgram(shaderProgram);
        glBindVertexArray(VAO);

    }
}

However! If I change my initGL() to the class constructor I get Error 00000502 after convex fill ?
Like this.

    // Default constructor
    Viewport::Viewport(const Vector2i size, const std::string caption, bool resize, bool fullscreen) : Screen(size, caption, resize, fullscreen) {

        initGL();
    };

I would like to init the buffers only once and then simply draw them every frame. How could I acheve that and what I`m doing wrong? Uhh…

I bet I`m doing stupid things but please sensei help me!! : )

Thanks,

  • J

The constructor is likely called before any OpenGL context is created, but you shouldn’t put any OpenGL code in constructors or destructors. Check this wiki page about why you shouldn’t wrap OpenGL objects in classes.

Thank you Spoops for answering my foolish questions!

Youre right! Also I had put my mind so much into writing raytracer that I forgot that openGL is very different. I realized that its actually my OBJECTS that need to draw themselves not the VIEWPORT!
I will also need to remove all those constructor initializations and go with member functions? The wiki page dosen`t give single solution to initializing objects, though.

I`m doing now simple scene graph and hopefully it will work better when I do the changes! : )

Thanks a lot for sharing your wisdom man,

  • J

I’d say it’s better to only have one monolithic class that makes all the OpenGL calls, as you will get lost very often when delegating code to objects. The actual objects should only contain data and act on that data.

If you want to keep it simple though, just create init and destroy member functions.

Ah! Okey.

Then I think I was doing it more or less correctly before(without the member functions tho)

My confusion comes partly from the Nanogui as well… I dont quite know how to integrate the main GL drawing loop into it. The author is so busy and the documentation is sparse. Also hes so badass coder that hes examples are bit too advanced for me. Im trying to use this as example as it has GL viewport https://github.com/wjakob/instant-meshes

I will post my progress once I get forward a bit haha : )

Thanks a lot,

  • J