📄 triangle.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 + -