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.
#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)=trueI 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\$