PDA

View Full Version : Trying to load multiple models in C for openGL



RET80
12-03-2011, 08:10 PM
I have a .obj loader that reads in and separates the obj files into verts, faces and normals, as seen here in a IONmodel.c file

(also if it looks too long, just scroll down to the bottom for what exactly is needed help with...It sounds pretty simple, I just need help with return variables and such)



IONmodel* ION_loadModel(const char* filename){

IONmodel* newModel = (IONmodel*)malloc( sizeof(IONmodel) );
//INITS
//STRANGE: MING does NOT like 70,000 as a char array size
char stringArray[40000][51];
char keySpace[] = " ";
int i = 0;
int j =0;
int k =0;
int text = 0;
long size = 0;
int keySpacePositionTemp2;
int keySpacePositionTemp3;
float temp = 0.000000000;
float temp2 = 0.000000000;
float temp3 = 0.000000000;



float *vertexBuffer;
float *Faces_Triangles;
float *normals;

long TotalConnectedPoints = 0;
long TotalConnectedTriangles = 0;

int tempInt1 = 0;
int tempInt2 = 0;
int tempInt3 = 0;

int triangle_index = 0;
int normal_index = 0;


//create file reader
FILE *file = fopen(filename, "r");

//Check to see if file exists
if (file == NULL)
{
printf("ERROR OPENING FILE!");
return -1; // -1 means file opening fail
}

//Check file size
fseek(file, 0, SEEK_END);
size = ftell(file);
printf("Size of file: %d \n",size);
fseek(file, 0, SEEK_SET);


vertexBuffer = (float*) malloc (size);
Faces_Triangles = (float*) malloc(size*sizeof(float));
normals = (float*) malloc(size*sizeof(float));


//parse through entire obj file and store as a 2D char array
char line[50];
while( fgets(line, sizeof(line), file) != NULL)
{
//output file as a string
printf(line);
for(text = 0; text <= sizeof(line); text++){
//read in file as a 2D array of chars
stringArray[i][text] = line[text];
}
i++;
}

//close obj file
fclose(file);


//seperating portions of the .obj file into v, vt, f
for(j = 0; j < i; j++){

//PORTION v
if(strncmp (stringArray[j], "v ",3) == 0){
printf("Entered v portion ----- \n");

//read in initial number, 0+3 ignores initial white space
temp = atof(&amp;stringArray[j][0+3]);
printf("float converted from the string: %f\n", temp);


//temp2 read in. Reads in leading whitespace as an index
keySpacePositionTemp2 = strcspn (&amp;stringArray[j][0+3],keySpace);

printf("Key Space Position for temp2: %d\n", keySpacePositionTemp2);

temp2 = atof(&amp;stringArray[j][keySpacePositionTemp2+3]);
printf("float converted from the string: %f\n", temp2);


//temp3 read in. Reads in leading whitespace of previous and current for index
keySpacePositionTemp3 = strcspn (&amp;stringArray[j][keySpacePositionTemp2+4],keySpace);

printf("Key Space Position temp3: %d\n", keySpacePositionTemp2+keySpacePositionTemp3);

temp3 = atof(&amp;stringArray[j][keySpacePositionTemp2+keySpacePositionTemp3+4]);
printf("float converted from the string: %f\n", temp3);


//use the temp values and store them into the vector buffer
vertexBuffer[TotalConnectedPoints] = temp;
vertexBuffer[TotalConnectedPoints+1] = temp2;
vertexBuffer[TotalConnectedPoints+2] = temp3;

//increment counter by sets of 3 (X, Y, Z)
TotalConnectedPoints += POINTS_PER_VERTEX;
}




//PORTION vt
else if(strncmp (stringArray[j], "vt ",3) == 0){
printf("Entered vt portion ----- \n");


//read in initial number, 0+3 ignores initial white space
temp = atof(&amp;stringArray[j][0+4]);
printf("float converted from the string: %f\n", temp);


//temp2 read in. Reads in leading whitespace as an index
keySpacePositionTemp2 = strcspn (&amp;stringArray[j][0+4],keySpace);

printf("Key Space Position for temp2: %d\n", keySpacePositionTemp2);

temp2 = atof(&amp;stringArray[j][keySpacePositionTemp2+4]);
printf("float converted from the string: %f\n", temp2);


//temp3 read in. Reads in leading whitespace of previous and current for index
keySpacePositionTemp3 = strcspn (&amp;stringArray[j][keySpacePositionTemp2+5],keySpace);

printf("Key Space Position temp3: %d\n", keySpacePositionTemp2+keySpacePositionTemp3);

temp3 = atof(&amp;stringArray[j][keySpacePositionTemp2+keySpacePositionTemp3+5]);
printf("float converted from the string: %f\n", temp3);



}

//PORTION f reads in only first values before '/' calculations will be done later
//PORTION f ignores vt and n delimiters
else if(strncmp (stringArray[j], "f ",2) == 0){
printf("Entered f portion ----- \n");


//read in initial number, 0+2 ignores initial white space
tempInt1 = atoi(&amp;stringArray[j][0+2]);
printf("int converted from the string: %d\n", tempInt1);


//tempInt2 read in. Reads in leading whitespace as an index
keySpacePositionTemp2 = strcspn (&amp;stringArray[j][0+2],keySpace);

printf("Key Space Position for temp2: %d\n", keySpacePositionTemp2);

tempInt2 = atoi(&amp;stringArray[j][keySpacePositionTemp2+2]);
printf("int converted from the string: %d\n", tempInt2);


//tempInt3 read in. Reads in leading whitespace of previous and current for index
keySpacePositionTemp3 = strcspn (&amp;stringArray[j][keySpacePositionTemp2+3],keySpace);

printf("Key Space Position temp3: %d\n", keySpacePositionTemp2+keySpacePositionTemp3);

tempInt3 = atoi(&amp;stringArray[j][keySpacePositionTemp2+keySpacePositionTemp3+3]);
printf("int converted from the string: %d\n", tempInt3);


int vertexNumber[4] = { 0, 0, 0 };

vertexNumber[0] = tempInt1;
vertexNumber[1] = tempInt2;
vertexNumber[2] = tempInt3;

vertexNumber[0] -= 1;
vertexNumber[1] -= 1;
vertexNumber[2] -= 1;
printf("VertexNumber is: %d %d %d\n",tempInt1,tempInt2,tempInt3);
printf("Face vertex at 0 and minusing -1 for obj count: %d %d %d\n", vertexNumber[0],vertexNumber[1],vertexNumber[2]);

//arrange vertexBuffer into sets of 3 triangle groupings
int tCounter = 0;
int l = 0;
for (l = 0; l < POINTS_PER_VERTEX; l++)
{

Faces_Triangles[triangle_index + tCounter ] = vertexBuffer[3*vertexNumber[l] ];
Faces_Triangles[triangle_index + tCounter +1 ] = vertexBuffer[3*vertexNumber[l]+1 ];
Faces_Triangles[triangle_index + tCounter +2 ] = vertexBuffer[3*vertexNumber[l]+2 ];
tCounter += POINTS_PER_VERTEX;


}


//calculate normals to be used for lighting
float coord1[3] = {Faces_Triangles[triangle_index], Faces_Triangles[triangle_index+1],Faces_Triangles[triangle_index+2]};
float coord2[3] = {Faces_Triangles[triangle_index+3],Faces_Triangles[triangle_index+4],Faces_Triangles[triangle_index+5]};
float coord3[3] = {Faces_Triangles[triangle_index+6],Faces_Triangles[triangle_index+7],Faces_Triangles[triangle_index+8]};
float *norm = ION_calculateModelNormals( coord1, coord2, coord3 );

//insert normals to appropriate pointers
tCounter = 0;
int m = 0;
for (m = 0; m < POINTS_PER_VERTEX; m++)
{
normals[normal_index + tCounter ] = norm[0];
normals[normal_index + tCounter +1] = norm[1];
normals[normal_index + tCounter +2] = norm[2];
tCounter += POINTS_PER_VERTEX;
}



triangle_index += TOTAL_FLOATS_IN_TRIANGLE;
normal_index += TOTAL_FLOATS_IN_TRIANGLE;
//for some reason not used here...
TotalConnectedTriangles += TOTAL_FLOATS_IN_TRIANGLE;
}
}
printf("\n\n\n");
printf ("triangle_index: %d\n", triangle_index);
printf("normal_index: %d\n",normal_index);
printf("TotalConnectedTriangles: %d\n",TotalConnectedTriangles);
printf("Total connected points: %d\n",TotalConnectedPoints);
int testSize = sizeof(vertexBuffer);
printf("Total vertex index: %d", testSize);


newModel->vertexBuffer;
newModel->Faces_Triangles;
newModel->normals;
newModel->TotalConnectedTriangles;

return newModel;
}


