Thread: Help with file reading/dynamic memory allocation

  1. #1
    Registered User
    Join Date
    May 2004
    Posts
    19

    Help with file reading/dynamic memory allocation

    Hi there, i never worked with dynamic memory allocation in C++, that is the new and delete. I'm creating an open GL based graphics engine and i need to read files with deep exploration structure, that is:

    Code:
    struct sample_MATERIAL{
     GLfloat ambient[3];
     GLfloat diffuse[3];
     GLfloat specular[3];
     GLfloat emission[3];
     GLfloat alpha;
     GLfloat phExp;
     int   texture;
    };
    
    struct sample_TEXTURE{
     char * name;
     GLint  id;
    };
    
    sample_MATERIAL materials[];
    sample_TEXTURE texture_maps[];
    GLfloat face_indicies[][9];
    GLfloat vertices[][3];
    GLfloat normals[][3];
    GLfloat textures[][2];
    int material_ref[][2] ;
    I converted this structure to a plain text file, with values separated by spaces, recreated a similar structure and functions to read the file:

    FILE: "data_parser.h"
    Code:
    #include <iostream.h>
    #include <fstream.h>
    #include <process.h>
    #include <math.h>
    #include <string.h>
    #include <GL\glut.h>
    #include <stdio.h>
    
    struct Material
    {
     GLfloat ambient[3];
     GLfloat diffuse[3];
     GLfloat specular[3];
     GLfloat emission[3];
     GLfloat alpha;
     GLfloat phExp;
     GLint   texture;
    };
    
    struct TextureMap
    {
     char *name;
     GLint  id;
    };
    
    struct FaceIndex
    {
    	GLint index[9];
    };
    
    struct Vertex
    {
    	GLfloat vertex[3];
    };
    
    struct Normal
    {
    	GLfloat normal[3];
    };
    
    struct TextureCoord
    {
    	GLfloat coord[2];
    };
    
    struct MaterialIndex
    {
    	GLint index[2];
    };
    
    struct Model
    {
     Material *materials_list;
     TextureMap *texture_maps_list;
     FaceIndex *face_indicies_list;
     Vertex *vertices_list;
     Normal *normals_list;
     TextureCoord *texture_coords_list;
     MaterialIndex *material_indicies_list;
     GLint materials_list_size;
     GLint texture_maps_list_size;
     GLint face_indicies_list_size;
     GLint vertices_list_size;
     GLint normals_list_size;
     GLint texture_coords_list_size;
     GLint material_indicies_list_size;
    };
    
    int GetInt(ifstream infile);
    float GetFloat(ifstream infile);
    
    void ProcessHeader(ifstream infile, Model *model);
    void ProcessMaterialsList(ifstream infile, Model *model);
    void ProcessTextureMapsList(ifstream infile, Model *model);
    void ProcessFaceIndiciesList(ifstream infile, Model *model);
    void ProcessVerticesList(ifstream infile, Model *model);
    void ProcessNormalsList(ifstream infile, Model *model);
    void ProcessTextureCoordsList(ifstream infile, Model *model);
    void ProcessMaterialIndiciesList(ifstream infile, Model *model);
    
    void ModelFileParser(static char *filename, Model *model);
    ==================================================

    FILE: "data_parser.cpp"
    Code:
    #include "data_parser.h"
    
    unsigned int data_error = GL_FALSE;
    
    int GetInt(ifstream infile)
    {
    	char c;
    	int buffer = 0;
    	int negative = 0;
    	int done = 0;
    	while(!done)
    	{
    		infile.get(c);
    		if(c == '-')
    			negative = 1;
    		else if((c >= '0') && (c <= '9'))
    		{
    			c = c - 48;
    			buffer = (buffer * 10) + c;
    		}
    		else if(c == ' ')
    		{
    			if(negative)
    				buffer = -buffer;
    			done = 1;
    		}
    		else if(c == -1)
    			done = 1;
    	}
    	return buffer;
    }
    
    float GetFloat(ifstream infile)
    {
    	char c;
    	float buffer = 0;
    	int exp_buffer = 0;
    	int negative = 0, decimal = 0, exp = 0, exp_negative = 0;
    	double order = 0.1;
    	int done = 0;
    	while(!done)
    	{
    		infile.get(c);
    		if(c == '-')
    		{
    			if(exp)
    				exp_negative = 1;
    			else
    				negative = 1;
    		}
    		else if(c == '.')
    			decimal = 1;
    		else if(c == 'e')
    		{
    			exp = 1;
    			decimal = 0;
    		}
    		else if((c >= '0') && (c <= '9'))
    		{
    			c = c - 48;
    			if(decimal)
    			{
    				buffer = buffer + (c * order);
    				order *= 0.1;
    			}
    			else if(exp)
    				exp_buffer = (exp_buffer * 10) + c;
    			else
    				buffer = (buffer * 10) + c;
    		}
    		else if(c == ' ')
    		{
    			if(negative)
    				buffer = -buffer;
    			if(exp)
    			{
    				if(exp_negative)
    					exp_buffer = -exp_buffer;
    				buffer = buffer * pow(10, exp_buffer);
    			}
    			done = 1;
    		}
    		else if(c == -1)
    			done = 1;
    	}
    	return buffer;
    }
    
    void ProcessHeader(ifstream infile, Model *model)
    {
    	model->materials_list_size = GetInt(infile);
    	model->texture_maps_list_size = GetInt(infile);
    	model->face_indicies_list_size = GetInt(infile);
    	model->vertices_list_size = GetInt(infile);
    	model->normals_list_size = GetInt(infile);
    	model->texture_coords_list_size = GetInt(infile);
    	model->material_indicies_list_size = GetInt(infile);
    }
    
    void ProcessMaterialsList(ifstream infile, Model *model)
    {
    	int i = 0, j = 0;
    	model->materials_list = new Material[model->materials_list_size];
    	while(i < model->materials_list_size)
    	{
    		for (j = 0; j < 3; j++)
    			model->materials_list[i].ambient[j] = GetFloat(infile);
    		for (j = 0; j < 3; j++)
    			model->materials_list[i].diffuse[j] = GetFloat(infile);
    		for (j = 0; j < 3; j++)
    			model->materials_list[i].specular[j] = GetFloat(infile);
    		for (j = 0; j < 3; j++)
    			model->materials_list[i].emission[j] = GetFloat(infile);
    		model->materials_list[i].alpha = GetFloat(infile);
    		model->materials_list[i].phExp = GetFloat(infile);
    		model->materials_list[i].texture = GetInt(infile);
    		i++;
    	}
    }
    
    void ProcessTextureMapsList(ifstream infile, Model *model)
    {
    
    	int i = 0, j = 0, init = 0;
    	int done = 0;
    	char c;
    	char buffer[100];
    	buffer[0];
    	model->texture_maps_list = new TextureMap[model->texture_maps_list_size];
    	for (i = 0; i < model->texture_maps_list_size; i++)
    	{
    		model->texture_maps_list[i].name = new char[100];
    		while (!done)
    		{
    			infile.get(c);
    		if((c == ' ') || (c == -1))
    		{
    			j = 0;
    			model->texture_maps_list[i].id = GetInt(infile);
    				done = 1;
    		}
    		else
    		{
    			model->texture_maps_list[i].name[j] = c;
    			j++;
    		}
    		}
    	}
    }
    void ProcessFaceIndiciesList(ifstream infile, Model *model)
    {
    	model->face_indicies_list = new FaceIndex[model->face_indicies_list_size];
    	for(int i = 0; i < model->face_indicies_list_size; i++)
    	{
    		for(int j = 0; j < 9; j++)
    			model->face_indicies_list[i].index[j] = GetInt(infile);
    	}
    }
    
    void ProcessVerticesList(ifstream infile, Model *model)
    {
    	model->vertices_list = new Vertex[model->vertices_list_size];
    	for(int i = 0; i < model->vertices_list_size; i++)
    	{
    		for(int j = 0; j < 3; j++)
    			model->vertices_list[i].vertex[j] = GetFloat(infile);
    	}
    }
    
    void ProcessNormalsList(ifstream infile, Model *model)
    {
    	model->normals_list = new Normal[model->normals_list_size];
    	for(int i = 0; i < model->normals_list_size; i++)
    	{
    		for(int j = 0; j < 3; j++)
    			model->normals_list[i].normal[j] = GetFloat(infile);
    	}
    }
    
    void ProcessTextureCoordsList(ifstream infile, Model *model)
    {
    	model->texture_coords_list = new TextureCoord[model->texture_coords_list_size];
    	for(int i = 0; i < model->texture_coords_list_size; i++)
    	{
    		for(int j = 0; j < 2; j++)
    			model->texture_coords_list[i].coord[j] = GetFloat(infile);
    	}
    }
    
    void ProcessMaterialIndiciesList(ifstream infile, Model *model)
    {
    	model->material_indicies_list = new MaterialIndex[model->material_indicies_list_size];
    	for(int i = 0; i < model->material_indicies_list_size; i++)
    	{
    		for(int j = 0; j < 2; j++)
    			model->material_indicies_list[i].index[j] = GetInt(infile);
    	}
    }
    
    void ModelFileParser(static char *filename, Model *model)
    {
    	ifstream infile;
    	infile.open(filename, ios::nocreate);
    	if (!infile)
    	{
    		data_error = GL_TRUE;
    				printf("error");
    	}
    	else
    	{
    		ProcessHeader(infile, model);
    		ProcessMaterialsList(infile, model);
    		ProcessTextureMapsList(infile, model);
    		ProcessFaceIndiciesList(infile, model);
    		ProcessVerticesList(infile, model);
    		ProcessNormalsList(infile, model);
    		ProcessTextureCoordsList(infile, model);
    		ProcessMaterialIndiciesList(infile, model);
    		infile.close();
    	}
    }
    ==================================================

    The ModelFileParser starts by calling the ProcessHeader function which stores the size of every array. Then each individual function reads the data it is supposed to read, based on the size of the array retrieved by the header processing function. However i can't get the ProcessTextureMapsList function to work, no matter how i read the file i always get one of two scenarios:
    1. Error, i am trying to write to somethng that doesn't exit, or
    2. I manage to read the string and copy it to the model structure, but it ends with tons of trailing chars that further along make me unable to read the texture file, because it's file name is something like "texture.bmp_a_lot_of_stuff_i_didn't_really_want_t o_read".

    Can anyone help me out here?

    Also, i couldn't figure how to work with NxM arrays and the new operator, so had to create all those structures to make it work. if anyone has any idea how to make this work with this structure, for me to get rid of all the others, i would greatlly apreciate:

    Code:
    struct Model
    {
     Material *materials_list;
     TextureMap *texture_maps_list;
     GLint *face_indicies_list[9];
     GLfloat *vertices_list[3];
     GLfloat *normals_list[3];
     GLfloat *texture_coords_list[2];
     GLint *material_indicies_list[2];
     GLint materials_list_size;
     GLint texture_maps_list_size;
     GLint face_indicies_list_size;
     GLint vertices_list_size;
     GLint normals_list_size;
     GLint texture_coords_list_size;
     GLint material_indicies_list_size;
    };
    Thanks.
    Last edited by Quasar; 05-17-2004 at 11:46 AM.

  2. #2
    Registered User
    Join Date
    May 2004
    Posts
    19
    Another version of ProcessTextureMapsList, again it doesn't work because buffer isn't initialized, however if i initialize it i must make it match the size of the string it is going to read, so that i don't get an error when copying the strings (writing to an invalid address).

    Code:
    void ProcessTextureMapsList(ifstream infile, Model *model)
    {
    	char c;
    	char *buffer;
    	int i = 0, j = 0;
    	model->texture_maps_list = new TextureMap[model->texture_maps_list_size];
    	while(i < model->texture_maps_list_size)
    	{
    		infile.get(c);
    		if (c == ' ')
    		{
    				model->texture_maps_list[i].name = new char[j];
    				strcpy(model->texture_maps_list[i].name, buffer);
    				model->texture_maps_list[i].id = GetInt(infile);
    				j = 0;
    				i++;
    		}
    		else
    		{
    			buffer[j] = c;
    			j++;
    		}
    
    	}
    }

  3. #3
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Code:
    		if((c == ' ') || (c == -1))
    		{
    			j = 0;
    			model->texture_maps_list[i].id = GetInt(infile);
    				done = 1;
    		}
    Once you're done reading the name, you need to add a string terminator to name.
    Code:
    		if((c == ' ') || (c == -1))
    		{
    			model->texture_maps_list[i].name[j] = '\0';
    			j = 0;
    			model->texture_maps_list[i].id = GetInt(infile);
    				done = 1;
    		}

  4. #4
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    >Also, i couldn't figure how to work with NxM arrays and the new operator
    See Prelude's post here on how to allocate two dimensional arrays:

    http://cboard.cprogramming.com/showt...ghlight=memory

  5. #5
    Registered User
    Join Date
    May 2004
    Posts
    19
    all solved, it's perfect now, thnx for the help.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Newbie homework help
    By fossage in forum C Programming
    Replies: 3
    Last Post: 04-30-2009, 04:27 PM
  2. File transfer- the file sometimes not full transferred
    By shu_fei86 in forum C# Programming
    Replies: 13
    Last Post: 03-13-2009, 12:44 PM
  3. Inventory records
    By jsbeckton in forum C Programming
    Replies: 23
    Last Post: 06-28-2007, 04:14 AM
  4. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 02:53 AM
  5. Encryption program
    By zeiffelz in forum C Programming
    Replies: 1
    Last Post: 06-15-2005, 03:39 AM