Problem with vector.push_back()

Started by
9 comments, last by jake_Ghost 18 years, 10 months ago
I have an ms3d ascii file loader and i have a problem. I have a class called cModel which is the big momma class. It has all teh model info saved in it. When I push the vector called model it has a class in it called Model which gives me a generic windows error... This program has encountered an error and needs to be closed. Sorry for the inconvince... heres the classes...

#ifndef _MS3D_ASCII_H
#define _MS3D_ASCII_H

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <gl/gl.h>
#include <assert.h>
#include "Matrix.h"
#include <vector>
#include <string>


#define MS_MAX_NAME 32
#define MS_MAX_PATH 256


class Vec
{
	public:
		void	transform( const Matrix& m );
		void	transform3( const Matrix& m );
		float	x,y,z;
		float	w;										
		float	u,v;							// Texture position
		int		bone;										
};


class Tri
{
	public:
		int		v[3];								
		int		n[3];										
};


class Normal
{
	public:
		float	x,y,z;
};
	

//////////////////////////////////////
//The Shape Class
//////////////////////////////////////
class Shape 
{
	public:
		Shape();
		~Shape();

		bool loadFromFile( const char *filename );
		bool loadFromMs3dAsciiSegment( FILE *file );

		bool saveToFile( const char *filename );
		void render( void );

		int	num_vertices;
		Vec	*vertices;

		int	num_triangles;
		Tri	*triangles;

		int	num_normals;
		Normal	*normals;
};


//////////////////////////////////////
//The Material Class
//////////////////////////////////////
class Material
{
	public:
		Material();
		~Material();

		bool loadFromMs3dAsciiSegment( FILE *file );
		void activate( void );
		void reloadTexture( void );

	private:
		char  Name[MS_MAX_NAME];
		float Ambient[4];
		float Diffuse[4];
		float Specular[4];
		float Emissive[4];
		float Shininess;
		float Transparency;
		char  DiffuseTexture[MS_MAX_NAME];
		char  AlphaTexture[MS_MAX_NAME];
		GLuint texture;
};


//////////////////////////////////////
//The Model Class
//////////////////////////////////////
class Model
{
	public:
		Model();
		~Model();

		bool loadFromMs3dAsciiFile( const char *filename );
		void reloadTextures( void );
		void render( void );

	protected:													
		float x,y,z;

	private:
		int	num_shapes;
		Shape *shapes;
		int	*material_indices;

		int	num_materials;
		Material *materials;
};

typedef struct
{
	Model obj;
	std::string Name;
	GLuint objList;
} sModel;

class cModel
{
public:
	cModel();
	~cModel();

	bool LoadModel(std::string Name);
	void Render(std::string Name);

private:
	std::vector<sModel> model;
	int ModelCount;
};

extern cModel cmod;

#endif



heres the .cpp file



#include "jpeg.h"
#include "ms3d_ascii.h" 


/////////////////////////////////////////////////////////////////////////////////////////////////
//										The Shape Class
/////////////////////////////////////////////////////////////////////////////////////////////////
Shape::Shape()
{
	num_vertices = 0;
	vertices = NULL;
	num_triangles = 0;
	triangles = NULL;
	num_normals = 0;
	normals = NULL;
}

Shape::~Shape()
{
	if(vertices != NULL)
		delete[] vertices;	
	if(triangles != NULL)
		delete[] triangles;
	if(normals != NULL)
		delete[] normals;
}


bool Shape::loadFromFile( const char *filename )
{
	FILE	*fp;
	int	i;
	
	fp = fopen(filename, "r");
	if(fp == NULL)
		return false;
	
	fscanf(fp, "%d\n", &num_vertices );
	
	vertices = new Vec[num_vertices];
	
	for(i = 0 ; i < num_vertices; i++)
	{
		fscanf(fp, "%f %f %f %f %f\n", 
			&vertices.x,
			&vertices.y,
			&vertices.z,
			&vertices.u,
			&vertices.v );
	}
	
	fscanf(fp, "%d\n", &num_triangles );
	
	triangles = new Tri[num_triangles];
	for(i = 0 ; i < num_triangles; i++)
	{
		fscanf(fp, "%d %d %d\n",
			&triangles.v[0],
			&triangles.v[1],
			&triangles.v[2] );
	}
	
	fclose(fp);
	
	return true;
}


bool Shape::saveToFile( const char *filename )
{
	FILE	*fp;
	int	i;
	
	fp = fopen(filename, "w");
	if(fp == NULL)
		return false;
	
	fprintf(fp, "%d\n", num_vertices );
	
	for(i = 0 ; i < num_vertices; i++)
	{
		fprintf(fp, "%f %f %f %f %f\n", 
			vertices.x,
			vertices.y,
			vertices.z,
			vertices.u,
			vertices.v );
	}
	
	fprintf(fp, "%d\n", num_triangles );
	
	for(i = 0 ; i < num_triangles; i++)
	{
		fprintf(fp, "%d %d %d\n",
			triangles.v[0],
			triangles.v[1],
			triangles.v[2] );
	}
	fclose(fp);
	return true;
}


