I recently made my own vertex class, vertexColored, to hold position and color data. I changed from passing a std::vector of glm::vec3 to my VBO, to passing a std::vector of vectorColored. The class is defined like this:
//vertexTypes.h
#ifndef VERTEXTYPES_H
#define VERTEXTYPES_H
#include <glm\glm.hpp>
class vertexColored
{
public:
vertexColored();
~vertexColored();
glm::vec3 vertexPos;
glm::vec4 vertexColor;
};
#endif // VERTEXTYPES_H
//vertexTypes.cpp
#include "vertexTypes.h"
vertexColored::vertexColored()
{
this->vertexPos = glm::vec3(0.0f, 0.0f, 0.0f);
this->vertexColor = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f);
}
vertexColored::~vertexColored()
{
}
And I have also brush.h:
//brush.h
#ifndef BRUSH_H
#define BRUSH_H
#include <GL/glew.h>
#include <glm/glm.hpp>
#include <vector>
#include "vertexTypes.h"
class brush
{
public:
brush();
~brush();
void updateVertices();
void render();
void makeBuffers();
//other stuff...
private:
GLuint vboId, iboId;
std::vector<vertexColored> brushVecs;
std::vector<GLuint> brushIndices;
//other stuff...
};
#endif // BRUSH_H
And inside brush.cpp:
#include "brush.h"
brush::brush()
{
this->size = 2;
this->brushVecs.reserve(0);
this->brushIndices.reserve(0);
}
brush::~brush()
{
glDeleteBuffers(1, &(this->vboId));
glDeleteBuffers(1, &(this->iboId));
}
void brush::updateVertices(){
int numPoints = ((2 * this->size) + 1) * ((2 * this->size) + 1);
if (this->brushVecs.capacity() < numPoints)
{
this->brushVecs.reserve(numPoints);
}
vertexColored baseVertex;
this->brushVecs.resize(numPoints, baseVertex);
int curX = this->pos.x - this->size;
int index = 0;
while (curX <= this->pos.x + this->size){
int curZ = this->pos.z - this->size;
while (curZ <= this->pos.z + this->size){
this->brushVecs[index].vertexPos = glm::vec3((float)curX, 0.0f, (float)curZ);
this->brushVecs[index].vertexColor = glm::vec4(0.0f, 0.7f, 0.5f, 1.0f);
index++;
curZ++;
}
curX++;
}
if (this->brushIndices.capacity() < numPoints)
{
this->brushIndices.reserve(numPoints);
}
this->brushIndices.resize(numPoints, 0);
index = 0;
while (index < numPoints){
this->brushIndices[index] = index;
index++;
}
}
void brush::makeBuffers(){
glGenBuffers(1, &(this->vboId));
glBindBuffer(GL_ARRAY_BUFFER, this->vboId);
glBufferData(GL_ARRAY_BUFFER, this->brushVecs.size()*sizeof(vertexColored), &this->brushVecs[0], GL_DYNAMIC_DRAW);
glGenBuffers(1, &(this->iboId));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->iboId);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->brushIndices.size()*sizeof(GLuint), &this->brushIndices[0], GL_DYNAMIC_DRAW);
}
void brush::render(){
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glUseProgram(this->progId);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->iboId);
glBindBuffer(GL_ARRAY_BUFFER, this->vboId);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertexColored), (GLvoid*)0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(vertexColored), (GLvoid*)sizeof(glm::vec3));
glDrawElements(GL_POINTS, this->getNumPoints(), GL_UNSIGNED_INT, (GLvoid*)0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glUseProgram(0);
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
}
All this renders correctly - I don’t detect any problems while the program’s running. However, when I close the window (I’m using Qt for windowing), my IDE (Visual Studio 2010) stays in debugging mode for a few seconds. Then a popup shows up, saying:
Windows has triggered a breakpoint in qt_integration_test.exe.
This may be due to a corruption of the heap, which indicates a bug in qt_integration_test.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while qt_integration_test.exe has focus.
The output window may have more diagnostic information.
The output window contains multiple copies of the same message, all preceded by something like:
HEAP[qt_integration_test.exe]: Invalid address specified to RtlFreeHeap( 005F0000, 03CDF180 )
Or:
First-chance exception at 0x76f71bee in qt_integration_test.exe: 0xC0000005: Access violation reading location 0x07440018.
First-chance exception at 0x76f71bee in qt_integration_test.exe: 0xC0000005: Access violation reading location 0x07440018.
HEAP[qt_integration_test.exe]: HEAP: Free Heap block 745f840 modified at 745f854 after it was freed
I have no idea why these errors are arising. I googled heap corruption and found it could be a buffer overflow somewhere, but my buffers were fine back when I was passing a plain old vector of glm::vec3’s - and I’m pretty sure I set the stride and everything right for my own custom class. And if it is the VBO or IBO overflowing, why didn’t I get an error while running the program? Why only after I close it?
I tried defining a struct instead of a class in vertexTypes.h and got the same errors. At this point I’m lost. I’m not sure what could possibly be trying to access things in memory after the window closes. Has anyone experienced something similar, or have any idea why this is happening?