Hi, I've written a program that reads object information from an ASCII file (exported from 3dsmax) so that an object/objects can be reproduced in OpenGL. It works fine at the minute and can read multiple objects from a single file but what I want to be able to do is specify more than one file and store the data in seperate arrays.
I am currently using two variables 'int ***facets' and 'float ***vertices' to store the vertices and facet windings of all shapes in a single file ("scene.ASE"). I now want to extend that so that I could say use 'int ***tableFacets' and 'float ***tableVertices' to store the vertices and facet windings of the file "table.ASE" aswell.
Code below:
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "glut.h"
#include <GL\gl.h>
#include <GL\glu.h>
int ***facets;
float ***vertices;
int *nFacets;
int *nVertices;
int ***tableFacets;
float ***tableVertices;
int ***boxFacets;
float ***boxVertices;
int numObjects;
int number = 0;
int numShapes = 1;
int numCols = 3;
GLfloat rquad;
GLfloat ud = 0.0;
GLfloat lr = 0.0;
GLfloat zz = 5.0;
GLfloat rShapeY = 0.0;
GLfloat rShapeX = 0.0;
GLfloat rShapeZ = 0.0;
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 Keyboard(unsigned char key, int x, int y);
void SpecialKeys(int key, int x, int y);
void polygon(int a, int b, int c, int i);
void shape();
void DrawGround();
void loadShape(char filename[20]);
char *readFile(FILE *sceneFile);
void countObjects(char fileName[20])
{
char * fullFile = readFile(fopen (fileName, "rb"));
char * pch;
char * delim = " *\x9\xA\xD\\:";
int i;
numObjects = 0;
pch = strtok(fullFile, delim);
while(pch != NULL)//while NEOF
{
if(strcmp(pch, "GEOMOBJECT")==NULL)
numObjects++;
pch = strtok(NULL, delim);
}
vertices = (float ***) calloc(numObjects, sizeof(float **));
facets = (int ***) calloc(numObjects, sizeof(int **));
nVertices = (int *) calloc(numObjects, sizeof(int));
nFacets = (int *) calloc(numObjects, sizeof(int));
}
void SetupRC()
{
// Light values and coordinates
GLfloat ambientLight[] = { 0.3f, 0.3f, 0.3f, 1.0f };
GLfloat diffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f };
glEnable(GL_DEPTH_TEST); // Hidden surface removal
glFrontFace(GL_CCW); // Counter clock-wise polygons face out
glEnable(GL_CULL_FACE); // Do not calculate inside of objects
// Enable lighting
glEnable(GL_LIGHTING);
// Setup and enable light 0
glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight);
glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight);
glEnable(GL_LIGHT0);
// Enable color tracking
glEnable(GL_COLOR_MATERIAL);
//Set up and enable light 0
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glEnable(GL_LIGHT0);
//Enable colour tracking
glEnable(GL_COLOR_MATERIAL);
// Set Material properties to follow glColor values
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
// Light blue background
glClearColor(0.0f, 0.0f, 1.0f, 1.0f );
//Rescale normals to unit length
glEnable(GL_NORMALIZE);
}
int main(int argc, char **argv)
{
loadShape("scene.ASE");
//loadShape("test_box.ASE");
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("TEST READING ASCII FILE");
glutDisplayFunc(display);
glutReshapeFunc(adjustSize);
//glutMouseFunc(mouse);
glutKeyboardFunc(Keyboard);
glutSpecialFunc(SpecialKeys);
glutIdleFunc(animate);
glEnable(GL_DEPTH_TEST); //enable hidden surface removal
SetupRC();
glutMainLoop();
return 0;
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(lr,ud,zz,0.0,0.0,0.0,0.0,1.0,0.0);
//Draw the ground
//DrawGround();
glPushMatrix();
glRotatef(rShapeY, 0.0f, 1.0f, 0.0f);
glRotatef(rShapeX, 1.0f, 0.0f, 0.0f);
glRotatef(rShapeZ, 0.0f, 0.0f, 1.0f);
shape();
glPopMatrix();
glFlush();
glutSwapBuffers();
}
void adjustSize(GLsizei w, GLsizei h)
{
float size = 200.0;
//Prevent a divide by zero
if(h == 0)
h = 1;
//Set viewport to window dimensions
glViewport(0,0,w,h);
//Reset coordinate system
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-size, size, -size * (GLfloat) h / (GLfloat) w, size * (GLfloat) h / (GLfloat) w, -size, size);
else if (h <= w)
glOrtho(-size * (GLfloat) w / (GLfloat) h, size * (GLfloat) w / (GLfloat) h, -size, size, -size, size);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void animate()
{
//rquad -= 0.15f;
display();
}
void polygon(int a, int b, int c, int i)
{
//glBegin(GL_POLYGON);
glBegin(GL_LINE_LOOP);
glColor3ub(0,0,0);
glVertex3fv(vertices[i][a]);
glVertex3fv(vertices[i][b]);
glVertex3fv(vertices[i][c]);
glEnd();
}
void shape()
{
int i, j;
for(i = 0; i < numObjects; ++i)
{
for(j = 0; j < nFacets[i]; ++j)
{
polygon(facets[i][j][0], facets[i][j][1], facets[i][j][2],i);
}
}
}
void loadShape(char fileName[20])
{
char *fullFile = readFile(fopen (fileName, "rb"));
char *pch;
int v, f;
char *delim = " *\x9\xA\xD\\:";
int i, nObj;
countObjects(fileName);
nObj = -1;
pch = strtok(fullFile, delim);
while(pch != NULL)
{
if(strcmp(pch, "GEOMOBJECT") == NULL)
nObj++;
if(strcmp(pch, "MESH_NUMVERTEX") == NULL)
{
nVertices[nObj] = atoi(strtok (NULL, delim));
vertices[nObj] = (float **) calloc(nVertices[nObj], sizeof(float *));
for(i = 0; i < nVertices[nObj]; ++i)
vertices[nObj][i] = (float *) calloc(numCols, sizeof(float));
}
if(strcmp(pch, "MESH_NUMFACES") == NULL)
{
nFacets[nObj] = atoi(strtok (NULL, delim));
facets[nObj] = (int **) calloc(nFacets[nObj], sizeof(int *));
for(i = 0; i < nFacets[nObj]; ++i)
facets[nObj][i] = (int *) calloc(numCols, sizeof(int));
}
if(strcmp(pch, "MESH_VERTEX") == NULL)
{
v = atoi(strtok (NULL, delim));
printf("v=%d\n", v);
for(i = 0; i < numCols; ++i)
{
vertices[nObj][v][i] = atof(strtok (NULL, delim));
}
}
if(strcmp(pch, "MESH_FACE") == NULL)
{
f = atoi(strtok (NULL, delim));
for(i = 0; i < numCols; ++i)
{
strtok(NULL, delim);
facets[nObj][f][i] = atof(strtok (NULL, delim));
}
}
pch = strtok (NULL, delim);
}
free (fullFile);
if(number = 0){
tableVertices = vertices;
tableFacets = facets;}
else{
boxVertices = vertices;
boxFacets = facets;
}
number++;
}
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;
}
void Keyboard(unsigned char key, int x, int y)
{
switch(key)
{
case 'd':
//ud += 0.1f;
rShapeY += 1.0f;
break;
case 'a':
//ud -= 0.1f;
rShapeY -= 1.0f;
break;
case 's':
//lr += 0.1f;
rShapeX += 1.0f;
break;
case 'w':
//lr += 0.1f;
rShapeX -= 1.0f;
break;
case 'r':
rShapeZ += 1.0f;
break;
case 'f':
rShapeZ -= 1.0f;
break;
}
}
void SpecialKeys(int key, int x, int y)
{
switch(key)
{
case GLUT_KEY_UP:
//zz += 1.0f;
ud -= 1.0f;
break;
case GLUT_KEY_DOWN:
//zz -= 1.0f;
ud += 1.0f;
break;
case GLUT_KEY_LEFT:
lr -= 0.1f;
break;
case GLUT_KEY_RIGHT:
lr += 0.1f;
break;
}
}
/*void DrawGround(void)
{
GLfloat fExtent = 200.0f;
GLfloat fStep = 10.0f;
GLfloat y = -0.4f;
GLint iLine;
glBegin(GL_LINES);
for(iLine = -fExtent; iLine <= fExtent; iLine += fStep)
{
glVertex3f(iLine, y, fExtent); //Draw Z lines
glVertex3f(iLine, y, -fExtent);
glVertex3f(fExtent, y, iLine);
glVertex3f(-fExtent, y, iLine);
}
glEnd();
}*/
I have tried passing variables into the loadshape method to store the data that would be loaded but I haven't had any success and I can't really see much of a way to make my code as generic as I want (hence the post).
Any help would be greatly appreciated, thanks :)