Jump to content
  • Advertisement
Sign in to follow this  
jake_Ghost

Problem with vector.push_back()

This topic is 4811 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
Here's an example of a copy constructor.


class Foo
{
public:
Foo(const Foo &oldFoo)
{
i = oldFoo.i;
}

private:
int i;
};

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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;
}

Share this post


Link to post
Share on other sites
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 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()
{
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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!