I'm making a small game engine for vector graphics in OpenGL, and it is already broken in the early stages. I had it working with all the data for one object in the main.cpp file, but once I moved all that code into a class called Object, it completely stopped working. I don't have an old version of the code from before I implemented the object system, but all the code right now is at https://github.com/DJLevel3/Vector2.0. I think it's a problem with the initialization code (Object::genVAO()
in src/object.cpp
) but I can't figure out the problem.
I'll copy the code I think is relevant here, but there's a LOT of code in the files so I'll be removing all the unused methods and the methods with obvious functions. I'd recommend looking at the Github for the full files. Also, assume all headers have been included when needed and protected from duplicate includes.
Last thing before I post heaps of code, the things I think the problem is most likely in are closer to the top and the less likely ones are towards the bottom.
Source Code
Important structs used in most of the files:
struct vertex {
glm::vec3 pos;
glm::vec3 color;
};
struct shader {
GLuint program;
GLuint mvp;
GLint attribIDPosition;
GLint attribIDColor;
};
(Trimmed) object.cpp:
using namespace vector2;
Object::Object( std::vector<vertex> v, std::vector<GLuint> i, glm::vec3 position, glm::quat rotation, glm::vec3 scale )
{
vertices = v;
indices = i;
size = i.size()/3;
pos = position;
rot = rotation;
scl = scale;
genMatrix();
}
void Object::genVAO(shader s)
{
vertex v[vertices.size()];
std::copy(vertices.begin(), vertices.end(), v);
GLuint i[indices.size()];
std::copy(indices.begin(), indices.end(), i);
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );
GLuint vertexBuffer, indexBuffer;
glGenBuffers( 1, &vertexBuffer );
glGenBuffers( 1, &indexBuffer );
glBindBuffer( GL_ARRAY_BUFFER, vertexBuffer );
glBufferData( GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, indexBuffer );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof(i), i, GL_STATIC_DRAW );
glVertexAttribPointer( s.attribIDPosition, 3, GL_FLOAT, false, sizeof(vertex), MEMBER_OFFSET(vertex,pos) );
glEnableVertexAttribArray( s.attribIDPosition );
glVertexAttribPointer( s.attribIDColor, 3, GL_FLOAT, false, sizeof(vertex), MEMBER_OFFSET(vertex,color) );
glEnableVertexAttribArray( s.attribIDColor );
glBindVertexArray( 0 );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
glDisableVertexAttribArray( s.attribIDPosition );
glDisableVertexAttribArray( s.attribIDColor );
}
void Object::genMatrix()
{
modelMatrix = glm::translate(glm::mat4(), pos) * glm::toMat4(rot) * glm::scale(scl);
}
void Object::setVertices(std::vector<vertex> v)
{
vertices = v;
}
void Object::setIndices(std::vector<GLuint> i)
{
indices = i;
size = i.size()/3;
}
(Trimmed) object.hpp
namespace vector2 {
class Object {
protected:
std::vector<vertex> vertices;
std::vector<GLuint> indices;
int size;
GLuint vao = 0;
glm::vec3 pos = {0,0,0};
glm::quat rot = {1,0,0,0};
glm::vec3 scl = {1,1,1};
glm::mat4 modelMatrix;
public:
Object( std::vector<vertex> v, std::vector<GLuint> i, glm::vec3 position, glm::quat rotation, glm::vec3 scale );
void setVertices(std::vector<vertex> v);
void setIndices(std::vector<GLuint> i);
void genVAO( shader s );
void genMatrix();
};
}
**(Trimmed) render.cpp
using namespace vector2;
void vector2::drawModel(Object o, shader s)
{
glBindVertexArray( o.getVAO() );
glUseProgram( s.program );
glm::mat4 mvp = g_Camera.GetProjectionMatrix() * g_Camera.GetViewMatrix() * o.getMatrix();
glUniformMatrix4fv( s.mvp, 1, GL_FALSE, glm::value_ptr(mvp) );
glDrawElements( GL_TRIANGLES, o.getSize(), GL_UNSIGNED_INT, BUFFER_OFFSET(0) );
glUseProgram(0);
glBindVertexArray(0);
}
(Trimmed) main.cpp
using namespace vector2;
shader vecShader;
std::vector<vertex> shipVertices = {
{glm::vec3( 0.00, 2.00, -1.00), glm::vec3(0,1,0.2)}, // 0
{glm::vec3( 0.00, 0.00, 4.00), glm::vec3(0,1,0.2)}, // 1
{glm::vec3( 3.00, 0.00, -5.00), glm::vec3(0,1,0.2)}, // 2
{glm::vec3( 0.00, -1.50, -2.00), glm::vec3(0,1,0.2)}, // 3
{glm::vec3(-3.00, 0.00, -5.00), glm::vec3(0,1,0.2)}, // 4
{glm::vec3( 0.65, -1.50, -5.00), glm::vec3(0,1,0.2)}, // 5
{glm::vec3(-0.65, -1.50, -5.00), glm::vec3(0,1,0.2)}, // 6
{glm::vec3( 0.65, 0.00, -5.00), glm::vec3(0,1,0.2)}, // 7
{glm::vec3(-0.65, 0.00, -5.00), glm::vec3(0,1,0.2)} // 8
};
int shipSize = 8 * 3;
std::vector<GLuint> shipIndices = {
0, 1, 2, // 0
0, 1, 4, // 1
3, 1, 2, // 2
3, 1, 4, // 3
2, 1, 4, // 4
3, 5, 6, // 5
3, 5, 7, // 6
3, 6, 8, // 7
};
Object ship;
void DisplayGL()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
drawModel(ship, vecShader);
glutSwapBuffers();
}
int main( int argc, char* argv[] )
{
InitGL(argc, argv);
InitGLEW();
GLuint vertexShaderV,geoShaderV,fragmentShaderV;
vertexShaderV = LoadShader( GL_VERTEX_SHADER, "../resources/shaders/vecshader/vertex.glsl" );
geoShaderV = LoadShader( GL_GEOMETRY_SHADER, "../resources/shaders/vecshader/geometry.glsl" );
fragmentShaderV = LoadShader( GL_FRAGMENT_SHADER, "../resources/shaders/vecshader/fragment.glsl" );
std::vector<GLuint> shadersV;
shadersV.push_back(vertexShaderV);
shadersV.push_back(geoShaderV);
shadersV.push_back(fragmentShaderV);
vecShader.program = CreateShaderProgram( shadersV );
assert( vecShader.program != 0 );
vecShader.attribIDPosition = glGetAttribLocation( vecShader.program, "inPosition" );
vecShader.attribIDColor = glGetAttribLocation( vecShader.program, "inColor" );
vecShader.mvp = glGetUniformLocation( vecShader.program, "mvp" );
ship = Object(shipVertices, shipIndices, (glm::vec3){0,0,0}, (glm::quat){1,0,0,0}, (glm::vec3){1,1,1});
ship.genVAO(vecShader);
ship.genMatrix();
glutMainLoop();
}
CreateShaderProgram and LoadShader both work correctly (loading shaders from files and creating a program) and have not been modified since before I broke the code.
Shaders
vertex.glsl
#version 330 core
layout(location=0) in vec3 inPosition;
layout(location=1) in vec3 inColor;
out vec4 gsin;
uniform mat4 mvp;
void main()
{
gl_Position = mvp * vec4(inPosition, 1);
gsin = vec4(inColor, 1);
}
fragment.glsl
#version 330 core
layout (triangles) in;
layout (line_strip, max_vertices = 4) out;
in vec4 gsin[];
out vec4 fColor;
void main() {
fColor = gsin[0];
gl_Position = gl_in[0].gl_Position;
EmitVertex();
fColor = gsin[1];
gl_Position = gl_in[1].gl_Position;
EmitVertex();
fColor = gsin[2];
gl_Position = gl_in[2].gl_Position;
EmitVertex();
fColor = gsin[0];
gl_Position = gl_in[0].gl_Position;
EmitVertex();
EndPrimitive();
}
fragment.glsl
#version 330 core
in vec4 fColor;
layout(location=0) out vec4 outColor;
void main()
{
outColor = fColor;
}