0
\$\begingroup\$

Recently, I have been trying to learn modern OpenGL and I think I've grasped it (or the basics, at the very least.) but I have been having issues trying to make a triangle display on the screen but it doesn't seem to be working and I can't find where or what's going wrong. The console has proven fruitless and I've looked at examples on the internet for inspiration but I couldn't find what I was looking for.

Some things to note:

  • I know that the shaders are working correctly as I have them being loaded in at the start of the program and errors would appear in my program's console if they weren't working correctly. I have also checked and the shader program ID is correct.
  • I have loaded a triangle before in a rendering loop previously. However, I used const arrays instead of using STL vertex lists, which is what I'm using just now.
  • There are no empty lists. (As far as I and Visual Studio's inspector can tell, anyway.)
  • I have created a custom structure to help with loading in for glVertexAttribPointer called "VertexAttribPointerClass"
  • It's probably a very silly mistake.

Anyway, here's the code:

GraphicsModel.h

#ifndef GRAPHICSMODEL_H
#define GRAPHICSMODEL_H

#include "ExternalLibraries.h"
#include "Shader.h"

namespace game
{
    namespace model
    {
        namespace gfx
        {
            struct VertexAttribPointerClass
            {
                //  glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
                int _shaderPosition, _vectorSize, _type, _normalised, _stride, _offset;
                VertexAttribPointerClass()
                {}

                VertexAttribPointerClass(int shaderPosition, int vectorSize, int type, int normalised, int stride, int offset) :
                    _shaderPosition(shaderPosition), _vectorSize(vectorSize), _type(type), _normalised(normalised), _stride(stride), _offset(offset)
                {}
            };
            class Model
            {
                GLenum _drawSpeed;
                GLuint _shaderProgram;
                GLuint VAO, VBO, EBO;
            public:
                std::vector<GLfloat> _vertices;
                std::vector<GLuint> _elements;
                std::vector<VertexAttribPointerClass> _vapclasses;
                bool _wireframeMode;

                Model() {}
                Model(std::string shaderName, std::map<std::string, game::shader::ShaderClass*> shaderRegister, std::vector<GLfloat> vertices, std::vector<GLuint> elements, std::vector<VertexAttribPointerClass> vapclasses, GLenum drawSpeed, bool wireframeMode);
                virtual ~Model();

                void DrawModel();
            };
        }
    }
}

#endif

GraphicsModel.cpp

#include "GraphicsModel.h"

game::model::gfx::Model::Model(std::string shaderName, std::map<std::string, game::shader::ShaderClass*> shaderRegister, std::vector<GLfloat> vertices, std::vector<GLuint> elements, std::vector<VertexAttribPointerClass> vapclasses, GLenum drawSpeed, bool wireframeMode)
{
    _shaderProgram = game::shader::getShaderClassFromRegister(shaderName, shaderRegister)->getShaderProgram();

    _vertices = vertices;
    _elements = elements;
    _vapclasses = vapclasses;

    _drawSpeed = drawSpeed;
    _wireframeMode = wireframeMode;

    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);

    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(_vertices[0]) * _vertices.size(), &_vertices[0], _drawSpeed);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(_elements[0]) * _elements.size(), &_elements[0], _drawSpeed);

    for (int i = 0; i < _vapclasses.size(); i++)
    {
        glVertexAttribPointer(_vapclasses[i]._shaderPosition, _vapclasses[i]._vectorSize, _vapclasses[i]._type, _vapclasses[i]._normalised, _vapclasses[i]._stride, (GLvoid*)_vapclasses[i]._offset);
        glEnableVertexAttribArray(_vapclasses[i]._shaderPosition);
    }

    glBindVertexArray(0);
}

game::model::gfx::Model::~Model()
{
}

void game::model::gfx::Model::DrawModel()
{
    if (_wireframeMode)
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    else
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

    glUseProgram(_shaderProgram);
    glBindVertexArray(VAO);
    glDrawElements(GL_TRIANGLES, _elements.size(), GL_UNSIGNED_INT, &_elements[0]);
    glBindVertexArray(0);
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}

Initialisation Code

/*MODELS*/
    std::vector<GLfloat> testModelVertices = 
    {
        -0.5f, -0.5f, 0.0f, //0
         0.5f, -0.5f, 0.0f, //1
         0.0f,  0.5f, 0.0f  //2
    };
    std::vector<GLuint> testModelElements =
    {
        0, 1, 2
    };
    std::vector<game::model::gfx::VertexAttribPointerClass> testModelVAPClasses =
    {
        game::model::gfx::VertexAttribPointerClass(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0)
    };
    currentGameEnvironment->currentGameVariables.models.testModel = game::model::gfx::Model("testShader", currentGameEnvironment->currentGameVariables.util.shaderRegister, testModelVertices, testModelElements, testModelVAPClasses, GL_STATIC_DRAW, false);

Render Loop

bool game::graphics::render(GLFWwindow* window, game::core::GameEnvironment* currentGameEnvironment)
{
    //Sets "window's" OpenGL context to be current.
    glfwMakeContextCurrent(window);

    glClearColor(0.8f, 0.8f, 1.0f, 1.0f); //Sets the colour for glClear.
    glClear(GL_COLOR_BUFFER_BIT); //Clears the COLOR-BUFFER-BIT with the colour above. Other available bits are GL_DEPTH_BUFFER_BIT and GL_STENCIL_BUFFER_BIT

    currentGameEnvironment->currentGameVariables.models.testModel.DrawModel();

    glfwSwapBuffers(window);

    return true;
}

Sorry if I haven't uploaded enough information. -I can do so if needed, it's just that it isn't commented very well and I know for a fact that the other things work correctly.

Any help is appreciated!

EDIT #1: Used incorrect ENUM in glBindBuffer for VBO.

\$\endgroup\$
  • \$\begingroup\$ Check all gl function return codes, use the ARB_debug_output extension, and use a graphics debugger - have you tried any of those? \$\endgroup\$ – Sean Middleditch Nov 19 '16 at 0:06
  • \$\begingroup\$ I used glIntercept to get this log here: #The render log.# wglMakeCurrent(FB011C8C,00020000)=true glClearColor(0.800000,0.800000,1.000000,1.000000) glClear(GL_COLOR_BUFFER_BIT) glPolygonMode(GL_FRONT_AND_BACK,GL_FILL) glUseProgram(3) glBindVertexArray(1) glDrawElements(GL_TRIANGLES,3,GL_UNSIGNED_INT,0A286EF8) GLSL=3 glBindVertexArray(0) glPolygonMode(GL_FRONT_AND_BACK,GL_FILL) wglSwapBuffers(FB011C8C)=true I did fix an error as I used an incorrect ENUM in glBindBuffer. Apart from that, I didn't get errors that were my fault as the other errors are part of GLFW/GLEW. \$\endgroup\$ – Mr_Rockers Nov 19 '16 at 0:42
1
\$\begingroup\$

The problem I had was that I mistakenly put the _element array into the last parameter of glDrawElements when it just needed to be 0.

e.g.

glDrawElements(GL_TRIANGLES, _elements.size(), GL_UNSIGNED_INT, 0);

Not this:

    glDrawElements(GL_TRIANGLES, _elements.size(), GL_UNSIGNED_INT, &_elements[0]);

According to www.learnopengl.com, the last parameter is to specify an offset in the element array. (Maybe for animations?)

\$\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.