void Shape::render( void )
{
	int	i,j;
	Tri	*tri;
	Vec	*vec;
	Normal *N;
	
	glBegin(GL_TRIANGLES);
	for(i = 0; i < num_triangles; i++)				// for each triangle
	{
		tri = triangles + i;						// pointer to triangle
		
		for(j = 0; j < 3; j++)						// 3 vertices of the triangle
		{
			N = normals + tri->n[j];
			glNormal3f(N->x, N->y, N->z);			// set normal vector  (object space)
			
			vec = vertices + tri->v[j];				// pointer to vertex
			glTexCoord2f (vec->u, vec->v);			// texture coordinate
			
			glVertex3f( vec->x, vec->y, vec->z );	// 3d coordinate (object space)
		}
	}
	glEnd();
}



bool Shape::loadFromMs3dAsciiSegment( FILE *file )
{
    bool bError = false;
    char szLine[256];
    int nFlags, nIndex, j;
	
	
	// vertices
	
	if (!fgets (szLine, 256, file))
	{
		return false;
	}
	
	if (sscanf (szLine, "%d", &num_vertices) != 1)
	{
		return false;
	}
				vertices = new Vec[num_vertices];
				
                for (j = 0; j < num_vertices; j++)
                {
                    if (!fgets (szLine, 256, file))
                    {
						return false;
					}
                    if (sscanf (szLine, "%d %f %f %f %f %f %d",
                        &nFlags,
                        &vertices[j].x, &vertices[j].y, &vertices[j].z,
                        &vertices[j].u, &vertices[j].v
                        ) != 7)
					{
						return false;
					}
					// adjust the y direction of the texture coordinate
					vertices[j].v = 1.0f - vertices[j].v;
                }
				
				
                // normals
				
                if (!fgets (szLine, 256, file))
                {
					return false;
                }
				
                if (sscanf (szLine, "%d", &num_normals) != 1)
                {
					return false;
                }
				normals = new Normal[num_normals];
				
                for (j = 0; j < num_normals; j++)
                {
                    if (!fgets (szLine, 256, file))
                    {
						return false;
                    }
					
                    if (sscanf (szLine, "%f %f %f", 
						&normals[j].x, &normals[j].y, &normals[j].z) != 3)
                    {
						return false;
					}
                }
				
                // triangles
				
                if (!fgets (szLine, 256, file))
                {
					return false;
                }
				
                if (sscanf (szLine, "%d", &num_triangles) != 1)
                {
					return false;
				}
				triangles = new Tri[num_triangles];
				
                for (j = 0; j < num_triangles; j++)
                {
                    if (!fgets (szLine, 256, file))
                    {
						return false;
                    }
					
                    if (sscanf (szLine, "%d %d %d %d %d %d %d %d",
                        &nFlags,
                        &triangles[j].v[0], &triangles[j].v[1], &triangles[j].v[2],
                        &triangles[j].n[0], &triangles[j].n[1], &triangles[j].n[2],
                        &nIndex
                        ) != 8)
                    {
						return false;
                    }
					assert(triangles[j].v[0] >= 0);
					assert(triangles[j].v[0] < num_vertices);
					assert(triangles[j].v[1] >= 0);
					assert(triangles[j].v[1] < num_vertices);
					assert(triangles[j].v[2] >= 0);
					assert(triangles[j].v[2] < num_vertices);
				}
				
				return true;
}



/////////////////////////////////////////////////////////////////////////////////////////////////
//										The Material Class
/////////////////////////////////////////////////////////////////////////////////////////////////
Material::Material()	
{
}

Material::~Material()	
{
}

void Material::activate( void )
{
	glMaterialfv( GL_FRONT, GL_AMBIENT, Ambient );
	glMaterialfv( GL_FRONT, GL_DIFFUSE, Diffuse );
	glMaterialfv( GL_FRONT, GL_SPECULAR, Specular );
	glMaterialfv( GL_FRONT, GL_EMISSION, Emissive );
	glMaterialf( GL_FRONT, GL_SHININESS, Shininess );
	
	if ( texture > 0 )
	{
		glBindTexture( GL_TEXTURE_2D, texture );
		glEnable( GL_TEXTURE_2D );
	}
	else
		glDisable( GL_TEXTURE_2D );
}

bool Material::loadFromMs3dAsciiSegment( FILE *file )
{
    char szLine[256];
	
    // name
    if (!fgets (szLine, 256, file))
		return false;
    if (sscanf (szLine, "\"%[^\"]\"", Name) != 1)
		return false;
	
	// ambient
    if (!fgets (szLine, 256, file))
		return false;
	
	if (sscanf (szLine, "%f %f %f %f", &Ambient[0], &Ambient[1], &Ambient[2], &Ambient[3]) != 4)
		return false;
	
    // diffuse
    if (!fgets (szLine, 256, file))
		return false;
    if (sscanf (szLine, "%f %f %f %f", &Diffuse[0], &Diffuse[1], &Diffuse[2], &Diffuse[3]) != 4)
		return false;
	
    // specular
    if (!fgets (szLine, 256, file))
		return false;
    if (sscanf (szLine, "%f %f %f %f", &Specular[0], &Specular[1], &Specular[2], &Specular[3]) != 4)
		return false;
	
    // emissive
    if (!fgets (szLine, 256, file))
		return false;
    if (sscanf (szLine, "%f %f %f %f", &Emissive[0], &Emissive[1], &Emissive[2], &Emissive[3]) != 4)
		return false;
	
    // shininess
    if (!fgets (szLine, 256, file))
		return false;
    if (sscanf (szLine, "%f", &Shininess) != 1)
		return false;
	
    // transparency
    if (!fgets (szLine, 256, file))
		return false;
    if (sscanf (szLine, "%f", &Transparency) != 1)
		return false;
	
    // diffuse texture
    if (!fgets (szLine, 256, file))
		return false;
	strcpy(DiffuseTexture, "");
    sscanf (szLine, "\"%[^\"]\"", DiffuseTexture);
	
    // alpha texture
    if (!fgets (szLine, 256, file))
		return false;
	strcpy(AlphaTexture, "");
    sscanf (szLine, "\"%[^\"]\"", AlphaTexture);
	
	reloadTexture();
	
	return true;
}

