# Trying to abstract OpenGL model loading but can't draw triangle… (C++)

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"

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) :
{}
};
class Model
{
GLenum _drawSpeed;
GLuint VAO, VBO, EBO;
public:
std::vector<GLfloat> _vertices;
std::vector<GLuint> _elements;
std::vector<VertexAttribPointerClass> _vapclasses;
bool _wireframeMode;

Model() {}
virtual ~Model();

void DrawModel();
};
}
}
}

#endif


GraphicsModel.cpp

#include "GraphicsModel.h"

{

_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);
}

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);

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)
};


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.

• Check all gl function return codes, use the ARB_debug_output extension, and use a graphics debugger - have you tried any of those? – Sean Middleditch Nov 19 '16 at 0:06
• 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. – Mr_Rockers Nov 19 '16 at 0:42

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?)