Hi, I am basically writing a program that reads in ASCII files exported from 3ds max in order to reproduce an object in OpenGL. My code works fine for one object and I've even got it working for two as long as the second object contains less vertices/facet windings than the previous. Problem is, if I try and load any more than two or if the first object is 'smaller' than any that follow, my program crashes. I don't have much experiene using C but I'm pretty sure it's something to do with the way in which I am trying to allocate and then reallocate the memory for my 3d array.
I've attached the ASCII files (as text files because I can't upload .ASE files) that I'm trying to read and a text file with the actual code(for, perhaps, easier viewing). Any help would be greatly appreciated
code below:
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "glut.h"
#include <GL\gl.h>
#include <GL\glu.h>
GLint ***facets;
GLfloat ***vertices;
int nRows, nCols, row, col, i, j, k, numVertices, numFacets, shapeNum;
int numShapes = 2;
int numCols = 3;
GLfloat rquad;
//int totalVertices = 0;
//int totalFacets = 0;
int nFacets[10];
int nVertices[10];
GLfloat colors[][3] = {{0.0,0.0,0.0},{1.0,0.0,0.0},{1.0,1.0,0.0},{0.0,1.0,0.0},{0.0,0.0,1.0},{1.0,0.0,1.0},{1.0,1.0,1.0},
{0.0,1.0,1.0}};
//All methods used
void display();
void adjustSize(GLsizei, GLsizei);
void animate();
//void mouse(int btn, int state, int x, int y);
void polygon(int a, int b, int c, int shapeNum);
void shape(int shapeNum);
void loadShape(char filename[20], int shapeNum);
char *readFile(FILE *sceneFile);
GLint ***allocate_memoryi(int nShapes, int nRows, int nCols)
{
int ***shapeArray;
shapeArray = (int***) malloc(nShapes * sizeof(int**));
for(i=0; i<nShapes; ++i)
{
shapeArray[i] = (int**) malloc(nRows * sizeof(int));
for(j=0; j<nRows; ++j)
{
shapeArray[i][j] = (int*) malloc(nCols * sizeof(int));
}
}
return shapeArray;
}
GLfloat ***allocate_memoryf(int nShapes, int nRows, int nCols)
{
float ***shapeArray;
shapeArray = (float***) malloc(nShapes * sizeof(float**));
for(i=0; i<nShapes; ++i)
{
shapeArray[i] = (float**) malloc(nRows * sizeof(float));
for(j=0; j<nRows; ++j)
{
shapeArray[i][j] = (float*) malloc(nCols * sizeof(float));
}
}
return shapeArray;
}
GLfloat ***reallocate_memoryf(int nShapes, int nRows, int nCols)
{
float ***shapeArray;
shapeArray = (float***) realloc(vertices, nShapes * sizeof(float**));
for(i=0; i<nShapes; ++i)
{
shapeArray[i] = (float**) realloc(vertices[i], nVertices[i] * sizeof(float));
for(j=0; j<nVertices[i]; ++j)
{
shapeArray[i][j] = (float*) realloc(vertices[i][j], nCols * sizeof(float));
}
}
return shapeArray;
}
GLint ***reallocate_memoryi(int nShapes, int nRows, int nCols)
{
int ***shapeArray;
shapeArray = (int***) realloc(facets, nShapes * sizeof(int**));
for(i=0; i<nShapes; ++i)
{
shapeArray[i] = (int**) realloc(facets[i], nFacets[i] * sizeof(int));
for(j=0; j<nFacets[i]; ++j)
{
shapeArray[i][j] = (int*) realloc(facets[i][j], nCols * sizeof(int));
}
}
return shapeArray;
}
int main(int argc, char **argv)
{
loadShape("test_pyramid.ASE", 0);//won't work this way round as pyramid requires less vertices/facet windings
loadShape("test_sphere.ASE", 1);
//loadShape("test_sphere.ASE", 0);
//loadShape("test_pyramid.ASE", 1);//does work this way round
//loadShape("test_box.ASE", 2); as soon as a third shape is added it also crashes
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("TEST READING ASCII FILE");
glutDisplayFunc(display);
glutReshapeFunc(adjustSize);
//glutMouseFunc(mouse);
glutIdleFunc(animate);
glEnable(GL_DEPTH_TEST); //enable hidden surface removal
glutMainLoop();
return 0;
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glRotatef(rquad, 1.0f, 1.0f, 1.0f);
glColor3f(0.0f, 0.0f, 1.0f);
shape(0);
shape(1);
//shape(2);
glFlush();
glutSwapBuffers();
}
void adjustSize(GLsizei w, GLsizei h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-30.0, 30.0, -30.0 * (GLfloat) h / (GLfloat) w,30.0 * (GLfloat) h / (GLfloat) w, -100.0, 100.0);
else if (h <= w)
glOrtho(-30.0 * (GLfloat) w / (GLfloat) h, 30.0 * (GLfloat) w / (GLfloat) h, -30.0, 30.0, -100.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void animate()
{
rquad -= 0.15f;
display();
}
void polygon(int a, int b, int c, int shapeNum)
{
//for(i = 0; i < numShapes; ++i)
//{
//glBegin(GL_POLYGON);
glBegin(GL_LINE_LOOP);
glColor3f(0.0,0.0,1.0);
//glColor3fv(colors[a]);
glVertex3fv(vertices[shapeNum][a]);
//glColor3fv(colors[b]);
glVertex3fv(vertices[shapeNum][b]);
//glColor3fv(colors[c]);
glVertex3fv(vertices[shapeNum][c]);
glEnd();
//}
}
void shape(int shapeNum)
{
for(row = 0; row < nFacets[shapeNum]; ++row)
{
polygon(facets[shapeNum][row][0], facets[shapeNum][row][1], facets[shapeNum][row][2], shapeNum);
}
}
void loadShape(char filename[20], int shapeNum)
{
char *fullFile = readFile(fopen (filename, "rb"));
char *pch;
int v, f;
char *delim = " *\x9\xA\xD\\:";
pch = strtok(fullFile, delim);
while(pch != NULL)
{
if(strcmp(pch, "MESH_NUMVERTEX") == NULL)
{
numVertices = atoi(strtok (NULL, delim));
printf("numVertices%d\n", numVertices);
//totalVertices += numVertices;
nVertices[shapeNum] = numVertices;
if(shapeNum == 0)
vertices = allocate_memoryf(numShapes, nVertices[shapeNum], numCols);
else
vertices = reallocate_memoryf(numShapes, numVertices, numCols);
}
if(strcmp(pch, "MESH_NUMFACES") == NULL)
{
numFacets = atoi(strtok (NULL, delim));
printf("numFacets%d\n", numFacets);
//totalFacets += numFacets;
nFacets[shapeNum] = numFacets;
if(shapeNum == 0)
facets = allocate_memoryi(numShapes, nFacets[shapeNum], numCols);
else
facets = reallocate_memoryi(numShapes, numFacets, numCols);
}
if(strcmp(pch, "MESH_VERTEX") == NULL)
{
v = atoi(strtok (NULL, delim));
printf("v=%d\n", v);
for(i = 0; i < numCols; ++i)
{
vertices[shapeNum][v][i] = atof(strtok (NULL, delim));
printf("%f ", vertices[shapeNum][v][i]);
}
printf("\n");
}
if(strcmp(pch, "MESH_FACE") == NULL)
{
f = atoi(strtok (NULL, delim));
strtok (NULL, delim);
for(i = 0; i < numCols; ++i)
{
facets[shapeNum][f][i] = atoi(strtok (NULL, delim));
printf("%d: ", facets[shapeNum][f][i]);
strtok(NULL, delim);
}
}
pch = strtok (NULL, delim);
}
free (fullFile);
}
char *readFile(FILE *sceneFile)
{
long fileSize;
char *fullFile;
size_t result;
if(sceneFile==NULL)
{
fputs ("Error 1", stderr);
exit(1);
}
fseek(sceneFile, 0, SEEK_END);
fileSize = ftell(sceneFile);
rewind(sceneFile);
fullFile = (char*)malloc(sizeof(char)*fileSize);
if(fullFile == NULL)
{
fputs("Error 2", stderr);
exit(2);
}
result = fread(fullFile,1,fileSize,sceneFile);
if(result != fileSize)
{
fputs("Error 3", stderr);
exit(3);
}
fclose(sceneFile);
return fullFile;
}