void Material::reloadTexture( void )
{
	if( strlen(DiffuseTexture) > 0 )
	{			
		JPEG_Texture(&texture,DiffuseTexture,0);
	}
	else	texture = 0;
}




/////////////////////////////////////////////////////////////////////////////////////////////////
//										The Model Class
/////////////////////////////////////////////////////////////////////////////////////////////////
Model::Model()
{
	num_shapes = 0;
	shapes = NULL;
	num_materials = 0;
	materials = NULL;
}

Model::~Model()
{
	
	if(shapes != NULL)
	{
		delete[] shapes;
		shapes = NULL;
	}
	if(materials != NULL)
	{
		delete[] materials;
		materials = NULL;
	}
	if(material_indices != NULL)
	{
		delete[] material_indices;
		material_indices = NULL;
	}
}

bool Model::loadFromMs3dAsciiFile( const char *filename )
{
    bool	bError = false;
    char	szLine[256];
    int		nFlags, nIndex, i;
	
	FILE *file = fopen (filename, "rt");
	if (!file)
		return false;
	
    while (fgets (szLine, 256, file) != NULL  && !bError)
    {
        if (!strncmp (szLine, "//", 2))
            continue;
		
        if (sscanf (szLine, "Meshes: %d", &num_shapes) == 1)
        {
			char	szName[MS_MAX_NAME];
			
			shapes = new Shape[num_shapes];
			material_indices = new int[num_shapes];
			
            for (i = 0; i < num_shapes && !bError; i++)
            {
				
                if (!fgets (szLine, 256, file))
                {
                    bError = true;
                    break;
                }
				
                // mesh: name, flags, material index
                if (sscanf (szLine, "\"%[^\"]\" %d %d",szName, &nFlags, &nIndex) != 3)
                {
                    bError = true;
                    break;
                }
				material_indices = nIndex;
				
				if( ! shapes.loadFromMs3dAsciiSegment(file) )
                {
                    bError = true;
                    break;
                }
			}
            continue;
		}
		
		
        // materials
		
        if (sscanf (szLine, "Materials: %d", &num_materials) == 1)
        {
            int i;
			
			materials = new Material[num_materials];
			
            for (i = 0; i < num_materials && !bError; i++)
            {
				if( ! materials.loadFromMs3dAsciiSegment(file) )
                {
                    bError = true;
                    break;
                }
			}
            continue;
        }
		
    }
	
	fclose (file);

	
	
	return true;
}




void Model::reloadTextures( void )
{
	int	i;
	
	for(i = 0; i < num_materials; i++)	// for each shape
	{
		materials.reloadTexture();
	}
}

#if 0
void Model::render( void )
{
	int	i;
	
	for(i = 0; i < num_shapes; i++)	// for each shape
	{
		int materialIndex = material_indices;
		if ( materialIndex >= 0 )
		{
			materials[materialIndex].activate();
		}
		else
		{
			glDisable( GL_TEXTURE_2D );
		}
		shapes.render();
	}
}
#endif

void Model::render( void )
{
	int	k;
	int	i, j;
	Tri	*tri;
	Vec	*vec;
	Normal *N;
	
	for(k = 0; k < num_shapes; k++)	// for each shape
	{
		int materialIndex = material_indices[k];
		if ( materialIndex >= 0 )
		{
			materials[materialIndex].activate();
		}
		else
		{
			// Material properties?
			glDisable( GL_TEXTURE_2D );
		}
		
		glBegin(GL_TRIANGLES);
		for(i = 0; i < shapes[k].num_triangles; i++)	// for each triangle
		{
			tri = shapes[k].triangles + i;				// pointer to triangle
			
			for(j = 0; j < 3; j++)						// 3 vertices of the triangle
			{
				N = shapes[k].normals + tri->n[j];
				glNormal3f(N->x, N->y, N->z);			// set normal vector  (object space)
				
				vec = shapes[k].vertices + tri->v[j];	// pointer to vertex
				glTexCoord2f (vec->u, vec->v);			// texture coordinate
				
				glVertex3f( vec->x , vec->y, vec->z);	
				
			}
			
		}
		glEnd();
	}
}

cModel :: cModel()
{
}

cModel :: ~cModel()
{
}