(please excuse the sloppy code, I'm testing it in bits and pieces)
The code WILL load and separate just fine as well.

I also have a IONmodel.h file with a typedef struct:


typedef struct
{
float* vertexBuffer;
float* Faces_Triangles;
float* normals;
long TotalConnectedTriangles;
} IONmodel;


Now my question is. I would like to pass the variables down form the loader to other functions, like my drawing function, but how do I do this. Also, I noticed it only works if I load just ONE model and that's it.

So what I would like to do is be able to load multiple models and draw them.

Here are my drawing functions:


IONmodel* ION_calculateModel()
{
long i = 0, j = 0, k;

//TRIANGLES
glLoadIdentity();
glTranslatef(0.0f,-2.0f,-10.0f);
glRotatef(rotate, 0.0f, 1.0f, 0.0f);

// Draw all the vertices needs total number of verticies num_vertex_indices
glBegin(GL_TRIANGLES);
while (i <= TotalConnectedTriangles)
{

// Draw the vertex and texture as sets of 3 (TRIANGLES)
for (k = 0; k < 3; k++)
{

//to test shape with color depth
float red;
float green;
glColor3f(red,green,1.0f);
red = red + 0.0001;
green = green + 0.0001;

glVertex3f(Faces_Triangles[i],Faces_Triangles[i+1],Faces_Triangles[i+2]);
glNormal3f(normals[i],normals[i+1],normals[i+2]);
i = i + 3;
}
}

rotate++;

glEnd();

//reset rotations
if(rotate == 360)
{
rotate = 0;
}

return 0;
}


so in my main I would call for example:


int main(int argc, char **argv)
{
ION_loadModel("/rd/field.obj");
ION_cameraInit(640,480,45.0,0.0001,1000);
while(1)
{
ION_renderModel();
}

return 0;
}


The ION_loadModel will work but I can't get renderModel working, because, frankly, I dont know how to pass variables down to other functions or how to use the typedef struct to my advantage, getter/setters maybe?

you'll notice that there are variables being called in the other functions like 'TotalConnectedTriangles' because I made all of the loader's variables public, but what was happening was that if I loaded 2 or more models, it would just overwrite the public variables and make an awful mess.

I seriously need help :)