There are several things wrong with your code.
First, you have completely redundant pieces of code that clearly abuse dynamic memory allocation. As in this snippet:
float *temp=new float[numv*5];
for (int i=0; i<numv*5; i++)
temp[i]=vars[i];
delete[]vars;vars=NULL;
vars=new float[numv*5+5];
for (int i=0; i<numv*5; i++)
vars[i]=temp[i];
delete[]temp;temp=NULL; You allocate, copy, delete, allocate, copy and delete. One of those repetition is useless. Here is the proper way to do it:
float *temp=new float[numv*5 + 5]; //allocate with new size.
for (int i=0; i<numv*5; i++)
temp[i]=vars[i]; //copy.
delete[]vars;vars=NULL; //delete old data.
vars = temp; //swap pointers.
//then, fill the values of the new element. Additionally, the use of a C-style array is very inefficient. You should use std::vector instead, or, at least, preallocate enough memory ahead of time.
Secondly, in Compile(), you don't need to build two new arrays for the vertices and tex-coords that are already interleaved in your "vars" array. OpenGL already has functionality to handle this kind of interleaved arrays (which is standard practice too). This is handled using the "stride" parameter in all the functions. So, all you need in Compile() to send your vertices and tex-coords is the following:
glGenBuffers(1,&model);
glBindBuffer(GL_ARRAY_BUFFER, model);
glBufferData(GL_ARRAY_BUFFER, numv * 5 * sizeof(float), vars, GL_STATIC_DRAW); //notice '5' and 'vars' And then, in your Draw() function, you can simply do:
glBindBuffer(GL_ARRAY_BUFFER, model);
glVertexPointer(3, GL_FLOAT, 5 * sizeof(float), 0);
glTexCoordPointer(2, GL_FLOAT, 5 * sizeof(float), 3 * sizeof(float) ); The last two parameters first tell OpenGL to skip 5 floats between each vertex, and then tell it to start at an offset of 3 floats from the start of the array (for the tex-coords). This will avoid you any unnecessary creation of temporary arrays and copying, then sending to OpenGL and then deleting, which is incredibly wasteful (which is why this "stride" functionality is standard everywhere in OpenGL and many other libraries that do similar things).
Finally, lets get to the real issue here, the one that makes your program crash. When using OpenGL VBOs, you have two choices about things like normals and colors, either you have one for all vertices, or you have one for each vertex. What you did was give OpenGL one normal vector for each triangle. That's not how it goes. When you do DrawArrays(), OpenGL will expect to find 'numv' normal vectors and will try to read 'numv' normal vectors, even though you actually have 'numn' normals. You will end up reading significantly past the size of the normal vector array, and it will crash the program. You need to have one normal vector per vertex in your model (even if you simply set the normal vectors of all the points on one triangle to the same vector-value).
With all those things in mind, this is probably going to work much better:
class glModel
{
private:
int numv;
int numn;
unsigned int model;
struct VertDef {
float v[3];
float t[2];
float n[3];
};
VertDef *vars;
public:
glModel() : numv(0), numn(0), model(0), vars(NULL) { }
glModel& Vertex(float tx, float ty, float x, float y, float z);
glModel& Compile();
glModel& Draw();
glModel& Move(float x, float y, float z){glTranslatef(x,y,z);} //IMO, this function is entirely useless.
};
glModel& glModel::Vertex(float tx, float ty, float x, float y, float z)
{
VertDef* temp = new VertDef[numv + 1];
for (int i = 0; i < numv; ++i)
temp[i] = vars[i];
delete[] vars; vars = temp; temp = NULL;
vars[numv].t[0] = tx;
vars[numv].t[1] = ty;
vars[numv].v[0] = x;
vars[numv].v[1] = y;
vars[numv].v[2] = z;
vars[numv].n[0] = 0.0;
vars[numv].n[1] = 0.0;
vars[numv].n[2] = 0.0;
++numv;
if (numv%3==0)
{
float z3 = vars[numv-1].v[2];
float y3 = vars[numv-1].v[1];
float x3 = vars[numv-1].v[0];
float z2 = vars[numv-2].v[2];
float y2 = vars[numv-2].v[1];
float x2 = vars[numv-2].v[0];
float z1 = vars[numv-3].v[2];
float y1 = vars[numv-3].v[1];
float x1 = vars[numv-3].v[0];
float dx1 = x2 - x1; float dx2 = x3 - x1;
float dy1 = y2 - y1; float dy2 = y3 - y1;
float dz1 = z2 - z1; float dz2 = z3 - z1;
float ox = dy1 * dz2 - dz1 * dy2;
float oy = dz1 * dx2 - dx1 * dz2;
float oz = dx1 * dy2 - dy1 * dx2;
float mag=sqrt(ox*ox+oy*oy+oz*oz);
ox/=mag;
oy/=mag;
oz/=mag;
vars[numv-1].n[0] = ox;
vars[numv-1].n[1] = oy;
vars[numv-1].n[2] = oz;
vars[numv-2].n[0] = ox;
vars[numv-2].n[1] = oy;
vars[numv-2].n[2] = oz;
vars[numv-3].n[0] = ox;
vars[numv-3].n[1] = oy;
vars[numv-3].n[2] = oz;
numn++;
}
return *this;
}
glModel &glModel::Compile()
{
glGenBuffers(1, &model);
glBindBuffer(GL_ARRAY_BUFFER, model);
glBufferData(GL_ARRAY_BUFFER, numv*sizeof(VertDef), vars, GL_STATIC_DRAW);
return *this;
}
glModel& glModel::Draw()
{
if(numn == 0)
return *this;
glBindBuffer(GL_ARRAY_BUFFER, model);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(VertDef), 0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(VertDef), &(vars[0].t[0]) - &(vars[0].v[0]));
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, sizeof(VertDef), &(vars[0].n[0]) - &(vars[0].v[0]));
glDrawArrays(GL_TRIANGLE, 0, 3 * numn); //draw only vertices that are part of a triangle.
return *this;
}