bool cModel :: LoadModel(std::string Name)
{
	sModel tmpModel;
	model.push_back(tmpModel);
	ModelCount += 1;

	if (!model[ModelCount - 1].obj.loadFromMs3dAsciiFile(Name.c_str()))
	{
		return FALSE;
	}

	//model[ModelCount - 1].Name = Name;

	model[ModelCount - 1].objList = glGenLists(1);

	glNewList(model[ModelCount - 1].objList,GL_COMPILE);
		model[ModelCount - 1].obj.render();
	glEndList();

	return TRUE;
}

void cModel :: Render(std::string Name)
{
	for (int i = 0; i < ModelCount; i++)
	{
		if (model.Name == Name)
		{
			glCallList(model.objList);
		}
	}
}


can anyone see why I cannot push the vector? Jake
Advertisement
The "rule of three": A class which has any one or more of (1) a copy constructor, (2) a destructor, or (3) an assignment operator, almost definitely needs all 3. In your case, you need to define a copy constructor, because the default copy constructor is copying pointers to memory that has already been freed. STL containers make heavy use of the copy constructor.
Hey thanks man. How would I add the copy constructor(s). Its been a while since I've used one and I currently don't have any c++ books on hand.

Jake
Here's an example of a copy constructor.

class Foo{public:    Foo(const Foo &oldFoo)    {        i = oldFoo.i;    }private:    int i;};
So would I do something like this....

