⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 triangle.cpp

📁 基于引擎基础上开发的三维游戏实例“恐怖之战”游戏者可以自爱三维地形上漫游
💻 CPP
字号:
// Triangle.cpp: implementation of the CTriangle class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "MyGame.h"
#include "Triangle.h"
#include <map>


#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CTriangle::CTriangle()
{

}

CTriangle::~CTriangle()
{

}

CTriangle::CTriangle(Point3f const &v0,Point3f const &v1,Point3f const &v2)
{
	v[0].v=v0;v[1].v=v1;v[2].v=v2;
	CalcNormal();
}

void CTriangle::CalcNormal()
{
	v[0].n=(v[1].v-v[0].v)^(v[2].v-v[0].v);
	v[0].n.Normalize();
	v[1].n=v[0].n;
	v[2].n=v[0].n;
}

void CTriangle::Flip()
{
	Vertex tmp;
	tmp=v[0];
	v[0]=v[1];
	v[1]=tmp;
	CalcNormal();
}

CMesh::CMesh()
{
	has_texture=false;has_color=false;dl=0;ti=0;
}

CMesh::~CMesh()
{
	if(dl) glDeleteLists(dl,1);
}

int CMesh::Draw()
{
	if(ti)
	{
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, ti);
		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	}
	glColor3f(1, 1, 1);
	vector<CTriangle>::iterator i;
	glEnable(GL_LIGHTING);
	glBegin(GL_TRIANGLES);
	for(i=T.begin();i!=T.end();++i)
		for(int j=0;j<3;++j)
			{
				if(has_color) glColor3fv((*i).v[j].c.v);
				if(has_texture) glTexCoord2fv((*i).v[j].t.v);
				glNormal((*i).v[j].n);
				glVertex((*i).v[j].v);
			}
		
	glEnd();
	glDisable(GL_TEXTURE_2D);
	return T.size();
}

int CMesh::DrawDL()
{
	if(dl==0) GenerateDL();
	glCallList(dl);
	return T.size();
}

void CMesh::GenerateDL()
{
	if(dl!=0) glDeleteLists(dl,1);
	dl=glGenLists(1);
	glNewList(dl,GL_COMPILE);
	Draw();
	glEndList();
}

int CMesh::DrawA()
{
	if(has_color)
	{
		glEnableClientState (GL_VERTEX_ARRAY);
		glEnableClientState (GL_COLOR_ARRAY);
		glEnableClientState (GL_NORMAL_ARRAY);
		glVertexPointer(3,GL_FLOAT,sizeof(Point3f)*3,T.begin());
		glNormalPointer(GL_FLOAT,sizeof(Point3f)*3,T.begin()+sizeof(Point3f));
		glColorPointer(3,GL_FLOAT,sizeof(Point3f)*3,T.begin()+sizeof(Point3f)*2);
		glDrawArrays(GL_TRIANGLES,0,T.size());
		glDisableClientState (GL_VERTEX_ARRAY);
		glDisableClientState (GL_COLOR_ARRAY);
		glDisableClientState (GL_NORMAL_ARRAY);
	}
	else
	{
		glEnableClientState (GL_VERTEX_ARRAY);
		glEnableClientState (GL_NORMAL_ARRAY);
		glVertexPointer(3,GL_FLOAT,sizeof(Point3f)*3,&(T[0].v[0].v.v[0]));
		glNormalPointer(  GL_FLOAT,sizeof(Point3f)*3,&(T[0].v[0].n.v[0]));
		glDrawArrays(GL_TRIANGLES,0,T.size()*3);
		glDisableClientState (GL_VERTEX_ARRAY);
		glDisableClientState (GL_NORMAL_ARRAY);
	}
	return T.size();
}
void CMesh::SetTexture(GLuint TextInd)
{
	assert(TextInd);
	ti=TextInd;
	has_texture=true;
}

void CMesh::SetTexture(char *filename)
{ 
	pngInfo info;
	glGenTextures(1, &ti);
	glBindTexture(GL_TEXTURE_2D, ti);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

	if (!pngLoad(filename, PNG_NOMIPMAP, PNG_SOLID, &info)) 
	{
		puts("Can't load file");
		exit(1);
	}
	has_texture=true;
}

void CMesh::Open(char *filename)
{
	if(strcmp(filename+strlen(filename)-4,"rawc")==0 ||
		 strcmp(filename+strlen(filename)-4,"RAWC")==0 )
	{
		 OpenColor(filename);
		 return ;
	}
	FILE *fp;
	fp=fopen(filename,"r");
	if(fp==0)	
	{
		printf("Unable to open %s",filename);
		exit(-1);
	}

	has_color=false;
	CTriangle tt;
	T.clear();
	float xf,yf,zf;
	int nc;
	while(1)
	{
		nc=fscanf(fp,"%f %f %f",&xf,&yf,&zf);
		if(nc!=3) break;
		tt.v[0].v=Point3f(xf,yf,zf);
		nc=fscanf(fp,"%f %f %f",&xf,&yf,&zf);
		if(nc!=3) break;
		tt.v[1].v=Point3f(xf,yf,zf);
		nc=fscanf(fp,"%f %f %f",&xf,&yf,&zf);
		if(nc!=3) break;
		tt.v[2].v=Point3f(xf,yf,zf);
		tt.CalcNormal();
		T.push_back(tt);
	}
	fclose(fp);
	printf("Read %i triangles\n",T.size());
}

