I am creating an OpenGL program which simply creates a triangle and draws it on the screen. I have created a class called Drawable which contains the draw function, as well as the VAO & VBO objects which are used. I have also created a Triangle class which inherits from the Drawable class. In the Triangle class I have a constructor which takes an array of points and a single array containing a color, and it initializes the VAO & VBO (which are inherited from Drawable) using this data.
In my main function I initialize the Triangle using point and color data and then call the draw function on the Triangle object (this draw function is in Drawable). Ultimately though, the window opens and the triangle is not drawn. I have a simple constructor in the Drawable class, and if I initialize the object using this constructor and call the draw function it will display the object so I don't think its my draw function. The only thing I could think of is that because of how I am accessing the VAO & VBO objects maybe they aren't actually getting initialized to anything, but I don't know how to check that.
Drawable.h
class Drawable
{
public:
Drawable();
void draw();
GLuint objBuffer, VAO, program;
std::string vShaderName, fShaderName;
bool isUniform = false;
int numVertices = 0;
vec4 uniformColorVec;
};
Drawable.cpp
Drawable::Drawable()
{}
void Drawable::draw()
{
GLuint program = InitShader(vShaderName.c_str(), fShaderName.c_str());
glUseProgram(program);
GLuint color_loc = glGetUniformLocation(program, "color");
glBindVertexArray(VAO);
glUniform4fv(color_loc, 1, uniformColorVec);
glDrawArrays(GL_TRIANGLE_FAN, 0, numVertices);
}
Triangle.cpp
Triangle::Triangle(vec4 triPoints[3], vec4 color)
{
uniformColorVec = color;
vShaderName = "vshader00_v150.glsl";
fShaderName = "fshader00_v150.glsl";
numVertices = 3;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &objBuffer);
glBindBuffer(GL_ARRAY_BUFFER, objBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(triPoints), triPoints, GL_STATIC_DRAW);
program = InitShader(vShaderName.c_str(), fShaderName.c_str());
glUseProgram(program);
GLuint vPosition = glGetAttribLocation(program, "vPosition");
GLuint color_loc = glGetUniformLocation(program, "color");
glEnableVertexAttribArray(vPosition);
glVertexAttribPointer(vPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glUniform4fv(color_loc, 1, uniformColorVec);
}
main file
/* All the OpenGL windowing is intialized but I won't
include that since I know it's fine due to other objects being drawn
correctly */
vec4 triPoints2[3] = {
vec4(0.0, 0.0, 1.0, 1.0),
vec4(-0.75, -0.75, 1.0, 1.0),
vec4(0.0, -0.75, 1.0, 1.0)
};
vec4 blue_opaque = vec4(0.0, 0.0, 1.0, 1.0);
Triangle t;
t = Triangle(triPoints2, blue_opaque);
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
t.draw();
glFlush();
Your function gets a vec4 triPoints[3] argument, but by C++ rules it's equivalent to vec4 *triPoints as a function argument. As a result sizeof(triPoints) is not the size of the data but rather the size of the pointer itself (either 4 or 8). Instead, change it to:
glBufferData(GL_ARRAY_BUFFER, sizeof(*triPoints)*numVertices, triPoints, GL_STATIC_DRAW);
Related
I am following some tutorial on OpenGL and am running into a problem. I constructed a class called Mesh that takes an array of vertices in its constructor and generates vertexarrays and such to do the drawing. The problem is is that I am not seeing anything. Here is the interface:
class Mesh
{
public:
Mesh(Vertex * vertices, size_t numVertices);
virtual ~Mesh();
void Draw();
private:
enum { POSITION_VB, NUM_BUFFERS };
GLuint m_vertexArrayObject;
GLuint m_vertexArrayBuffers;
size_t m_drawCount;
};
and here are the implementations
#include "mesh.h"
Mesh::Mesh(Vertex *vertices, size_t numVertices)
{
m_drawCount = numVertices;
glGenVertexArrays(1, &m_vertexArrayObject);
glBindVertexArray(m_vertexArrayObject);
glGenBuffers(NUM_BUFFERS, &m_vertexArrayBuffers);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexArrayBuffers);
glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(vertices[0]), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindVertexArray(0);
}
void Mesh::Draw()
{
glBindVertexArray(m_vertexArrayObject);
glDrawArrays(GL_TRIANGLES, 0, m_drawCount);
glBindVertexArray(0);
}
Mesh::~Mesh()
{
glDeleteVertexArrays(1, &m_vertexArrayObject);
}
The Vertex type is a simple class that looks as
class Vertex {
public:
Vertex(glm::vec3 const & pos) { this->pos = pos;}
private:
glm::vec3 pos;
};
If I change the implementation of Mesh::Draw() to
glBegin(GL_TRIANGLES);
glVertex3f(-1.0f, -0.25f, 0.0f); //triangle first vertex
glVertex3f(-0.5f, -0.25f, 0.0f); //triangle second vertex
glVertex3f(-0.75f, 0.25f, 0.0f); //triangle third vertex
glEnd(); //end drawing of triangles
I am getting a triangle printed to the screen. My question is: Does this necessarily mean that there is an error in the implementation of Mesh' member functions, and if so, can anyone spot it? I thought maybe the glBegin method bypasses some error somewhere else in the code that the vertexarray method cannot bypass. I would be grateful for any help. Also, I can post additional code if needed!
The shader code:
#version 120
void main()
{
gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0);
}
More than likely your Mesh classes destructor is to blame:
Mesh::~Mesh()
{
glDeleteVertexArrays(1, &m_vertexArrayObject);
}
You have an implicit copy constructor, which does a byte-for-byte copy of your class's members whenever a copy of your Mesh is necessary. That byte-for-byte copy includes the name (m_vertexArrayObject) of an OpenGL-managed resource, which means you now have two distinct objects referencing the same resource.
As soon as one of these copies goes out of scope, it will delete the VAO that is still referenced by the original object.
The simplest way to solve this problem is to disable the copy constructor (C++11 has new syntax for this), then you will get a compiler error anytime a copy needs to be made.
private:
Mesh (const Mesh& original); // Copy ctor is inaccessible.
If you really do want to support multiple Mesh objects sharing the same Vertex Array Object, you will need to add reference counting and only free the VAO when the reference count reaches 0.
For the past three hours I am trying to figure out how to draw two different triangles with different colours using shaders in OpenGL and still cannot figure it out. Here is my code:
void setShaders(void)
{
vshader = loadShader("test.vert", GL_VERTEX_SHADER_ARB);
fshader = loadShader("test.frag", GL_FRAGMENT_SHADER_ARB);
vshader2 = loadShader("test2.vert", GL_VERTEX_SHADER_ARB);
fshader2 = loadShader("test2.frag", GL_FRAGMENT_SHADER_ARB);
shaderProg = glCreateProgramObjectARB();
glAttachObjectARB(shaderProg, vshader);
glAttachObjectARB(shaderProg, fshader);
glLinkProgramARB(shaderProg);
shaderProg2 = glCreateProgramObjectARB();
glAttachObjectARB(shaderProg2, vshader2);
glAttachObjectARB(shaderProg2, fshader2);
glLinkProgramARB(shaderProg2);
}
void makeBuffers(void)
{
// smaller orange triangle
glGenBuffers (1, &vbo);
glBindBuffer (GL_ARRAY_BUFFER, vbo);
glBufferData (GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);
glGenVertexArrays (1, &vao);
glBindVertexArray (vao);
glEnableVertexAttribArray (0);
glBindBuffer (GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
// larger purple triangle
glGenBuffers (1, &vbo2);
glBindBuffer (GL_ARRAY_BUFFER, vbo2);
glBufferData (GL_ARRAY_BUFFER, sizeof(points2), points2, GL_STATIC_DRAW);
glGenVertexArrays (1, &vao2);
glBindVertexArray (vao2);
glEnableVertexAttribArray (0);
glBindBuffer (GL_ARRAY_BUFFER, vbo2);
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
}
void window::displayCallback(void)
{
Matrix4 m4; // MT = UT * SpinMatrix
m4 = cube.getMatrix(); // make copy of the cube main matrix
cube.get_spin().mult(m4); // mult
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear color and depth buffers
glMatrixMode(GL_MODELVIEW);
glLoadMatrixd(cube.get_spin().getPointer()); // pass the pointer to new MT matrix
// draw smaller orange triangle
glUseProgramObjectARB(shaderProg);
glBindVertexArray(vao);
glDrawArrays (GL_TRIANGLES, 0, 3);
glDeleteObjectARB(shaderProg);
// draw the larger purple triangle
glUseProgramObjectARB(shaderProg2);
glBindVertexArray(vao2);
glDrawArrays (GL_TRIANGLES, 0, 3);
glDeleteObjectARB(shaderProg2);
glFlush();
glutSwapBuffers();
}
shaders:
test.vert and test2.vert are the same and are:
#version 120
//varying vec3 vp;
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
test.frag:
#version 120
void main()
{
gl_FragColor = vec4(1.0, 0.5, 0.0, 1.0);
}
test2.frag:
#version 120
void main()
{
gl_FragColor = vec4(0.5, 0.0, 0.5, 1.0);
}
But what I get is two triangles that are coloured purple. What am I doing wrong that causes my smaller orange triangle is getting rewritten in purple colour?
You are deleting the shader programs after you use them in the displayCallback() method:
...
glDrawArrays (GL_TRIANGLES, 0, 3);
glDeleteObjectARB(shaderProg);
...
glDrawArrays (GL_TRIANGLES, 0, 3);
glDeleteObjectARB(shaderProg2);
If drawCallback() is called more than once, which you certainly need to expect since a window will often have to be redrawn multiple times, the shaders will be gone after the first time. In fact, the second one will not be immediately deleted because it is the currently active program. Which explains why it continues to be used for both triangles.
Shader programs are only deleted after glDelete*() is called on them, and they are not referenced as the active program. So on your first glDelete*() call for shaderProg, that program is deleted once you make shaderProg2 active, because shaderProg is then not active anymore, which releases its last reference.
You should not delete the shader programs until shutdown, or until you don't plan to use them anymore for rendering because e.g. you're creating new prgrams. So in your case, you can delete them when the application exits. At least that's often considered good style, even though it's not technically necessary. OpenGL resources will be cleaned up automatically when an application exits, similar to regular memory allocations.
BTW, if you are using at least OpenGL 2.0, all the calls for using shaders and programs are core functionality. There's no need to use the ARB version calls.
I have a cube that I am loading from an OBJ file. When I make its position (0, 0, 0) everything works fine. The cube renders, and my function that gives it a velocity moves the cube across the screen. However if I change the position of the cube to something other than (0, 0, 0) before entering my while loop where I render and calculate velocity changes, the cube never renders. This is the first time I have tried to reload my vertices every time I render a frame, and I am assuming I messed up something there - but I've looked over other code and can't figure out what.
Here is my main function:
int main()
{
#ifdef TESTING
testing();
exit(0);
#endif
setupAndInitializeWindow(768, 480, "Final Project");
TriangleTriangleCollision collisionDetector;
Asset cube1("cube.obj", "vertexShader.txt", "fragmentShader.txt");
cube1.position = glm::vec3(0.0, 2.0, 0.0);
cube1.velocity = glm::vec3(0.0, -0.004, 0.0);
MVP = projection * view * model;
do{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
moveAsset(cube1);
renderAsset(cube1);
glfwSwapBuffers(window);
glfwPollEvents();
} while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0);
glfwTerminate();
return 0;
}
my moveAsset function:
void moveAsset(Asset &asset)
{
double currentTime = glfwGetTime();
asset.position.x += (asset.velocity.x * (currentTime - asset.lastTime));
asset.position.y += (asset.velocity.y * (currentTime - asset.lastTime));
asset.position.z += (asset.velocity.z * (currentTime - asset.lastTime));
for (glm::vec3 &vertex : asset.vertices)
{
glm::vec4 transformedVector = glm::translate(glm::mat4(1.0f), asset.position) * glm::vec4(vertex.x, vertex.y, vertex.z, 1);
vertex = glm::vec3(transformedVector.x, transformedVector.y, transformedVector.z);
}
asset.lastTime = glfwGetTime();
}
void renderAsset(Asset asset)
{
glUseProgram(asset.programID);
GLuint MatrixID = glGetUniformLocation(asset.programID, "MVP");
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, asset.vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, asset.vertices.size() * sizeof(glm::vec3), &asset.vertices[0], GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glDrawArrays(GL_TRIANGLES, 0, asset.vertices.size());
glDisableVertexAttribArray(0);
}
my model, view and projection matrices are defined as:
glm::mat4 model = glm::mat4(1.0f);
glm::mat4 view = glm::lookAt(glm::vec3(5, 5, 10),
glm::vec3(0, 0, 0),
glm::vec3(0, 1, 0));
glm::mat4 projection = glm::perspective(45.0f, (float) _windowWidth / _windowHeight, 0.1f, 100.0f);
and finally, my Asset struct:
struct Asset
{
Asset() { }
Asset(std::string assetOBJFile, std::string vertexShader, std::string fragmentShader)
{
glGenVertexArrays(1, &vertexArrayID);
glBindVertexArray(vertexArrayID);
programID = LoadShaders(vertexShader.c_str(), fragmentShader.c_str());
// Read our .obj file
std::vector<glm::vec2> uvs;
std::vector<glm::vec3> normals;
loadOBJ(assetOBJFile.c_str(), vertices, uvs, normals);
// Load it into a VBO
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);
//velocity = glm::vec3(0.0, 1.0, 1.0);
velocity = glm::vec3(0.0, 0.0, 0.0);
position = glm::vec3(0.0, 0.0, 0.0);
lastTime = glfwGetTime();
}
GLuint vertexArrayID;
GLuint programID;
GLuint vertexbuffer;
std::vector<glm::vec3> faces;
std::vector<glm::vec3> vertices;
glm::vec3 velocity;
double lastTime;
glm::vec3 position;
};
It looks like you're adding the current asset.position to your vertex positions on every iteration, replacing the previous positions. From the moveAsset() function:
for (glm::vec3 &vertex : asset.vertices)
{
glm::vec4 transformedVector = glm::translate(glm::mat4(1.0f), asset.position) *
glm::vec4(vertex.x, vertex.y, vertex.z, 1);
vertex = glm::vec3(transformedVector.x, transformedVector.y, transformedVector.z);
}
Neglecting the velocity for a moment, and assuming that you have an original vertex at (0, 0, 0), you would move it to asset.position on the first iteration. Then add asset.position again on the second iteration, which places it at 2 * asset.position. Then on the third iteration, add asset.position to this current position again, resulting in 3 * asset.position. So after n steps, the vertices will be around n * asset.position. Even if your object might be visible initially, it would move out of the visible range before you can blink.
To get your original strategy working, the most straightforward approach is to have two lists of vertices. One list contains your original object coordinates, which you never change. Then before you draw, you build a second list of vertices, calculated as the sum of the original vertices plus the current asset.position, and use that second list for rendering.
The whole thing is... not very OpenGL. There's really no need to modify the vertex coordinates on the CPU. You can make the translation part of the transformation applied in your vertex shader. You already have a model matrix in place. You can simply put the translation by asset.position into the model matrix, and recalculate the MVP matrix. You already have the glUniformMatix4fv() call to pass the new matrix to the shader program in your renderAsset() function.
I'm trying to draw some basic triangles using opengl, but it's not rendering on screen. These are the relevant functions:
glewInit();
glClearColor(0.0, 0.0, 0.0, 1.0);
glFrontFace(GL_CW);
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
Vertex vertices[] = {Vertex(Vector3f(0.0, 1.0, 0.0)),
Vertex(Vector3f(-1.0, -1.0, 0.0)),
Vertex(Vector3f(1.0, -1.0, 0.0))};
mesh.addVertices(vertices, 3);
Pastebin links to Vertex.hpp and Vector3f.hpp:
Vertex.hpp
Vector3f.hpp
/*
* Mesh.cpp:
*/
Mesh::Mesh()
{
glGenBuffers(1, &m_vbo); // unsigned int Mesh::m_vbo
}
void Mesh::addVertices(Vertex vertices[4], int indexSize)
{
m_size = indexSize * 3;
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, m_size, vertices, GL_STATIC_DRAW);
}
void Mesh::draw()
{
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 4 * sizeof(Vertex), 0);
glDrawArrays(GL_TRIANGLES, 0, m_size);
glDisableVertexAttribArray(0);
}
It's just black if I call glClear otherwise just the random noise of a default window. I can make it draw a triangle by using the most primitive method:
glBegin(GL_TRIANGLES);
glColor3f(0.4, 0.0, 0.0);
glVertex2d(0.0, 0.5);
glVertex2d(-0.5, -0.5);
glVertex2d(0.5, -0.5);
glEnd();
That works and displays what it should do correctly, so I guess that at least says my application is not 100% busted. The tutorial I'm following is in Java, and I'm translating it to C++ SFML as I go along, so I guess it's possible that something got lost in translation so to speak, unless I'm just missing something really basic (more likely.)
How do we fix this so it uses the Vertex list to draw the triangle like it's supposed to?
So many mistakes. There are truly a lot of examples, in any language, so why?
const float pi = 3.141592653589793; is member field of Vector3f. Do you realise this is non-static member and it is included in each and every Vector3f you use, so your vectors actually have four elements - x, y, z, and pi? Did you informed GL about it, so it could skip this garbage data? I don't think so.
You using glVertexAttribPointer, but don't have active shader. There is no guarantee that position is in slot 0. Either use glVertexPointer, or use shader with position attribute bound to 0.
void Mesh::addVertices(Vertex vertices[4], int indexSize) what [4] supposed to mean here? While it is not an error, it is at least misguiding.
glBufferData(GL_ARRAY_BUFFER, m_size, vertices, GL_STATIC_DRAW); m_size is 3*3 in your example, while documentation says it should be array size in bytes - which is sizeof(Vertex) * indexSize.
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 4 * sizeof(Vertex), 0); why stride parameter is 4*sizeof(Vertex)? Either set it to 0 or write correct stride - which is sizeof(Vertex).
glDrawArrays(GL_TRIANGLES, 0, m_size); m_size is already [incorrectly] set as "vertex buffer size", while DrawArrays expects number of vertices to draw - which is m_size / sizeof(Vertex) (given m_size is calculated correctly).
I'm trying to get a small triangle to display.
Here is my initialization code:
void PlayerInit(Player P1)
{
glewExperimental = GL_TRUE;
glewInit();
//initialize buffers needed to draw the player
GLuint vao;
GLuint buffer;
glGenVertexArrays(1, &vao);
glGenBuffers(1, &buffer);
//bind the buffer and vertex objects
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
//Set up a buffer to hold 6 floats for position, and 9 floats for color
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*18, NULL, GL_STATIC_DRAW);
//push the vertices of the player into the buffer
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*9, CalcPlayerPoints(P1.GetPosition()));
//push the color of each player vertex into the buffer
glBufferSubData(GL_ARRAY_BUFFER, sizeof(float)*9, sizeof(float)*9, CalcPlayerColor(1));
//create and compile the vertex/fragment shader objects
GLuint vs = create_shader("vshader.glsl" ,GL_VERTEX_SHADER);
GLuint fs = create_shader("fshader.glsl" ,GL_FRAGMENT_SHADER);
//create a program object and link the shaders
GLuint program = glCreateProgram();
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
//error checking for linking
GLint linked;
glGetProgramiv(program, GL_LINK_STATUS, &linked);
if(!linked)
{
std::cerr<< "Shader program failed to link" <<std::endl;
GLint logSize;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logSize);
char* logMsg = new char[logSize];
glGetProgramInfoLog(program, logSize, NULL, logMsg);
std::cerr<< logMsg << std::endl;
delete [] logMsg;
exit(EXIT_FAILURE);
}
glUseProgram(program);
//create attributes for color and position to pass to shaders
//enable each attribute
GLuint Pos = glGetAttribLocation( program, "vPosition");
glEnableVertexAttribArray(Pos);
GLuint Col = glGetAttribLocation( program, "vColor");
glEnableVertexAttribArray(Col);
//set a pointer at the proper offset into the buffer for each attribute
glVertexAttribPointer(Pos, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*) (sizeof(float)*0));
glVertexAttribPointer(Col, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*) (sizeof(float)*9));
}
I don't have much experience writing shader linkers, so I think that is where the problem might be. I have some error checking in the shader loader, and nothing comes up. So I think that is fine.
Next I have my display and main function:
//display function for the game
void GameDisplay( void )
{
//set the background color
glClearColor(1.0, 0.0, 1.0, 1.0);
//clear the screen
glClear(GL_COLOR_BUFFER_BIT);
//Draw the Player
glDrawArrays(GL_TRIANGLES, 0, 3);
glutSwapBuffers();
}
//main function
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(500, 500);
glutCreateWindow("Asteroids");
Player P1 = Player(0.0, 0.0);
PlayerInit(P1);
glutDisplayFunc(GameDisplay);
glutMainLoop();
return 0;
}
Vertex shader :
attribute vec3 vPosition;
attribute vec3 vColor;
varying vec4 color;
void main()
{
color = vec4(vColor, 1.0);
gl_Position = vec4(vPosition, 1.0);
}
Fragment shader
varying vec4 color;
void main()
{
gl_FragColor = color;
}
That's all of the relevant code. CalcPlayerPoints just returns a float array of size 9 to hold the triangle coordinates. CalcPlayerColor does something similar.
One last problem that may help with diagnosing the problem is that whenever I try to exit the program by closing the window of the application, I get a breakpoint in the glutmainloop, however if I close the console window, it exits fine.
Edit: I added the shaders for reference.
Edit: I am using opengl version 3.1
Without the shaders, we can't say if the faulty code isn't GLSL (bad vertices transformations, etc.)
Have you tried checking glGetError to see if the problem doesn't come from your initialization code ?
Maybe try to set the output of your fragment shader to, say, vec4(1.0, 0.0, 0.0, 1.0) to check if its normal output is ill-formed.
Your last problem seems to unveil an undefined behavior, like bad memory allocation/deallocation, which may take place in your Player class (by the way consider passing the object as a reference in your initialization code, because it may at the moment trigger a shallow copy and then a double-free of some pointer).
Turns out there was something wrong with how I was returning the array of vertices from the function used to compute them. The rest of the code worked fine after that fix.