class Vec{	public:                Vec(const Vec &oldVec)                {                    x = oldVec.x;                    y = oldVec.y;                    ect....                }		void	transform( const Matrix& m );		void	transform3( const Matrix& m );		float	x,y,z;		float	w;												float	u,v;							// Texture position		int		bone;										};


Jake
Vec probably doesn't need a copy constructor, since it doesn't need a destructor. Classes without a defined copy constructor will have one automatically generated by the compiler, which performs a "member-wise copy"; that is, each member variable will be copied.
OK I added what I thought was a copy constructor but it still doesn't work. Probably did something wrong...

class Shape {	public:		Shape();		~Shape();				Shape(const Shape &oldShape)		{			num_vertices = oldShape.num_vertices;			vertices = oldShape.vertices;			num_triangles = oldShape.num_triangles;			triangles = oldShape.triangles;			num_normals = oldShape.num_normals;			normals = oldShape.normals;		}		bool loadFromFile( const char *filename );		bool loadFromMs3dAsciiSegment( FILE *file );		bool saveToFile( const char *filename );		void render( void );		int	num_vertices;		Vec	*vertices;		int	num_triangles;		Tri	*triangles;		int	num_normals;		Normal	*normals;};////////////////////////////////////////The Material Class//////////////////////////////////////class Material{	public:		Material();		~Material();		Material(const Material &oldMat)		{			Name[MS_MAX_NAME] = oldMat.Name[MS_MAX_NAME];			Ambient[4] = oldMat.Ambient[4];			Diffuse[4] = oldMat.Diffuse[4];			Specular[4] = oldMat.Specular[4];			Emissive[4] = oldMat.Emissive[4];			Shininess = oldMat.Shininess;			Transparency = oldMat.Transparency;			DiffuseTexture[MS_MAX_NAME] = oldMat.DiffuseTexture[MS_MAX_NAME];			AlphaTexture[MS_MAX_NAME] = oldMat.AlphaTexture[MS_MAX_NAME];			texture = oldMat.texture;		}		bool loadFromMs3dAsciiSegment( FILE *file );		void activate( void );		void reloadTexture( void );	private:		char  Name[MS_MAX_NAME];		float Ambient[4];		float Diffuse[4];		float Specular[4];		float Emissive[4];		float Shininess;		float Transparency;		char  DiffuseTexture[MS_MAX_NAME];		char  AlphaTexture[MS_MAX_NAME];		GLuint texture;};////////////////////////////////////////The Model Class//////////////////////////////////////class Model{	public:		Model();		~Model();		Model(const Model &oldMod)		{			x = oldMod.x;			y = oldMod.y;			z = oldMod.z;			num_shapes = oldMod.num_shapes;			shapes = oldMod.shapes;			material_indices = oldMod.material_indices;			num_materials = oldMod.num_materials;			materials = oldMod.materials;		}		bool loadFromMs3dAsciiFile( const char *filename );		void reloadTextures( void );		void render( void );	protected:															float x,y,z;	private:		int	num_shapes;		Shape *shapes;		int	*material_indices;		int	num_materials;		Material *materials;};


Jake
Add this code to your original post and it should work fine (obviously there must be some typos, since I dindn't attempt to compile it, but I think the logic is ok).

This code would be smaller and cleaner if you had added copy constructors and copy operators to all of your classes, this is definityly not the way to do it, but It should work.

Good look, please tell me if it works.

Model::Model(const Model &m){    num_shapes = m.num_shapes;    if (num_shapes &gt; 0)    {        shapes = new Shapes[num_shapes]            material_indices=new int[num_shapes];        memcpy(material_indices, m.material_indices, sizeof(int)*num_shapes);        for (size_t i=0; i&lt;num_shapes; i++)        {            shapes.num_vertices=m.shapes.num_vertices;            if (shapes.num_vertices &gt; 0)            {                shapes.vertices= new Vec[shapes.num_vertices];                memcpy(shapes.vertices, m.shapes.vertices, sizeof(Vec)*shapes.num_vertices);            }            else                shapes.vertices='\0';            shapes.num_triangles=m.shapes.num_triangles;            if (shapes.num_triangles &gt; 0)            {                shapes.triangles=new Tri[shapes.num_triangles];                memcpy(shapes.triangles, m.shapes.triangles, sizeof(Tri)*shapes.num_triangles);            }            else                shapes.triangles='\0';            shapes.num_normals=m.shapes.num_normals;            if (shapes.num_normals &gt; 0)            {                shapes.normals=new Normal[shapes.num_normals];                memcpy(shapes.normals, shapes.normals, sizeof(Normal)*shapes.num_normals);            }            else                shapes.normals='\0';        }    }    else    {        shapes='\0';        material_indices='\0';    }    num_materials = m.num_materials;    if (num_materials &gt; 0)    {        materials= new Material[num_materials];        for (size_t i=0; i&lt;num_materials; i++)        {            strcpy(materials.Name, m.materials.Name);            memcpy(materials.Ambient, m.materials.Ambient, 4*sizeof(float));            memcpy(materials.Diffuse, m.materials.Diffuse, 4*sizeof(float));            memcpy(materials.Specular, m.materials.Specular, 4*sizeof(float));            memcpy(materials.Emissive, m.materials.Emissive, 4*sizeof(float));            materials.Shininess=m.materials.Shininess;            materials.Transparency=m.materials.Transparency;            strcpy(materials.DiffuseTexture, m.materials.DiffuseTexture);            strcpy(materials.AlphaTexture, m.materials.AlphaTexture);            materials.texture=m.materials.texture;        }    }    else        materials = '\0';}const Model &Model::operator=(const Model &m){    if (&m != this)    {        if(shapes != NULL)        {            delete[] shapes;            shapes = NULL;        }        if(materials != NULL)        {            delete[] materials;            materials = NULL;        }        if(material_indices != NULL)        {            delete[] material_indices;            material_indices = NULL;        }        num_shapes = m.num_shapes;        if (num_shapes &gt; 0)        {            shapes = new Shapes[num_shapes]                material_indices=new int[num_shapes];            memcpy(material_indices, m.material_indices, sizeof(int)*num_shapes);            for (size_t i=0; i&lt;num_shapes; i++)            {                shapes.num_vertices=m.shapes.num_vertices;                if (shapes.num_vertices &gt; 0)                {                    shapes.vertices= new Vec[shapes.num_vertices];                    memcpy(shapes.vertices, m.shapes.vertices, sizeof(Vec)*shapes.num_vertices);                }                else                    shapes.vertices='\0';                shapes.num_triangles=m.shapes.num_triangles;                if (shapes.num_triangles &gt; 0)                {                    shapes.triangles=new Tri[shapes.num_triangles];                    memcpy(shapes.triangles, m.shapes.triangles, sizeof(Tri)*shapes.num_triangles);                }                else                    shapes.triangles='\0';                shapes.num_normals=m.shapes.num_normals;                if (shapes.num_normals &gt; 0)                {                    shapes.normals=new Normal[shapes.num_normals];                    memcpy(shapes.normals, m_shapes.normals, sizeof(Normal)*shapes.num_normals);                }                else                    shapes.normals='\0';            }        }        else        {            shapes='\0';            material_indices='\0';        }        num_materials = m.num_materials;        if (num_materials &gt; 0)        {            materials= new Material[num_materials];            for (size_t i=0; i&lt;num_materials; i++)            {                strcpy(materials.Name, m.materials.Name);                memcpy(materials.Ambient, m.materials.Ambient, 4*sizeof(float));                memcpy(materials.Diffuse, m.materials.Diffuse, 4*sizeof(float));                memcpy(materials.Specular, m.materials.Specular, 4*sizeof(float));                memcpy(materials.Emissive, m.materials.Emissive, 4*sizeof(float));                materials.Shininess=m.materials.Shininess;                materials.Transparency=m.materials.Transparency;                strcpy(materials.DiffuseTexture, m.materials.DiffuseTexture);                strcpy(materials.AlphaTexture, m.materials.AlphaTexture);                materials.texture=m.materials.texture;            }        }        else            materials = '\0';    }    return *this;}
Looks good, I'll try it tomorrow cause I have to go to sleep, school tomorrow.

Jake
well I tried out your suggestion, and it still doesn't work. Here's what it looks like now...

#include "jpeg.h"#include "ms3d_ascii.h" ///////////////////////////////////////////////////////////////////////////////////////////////////										The Shape Class/////////////////////////////////////////////////////////////////////////////////////////////////Shape::Shape(){	num_vertices = 0;	vertices = NULL;	num_triangles = 0;	triangles = NULL;	num_normals = 0;	normals = NULL;}Shape::~Shape(){	if(vertices != NULL)		delete[] vertices;		if(triangles != NULL)		delete[] triangles;	if(normals != NULL)		delete[] normals;}bool Shape::loadFromFile( const char *filename ){	FILE	*fp;	int	i;		fp = fopen(filename, "r");	if(fp == NULL)		return false;		fscanf(fp, "%d\n", &num_vertices );		vertices = new Vec[num_vertices];		for(i = 0 ; i < num_vertices; i++)	{		fscanf(fp, "%f %f %f %f %f\n", 			&vertices.x,			&vertices.y,			&vertices.z,			&vertices.u,			&vertices.v );	}		fscanf(fp, "%d\n", &num_triangles );		triangles = new Tri[num_triangles];	for(i = 0 ; i < num_triangles; i++)	{		fscanf(fp, "%d %d %d\n",			&triangles.v[0],			&triangles.v[1],			&triangles.v[2] );	}		fclose(fp);		return true;}bool Shape::saveToFile( const char *filename ){	FILE	*fp;	int	i;		fp = fopen(filename, "w");	if(fp == NULL)		return false;		fprintf(fp, "%d\n", num_vertices );		for(i = 0 ; i < num_vertices; i++)	{		fprintf(fp, "%f %f %f %f %f\n", 			vertices.x,			vertices.y,			vertices.z,			vertices.u,			vertices.v );	}		fprintf(fp, "%d\n", num_triangles );		for(i = 0 ; i < num_triangles; i++)	{		fprintf(fp, "%d %d %d\n",			triangles.v[0],			triangles.v[1],			triangles.v[2] );	}	fclose(fp);	return true;}void Shape::render( void ){	int	i,j;	Tri	*tri;	Vec	*vec;	Normal *N;		glBegin(GL_TRIANGLES);	for(i = 0; i < num_triangles; i++)				// for each triangle	{		tri = triangles + i;						// pointer to triangle				for(j = 0; j < 3; j++)						// 3 vertices of the triangle		{			N = normals + tri->n[j];			glNormal3f(N->x, N->y, N->z);			// set normal vector  (object space)						vec = vertices + tri->v[j];				// pointer to vertex			glTexCoord2f (vec->u, vec->v);			// texture coordinate						glVertex3f( vec->x, vec->y, vec->z );	// 3d coordinate (object space)		}	}	glEnd();}bool Shape::loadFromMs3dAsciiSegment( FILE *file ){    bool bError = false;    char szLine[256];    int nFlags, nIndex, j;			// vertices		if (!fgets (szLine, 256, file))	{		return false;	}		if (sscanf (szLine, "%d", &num_vertices) != 1)	{		return false;	}				vertices = new Vec[num_vertices];				                for (j = 0; j < num_vertices; j++)                {                    if (!fgets (szLine, 256, file))                    {						return false;					}                    if (sscanf (szLine, "%d %f %f %f %f %f %d",                        &nFlags,                        &vertices[j].x, &vertices[j].y, &vertices[j].z,                        &vertices[j].u, &vertices[j].v                        ) != 7)					{						return false;					}					// adjust the y direction of the texture coordinate					vertices[j].v = 1.0f - vertices[j].v;                }								                // normals				                if (!fgets (szLine, 256, file))                {					return false;                }				                if (sscanf (szLine, "%d", &num_normals) != 1)                {					return false;                }				normals = new Normal[num_normals];				                for (j = 0; j < num_normals; j++)                {                    if (!fgets (szLine, 256, file))                    {						return false;                    }					                    if (sscanf (szLine, "%f %f %f", 						&normals[j].x, &normals[j].y, &normals[j].z) != 3)                    {						return false;					}                }				                // triangles				                if (!fgets (szLine, 256, file))                {					return false;                }				                if (sscanf (szLine, "%d", &num_triangles) != 1)                {					return false;				}				triangles = new Tri[num_triangles];				                for (j = 0; j < num_triangles; j++)                {                    if (!fgets (szLine, 256, file))                    {						return false;                    }					                    if (sscanf (szLine, "%d %d %d %d %d %d %d %d",                        &nFlags,                        &triangles[j].v[0], &triangles[j].v[1], &triangles[j].v[2],                        &triangles[j].n[0], &triangles[j].n[1], &triangles[j].n[2],                        &nIndex                        ) != 8)                    {						return false;                    }					assert(triangles[j].v[0] >= 0);					assert(triangles[j].v[0] < num_vertices);					assert(triangles[j].v[1] >= 0);					assert(triangles[j].v[1] < num_vertices);					assert(triangles[j].v[2] >= 0);					assert(triangles[j].v[2] < num_vertices);				}								return true;}///////////////////////////////////////////////////////////////////////////////////////////////////										The Material Class/////////////////////////////////////////////////////////////////////////////////////////////////Material::Material()	{}Material::~Material()	{}void Material::activate( void ){	glMaterialfv( GL_FRONT, GL_AMBIENT, Ambient );	glMaterialfv( GL_FRONT, GL_DIFFUSE, Diffuse );	glMaterialfv( GL_FRONT, GL_SPECULAR, Specular );	glMaterialfv( GL_FRONT, GL_EMISSION, Emissive );	glMaterialf( GL_FRONT, GL_SHININESS, Shininess );		if ( texture > 0 )	{		glBindTexture( GL_TEXTURE_2D, texture );		glEnable( GL_TEXTURE_2D );	}	else		glDisable( GL_TEXTURE_2D );}bool Material::loadFromMs3dAsciiSegment( FILE *file ){    char szLine[256];	    // name    if (!fgets (szLine, 256, file))		return false;    if (sscanf (szLine, "\"%[^\"]\"", Name) != 1)		return false;		// ambient    if (!fgets (szLine, 256, file))		return false;		if (sscanf (szLine, "%f %f %f %f", &Ambient[0], &Ambient[1], &Ambient[2], &Ambient[3]) != 4)		return false;	    // diffuse    if (!fgets (szLine, 256, file))		return false;    if (sscanf (szLine, "%f %f %f %f", &Diffuse[0], &Diffuse[1], &Diffuse[2], &Diffuse[3]) != 4)		return false;	    // specular    if (!fgets (szLine, 256, file))		return false;    if (sscanf (szLine, "%f %f %f %f", &Specular[0], &Specular[1], &Specular[2], &Specular[3]) != 4)		return false;	    // emissive    if (!fgets (szLine, 256, file))		return false;    if (sscanf (szLine, "%f %f %f %f", &Emissive[0], &Emissive[1], &Emissive[2], &Emissive[3]) != 4)		return false;	    // shininess    if (!fgets (szLine, 256, file))		return false;    if (sscanf (szLine, "%f", &Shininess) != 1)		return false;	    // transparency    if (!fgets (szLine, 256, file))		return false;    if (sscanf (szLine, "%f", &Transparency) != 1)		return false;	    // diffuse texture    if (!fgets (szLine, 256, file))		return false;	strcpy(DiffuseTexture, "");    sscanf (szLine, "\"%[^\"]\"", DiffuseTexture);	    // alpha texture    if (!fgets (szLine, 256, file))		return false;	strcpy(AlphaTexture, "");    sscanf (szLine, "\"%[^\"]\"", AlphaTexture);		reloadTexture();		return true;}void Material::reloadTexture( void ){	if( strlen(DiffuseTexture) > 0 )	{					JPEG_Texture(&texture,DiffuseTexture,0);	}	else	texture = 0;}///////////////////////////////////////////////////////////////////////////////////////////////////										The Model Class/////////////////////////////////////////////////////////////////////////////////////////////////Model::Model(){	num_shapes = 0;	shapes = NULL;	num_materials = 0;	materials = NULL;}Model::~Model(){		if(shapes != NULL)	{		delete[] shapes;		shapes = NULL;	}	if(materials != NULL)	{		delete[] materials;		materials = NULL;	}	if(material_indices != NULL)	{		delete[] material_indices;		material_indices = NULL;	}}bool Model::loadFromMs3dAsciiFile( const char *filename ){    bool	bError = false;    char	szLine[256];    int		nFlags, nIndex, i;		FILE *file = fopen (filename, "rt");	if (!file)		return false;	    while (fgets (szLine, 256, file) != NULL  && !bError)    {        if (!strncmp (szLine, "//", 2))            continue;		        if (sscanf (szLine, "Meshes: %d", &num_shapes) == 1)        {			char	szName[MS_MAX_NAME];						shapes = new Shape[num_shapes];			material_indices = new int[num_shapes];			            for (i = 0; i < num_shapes && !bError; i++)            {				                if (!fgets (szLine, 256, file))                {                    bError = true;                    break;                }				                // mesh: name, flags, material index                if (sscanf (szLine, "\"%[^\"]\" %d %d",szName, &nFlags, &nIndex) != 3)                {                    bError = true;                    break;                }				material_indices = nIndex;								if( ! shapes.loadFromMs3dAsciiSegment(file) )                {                    bError = true;                    break;                }			}            continue;		}				        // materials		        if (sscanf (szLine, "Materials: %d", &num_materials) == 1)        {            int i;						materials = new Material[num_materials];			            for (i = 0; i < num_materials && !bError; i++)            {				if( ! materials.loadFromMs3dAsciiSegment(file) )                {                    bError = true;                    break;                }			}            continue;        }		    }		fclose (file);			return true;}void Model::reloadTextures( void ){	int	i;		for(i = 0; i < num_materials; i++)	// for each shape	{		materials.reloadTexture();	}}#if 0void Model::render( void ){	int	i;		for(i = 0; i < num_shapes; i++)	// for each shape	{		int materialIndex = material_indices;		if ( materialIndex >= 0 )		{			materials[materialIndex].activate();		}		else		{			glDisable( GL_TEXTURE_2D );		}		shapes.render();	}}#endifvoid Model::render( void ){	int	k;	int	i, j;	Tri	*tri;	Vec	*vec;	Normal *N;		for(k = 0; k < num_shapes; k++)	// for each shape	{		int materialIndex = material_indices[k];		if ( materialIndex >= 0 )		{			materials[materialIndex].activate();		}		else		{			// Material properties?			glDisable( GL_TEXTURE_2D );		}				glBegin(GL_TRIANGLES);		for(i = 0; i < shapes[k].num_triangles; i++)	// for each triangle		{			tri = shapes[k].triangles + i;				// pointer to triangle						for(j = 0; j < 3; j++)						// 3 vertices of the triangle			{				N = shapes[k].normals + tri->n[j];				glNormal3f(N->x, N->y, N->z);			// set normal vector  (object space)								vec = shapes[k].vertices + tri->v[j];	// pointer to vertex				glTexCoord2f (vec->u, vec->v);			// texture coordinate								glVertex3f( vec->x , vec->y, vec->z);								}					}		glEnd();	}}cModel :: cModel(){}cModel :: ~cModel(){	model.clear();}Model::Model(const Model &m){    num_shapes = m.num_shapes;    if (num_shapes > 0)    {        shapes = new Shape[num_shapes];            material_indices=new int[num_shapes];        memcpy(material_indices, m.material_indices, sizeof(int)*num_shapes);        for (size_t i=0; i<num_shapes; i++)        {            shapes.num_vertices=m.shapes.num_vertices;            if (shapes.num_vertices > 0)            {                shapes.vertices= new Vec[shapes.num_vertices];                memcpy(shapes.vertices, m.shapes.vertices, sizeof(Vec)*shapes.num_vertices);            }            else                shapes.vertices='\0';            shapes.num_triangles=m.shapes.num_triangles;            if (shapes.num_triangles > 0)            {                shapes.triangles=new Tri[shapes.num_triangles];                memcpy(shapes.triangles, m.shapes.triangles, sizeof(Tri)*shapes.num_triangles);            }            else                shapes.triangles='\0';            shapes.num_normals=m.shapes.num_normals;            if (shapes.num_normals > 0)            {                shapes.normals=new Normal[shapes.num_normals];                memcpy(shapes.normals, shapes.normals, sizeof(Normal)*shapes.num_normals);            }            else                shapes.normals='\0';        }    }    else    {        shapes='\0';        material_indices='\0';    }    num_materials = m.num_materials;    if (num_materials > 0)    {        materials= new Material[num_materials];        for (size_t i=0; i<num_materials; i++)        {            strcpy(materials.Name, m.materials.Name);            memcpy(materials.Ambient, m.materials.Ambient, 4*sizeof(float));            memcpy(materials.Diffuse, m.materials.Diffuse, 4*sizeof(float));            memcpy(materials.Specular, m.materials.Specular, 4*sizeof(float));            memcpy(materials.Emissive, m.materials.Emissive, 4*sizeof(float));            materials.Shininess=m.materials.Shininess;            materials.Transparency=m.materials.Transparency;            strcpy(materials.DiffuseTexture, m.materials.DiffuseTexture);            strcpy(materials.AlphaTexture, m.materials.AlphaTexture);            materials.texture=m.materials.texture;        }    }    else        materials = '\0';}const Model &Model::operator=(const Model &m){    if (&m != this)    {        if(shapes != NULL)        {            delete[] shapes;            shapes = NULL;        }        if(materials != NULL)        {            delete[] materials;            materials = NULL;        }        if(material_indices != NULL)        {            delete[] material_indices;            material_indices = NULL;        }        num_shapes = m.num_shapes;        if (num_shapes > 0)        {            shapes = new Shape[num_shapes];                material_indices=new int[num_shapes];            memcpy(material_indices, m.material_indices, sizeof(int)*num_shapes);            for (size_t i=0; i<num_shapes; i++)            {                shapes.num_vertices=m.shapes.num_vertices;                if (shapes.num_vertices > 0)                {                    shapes.vertices= new Vec[shapes.num_vertices];                    memcpy(shapes.vertices, m.shapes.vertices, sizeof(Vec)*shapes.num_vertices);                }                else                    shapes.vertices='\0';                shapes.num_triangles=m.shapes.num_triangles;                if (shapes.num_triangles > 0)                {                    shapes.triangles=new Tri[shapes.num_triangles];                    memcpy(shapes.triangles, m.shapes.triangles, sizeof(Tri)*shapes.num_triangles);                }                else                    shapes.triangles='\0';                shapes.num_normals=m.shapes.num_normals;                if (shapes.num_normals > 0)                {                    shapes.normals=new Normal[shapes.num_normals];                    memcpy(shapes.normals, shapes.normals, sizeof(Normal)*shapes.num_normals);                }                else                    shapes.normals='\0';            }        }        else        {            shapes='\0';            material_indices='\0';        }        num_materials = m.num_materials;        if (num_materials > 0)        {            materials= new Material[num_materials];            for (size_t i=0; i<num_materials; i++)            {                strcpy(materials.Name, m.materials.Name);                memcpy(materials.Ambient, m.materials.Ambient, 4*sizeof(float));                memcpy(materials.Diffuse, m.materials.Diffuse, 4*sizeof(float));                memcpy(materials.Specular, m.materials.Specular, 4*sizeof(float));                memcpy(materials.Emissive, m.materials.Emissive, 4*sizeof(float));                materials.Shininess=m.materials.Shininess;                materials.Transparency=m.materials.Transparency;                strcpy(materials.DiffuseTexture, m.materials.DiffuseTexture);                strcpy(materials.AlphaTexture, m.materials.AlphaTexture);                materials.texture=m.materials.texture;            }        }        else            materials = '\0';    }    return *this;}bool cModel :: LoadModel(std::string Name){	//sModel tmpModel;	//model.push_back(tmpModel);	//ModelCount += 1;	if (!model[ModelCount - 1].obj.loadFromMs3dAsciiFile(Name.c_str()))	{		return FALSE;	}	model[ModelCount - 1].Name = Name;	model[ModelCount - 1].objList = glGenLists(1);	glNewList(model[ModelCount - 1].objList,GL_COMPILE);		model[ModelCount - 1].obj.render();	glEndList();	return TRUE;}void cModel :: Render(std::string Name){	for (int i = 0; i < ModelCount; i++)	{		if (model.Name == Name)		{			glCallList(model.objList);		}	}}


Jake

This topic is closed to new replies.

Advertisement