void CMesh::OpenColor(char *filename)
{
	FILE *fp;
	fp=fopen(filename,"r");
	if(fp==0)		
	{
		printf("Unable to open %s",filename);
		exit(-1);
	}
	has_color=true;
	CTriangle tt;
	T.clear();
	float xf,yf,zf;
	float cr,cg,cb;
	int nc;
	while(1)
	{
		nc= fscanf(fp,"%f %f %f",&xf,&yf,&zf);
		tt.v[0].v=Point3f(xf,yf,zf);
		nc+= fscanf(fp,"%f %f %f",&xf,&yf,&zf);
		tt.v[1].v=Point3f(xf,yf,zf);
		nc+= fscanf(fp,"%f %f %f",&xf,&yf,&zf);
		tt.v[2].v=Point3f(xf,yf,zf);
		nc+=fscanf(fp,"%f %f %f",&cr,&cg,&cb);
		tt.v[0].c=Point3f(cr,cg,cb);
		nc+=fscanf(fp,"%f %f %f",&cr,&cg,&cb);
		tt.v[1].c=Point3f(cr,cg,cb);
		nc+=fscanf(fp,"%f %f %f",&cr,&cg,&cb);
		tt.v[2].c=Point3f(cr,cg,cb);
		tt.CalcNormal();
		if(nc!=18) break;
		T.push_back(tt);
	}
	fclose(fp);
	printf("Read %i triangles\n",T.size());

}

void CMesh::Smooth()
{
	map<Point3f,Point3f> NN;  // the vertex to normal map
	vector<CTriangle>::iterator i;
	int j;
	// clear and create all the map entry
	for(i=T.begin();i!=T.end();++i)
		for(j=0;j<3;++j)
			NN[(*i).v[j].v]=Point3f(0,0,0);
			
	// accumulate normals per vertex 
	for(i=T.begin();i!=T.end();++i)
		for(j=0;j<3;++j)
			NN[(*i).v[j].v]+=(*i).v[j].n;
		
	// Normalize all the normals stored in the map
	map<Point3f,Point3f>::iterator in;
	for(in=NN.begin();in!=NN.end();++in)
			(*in).second.Normalize();
	
	// Distribute results into triangles
	for(i=T.begin();i!=T.end();++i)
		for(j=0;j<3;++j)
			(*i).v[j].n=NN[(*i).v[j].v];
}



void CMesh::Flip()
{
 	vector<CTriangle>::iterator i;
	// clear and create all the map entry
	for(i=T.begin();i!=T.end();++i)
		(*i).Flip();
}
void CMesh::Normalize(float size)
{
	assert(T.size()>0);
	Point3f min=T[0].v[0].v,max=T[0].v[0].v;

	int j;
	vector<CTriangle>::iterator i;
	for(i=T.begin();i!=T.end();++i){
		for(j=0;j<3;++j)
		{
			if(min.v[0] > (*i).v[j].v[0]) min.v[0] = (*i).v[j].v[0];
			if(min.v[1] > (*i).v[j].v[1]) min.v[1] = (*i).v[j].v[1];
			if(min.v[2] > (*i).v[j].v[2]) min.v[2] = (*i).v[j].v[2];
	
			if(max.v[0] < (*i).v[j].v[0]) max.v[0] = (*i).v[j].v[0];
			if(max.v[1] < (*i).v[j].v[1]) max.v[1] = (*i).v[j].v[1];
			if(max.v[2] < (*i).v[j].v[2]) max.v[2] = (*i).v[j].v[2];
		}
	}

	Point3f d=max-min;
	float maxd=d.x();
	if(maxd<d.y()) maxd=d.y();
	if(maxd<d.z()) maxd=d.z();
	Point3f c=(min+max)/2;
	for(i=T.begin();i!=T.end();++i)
		for(j=0;j<3;++j)
		{
			(*i).v[j].v-=c;
			(*i).v[j].v/=maxd;
		}
}

void CMesh::SetMapMode(mapmode m)
{
	vector<CTriangle>::iterator i;
	int j;
	Point3f tp(.5,.5,0);
	if(m==PLANAR)
		for(i=T.begin();i!=T.end();++i)
			for(j=0;j<3;++j)
				(*i).v[j].t=(*i).v[j].v+tp;
	if(m==CYLINDRICAL)
		for(i=T.begin();i!=T.end();++i)
			for(j=0;j<3;++j)
			{
				(*i).v[j].t[0]=(1+atan2((*i).v[j].v[1],(*i).v[j].v[0])/M_PI)/2;
				(*i).v[j].t[1]=(*i).v[j].v[2]+.5;
			}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -