📄 loadobj.cpp
字号:
// LoadOBJ.cpp: implementation of the CLoadOBJ class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MyExplosion.h"
#include "LoadOBJ.h"
#include <math.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
const float pi = 3.1415926;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
static char *NormalizeString(char *s)
{
while (*s == ' ') s++;
ULONG l = strlen(s);
for (ULONG i=(l-1); i>0; i--)
if (s[i] < 33) s[i] = 0;
else break;
return s;
}
static void ParseFloat(char *s, float *a, float *b, float *c)
{
int i, j;
int x, y, z;
s = NormalizeString(s);
x = 0; y = -1; z = -1;
j = (int)strlen(s);
for (i=0; i<j; i++)
{
if ((s[i] == ' ') || (s[i] == '\n'))
{
s[i] = 0;
if (y == -1) y = i+1;
else
if (z == -1) z = i+1;
}
}
*a = (float)atof(&s[x]);
*b = (float)atof(&s[y]);
*c = (float)atof(&s[z]);
}
static int Parse3(char *s, int *a, int *b, int *c)
{
int i, j;
char *sp;
int stage=0;
j = (int)strlen(s);
sp = s;
for (i=0; i<j; i++)
{
if ((s[i] == '/') || (i == j-1))
{
if (i != j-1) s[i] = 0;
switch (stage)
{
case 0: *a = atoi(sp); break;
case 1: *b = atoi(sp); break;
case 2: *c = atoi(sp); break;
}
stage++;
sp = &s[i+1];
}
}
return stage;
}
static int ParseFace(char *s, int *a, int *ta, int *na, int *b, int *tb, int *nb, int *c, int *tc, int *nc)
{
int i, j, stage=0, total;
char *sp;
s = NormalizeString(s);
j = (int)strlen(s);
sp = s;
for (i=0; i<j; i++)
{
if ((s[i] == ' ') || (i == j-1))
{
if (i != j-1) s[i] = 0;
switch (stage)
{
case 0: total = Parse3(sp, a, ta, na); break;
case 1: total = Parse3(sp, b, tb, nb); break;
case 2: total = Parse3(sp, c, tc, nc); break;
}
stage++;
sp = &s[i+1];
}
}
return total;
}
CTexture::CTexture()
{
cur_texture = 0;
}
CTexture::~CTexture()
{
// 删除所有纹理
if (cur_texture > 0) glDeleteTextures(cur_texture, &textures[0]);
}
void CTexture::Init()
{
glGenTextures(MAX_TEXTURES, textures);
}
GLuint CTexture::AddNewTexture(char *lpszName)
{
unsigned *teximage;
int texwid, texht;
int texcomps;
teximage = m_Texture->read_texture(lpszName, &texwid, &texht, &texcomps);
if (!teximage) return -1;
glBindTexture(GL_TEXTURE_2D, textures[cur_texture]);
cur_texture++;
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, 3, texwid, texht, 0, GL_RGBA, GL_UNSIGNED_BYTE, teximage);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, texwid, texht, GL_RGBA, GL_UNSIGNED_BYTE, teximage);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
free(teximage);
return textures[cur_texture-1];
}
CLoadOBJ::CLoadOBJ()
{
m_lpMtlName = NULL;
Materials = NULL;
tb = NULL;
tx = NULL;
ty = NULL;
vx = NULL;
vy = NULL;
vz = NULL;
vnx = NULL;
vny = NULL;
vnz = NULL;
m_vtotal = 0;
m_vttotal = 0;
m_vntotal = 0;
Explosion_Flag = 0;
srand((unsigned int)time(NULL));
e_tb = NULL;
}
CLoadOBJ::~CLoadOBJ()
{
STriangle *cur_s, *temp_s;
STriangleFull *cur_f, *temp_f;
STriangleBlock *temp;
STriangleBlockFull *temp1;
delete [] m_lpMtlName;
if (vx) delete [] vx;
if (vy) delete [] vy;
if (vz) delete [] vz;
if (vnx) delete [] vnx;
if (vny) delete [] vny;
if (vnz) delete [] vnz;
if (tx) delete [] tx;
if (ty) delete [] ty;
while (tb)
{
temp = tb->next;
cur_s = tb->tr;
while (cur_s)
{
temp_s = cur_s->next;
delete cur_s;
cur_s = temp_s;
}
delete tb;
tb = temp;
}
while (e_tb)
{
temp1 = e_tb->next;
cur_f = e_tb->tr;
while (cur_f)
{
temp_f = cur_f->next;
delete cur_f;
cur_f = temp_f;
}
delete e_tb;
e_tb = temp1;
}
}
// 获得Mtl文件
int CLoadOBJ::GetMtlName(FILE *f)
{
char buffer[512];
char *str;
while (!feof(f))
{
fgets(buffer, 512, f);
str = NormalizeString(buffer);
// 分析字符串
if (str[0] == '#') continue;
for (ULONG i=0; i<strlen(str); i++)
{
if (str[i] == ' ')
{
str[i] = 0;
if (!strcmp(str, "mtllib"))
{
// 删除老的Mtl名称
if (m_lpMtlName) delete [] m_lpMtlName;
m_lpMtlName = new char [MAX_FILE_NAME];
strcpy(m_lpMtlName, &str[i+1]);
return 0;
} else break;
}
else continue;
}
}
return -1; // 没有找到Mtl文件
}
int CLoadOBJ::LoadObjFile(FILE *f)
{
struct vertx
{
float x, y, z;
struct vertx *next;
};
struct tcoord
{
float x, y;
struct tcoord *next;
};
struct vertx *vrt=NULL, *vrt_cur, *vrt_temp;
struct vertx *nrm=NULL, *nrm_cur, *nrm_temp;
struct tcoord *tc=NULL, *tc_cur, *tc_temp;
char buffer[512];
char *str;
float zzz;
ULONG i;
struct STriangleBlock *tb_cur, *tb_temp;
struct STriangle *tr_cur, *tr_temp;
int pa, pb, pc, pat, pbt, pct, pan, pbn, pcn, total;
m_vtotal = 0;
m_vttotal = 0;
while (!feof(f))
{
fgets(buffer, 512, f);
str = NormalizeString(buffer);
if (str[0] == '#' || str[0] == 'g' || str[0] == 0) continue;
for (i=0; i<strlen(str); i++)
{
if (str[i] == ' ')
{
str[i] = 0;
if (!strcmp(str, "v")) // 顶点坐标
{
if (!vrt)
{
vrt = new vertx;
vrt_cur = vrt;
}
else
{
vrt_temp = new vertx;
vrt_cur->next = vrt_temp;
vrt_cur = vrt_temp;
}
vrt_cur->next = NULL;
ParseFloat(&str[i+1], &vrt_cur->x, &vrt_cur->y, &vrt_cur->z);
m_vtotal++;
break;
}
else
if (!strcmp(str, "vt")) // 纹理坐标
{
if (!tc)
{
tc = new tcoord;
tc_cur = tc;
}
else
{
tc_temp = new tcoord;
tc_cur->next = tc_temp;
tc_cur = tc_temp;
}
tc_cur->next = NULL;
ParseFloat(&str[i+1], &tc_cur->x, &tc_cur->y, &zzz);
m_vttotal++;
break;
}
else
if (!strcmp(str, "vn")) // 法向坐标
{
if (!nrm)
{
nrm = new vertx;
nrm_cur = nrm;
}
else
{
nrm_temp = new vertx;
nrm_cur->next = nrm_temp;
nrm_cur = nrm_temp;
}
nrm_cur->next = NULL;
ParseFloat(&str[i+1], &nrm_cur->x, &nrm_cur->y, &nrm_cur->z);
m_vntotal++;
break;
}
else
if (!strcmp(str, "usemtl"))
{
if (!tb)
{
tb = new STriangleBlock;
tb_cur = tb;
} else
{
tb_temp = new STriangleBlock;
tb_cur->next = tb_temp;
tb_cur = tb_temp;
}
tb_cur->next = NULL;
tb_cur->mat = GetMaterialByName(&str[i+1]);
tb_cur->tr = NULL;
break;
}
else
if (!strcmp(str, "f"))
{
total = ParseFace(&str[i+1], &pa, &pat, &pan, &pb, &pbt, &pbn, &pc, &pct, &pcn);
if (!tb_cur->tr)
{
tb_cur->tr = new STriangle;
tr_cur = tb_cur->tr;
}
else
{
tr_temp = new STriangle;
tr_cur->next = tr_temp;
tr_cur = tr_temp;
}
tr_cur->next = NULL;
if (total > 0)
{
tr_cur->a = pa;
tr_cur->b = pb;
tr_cur->c = pc;
}
if (total > 1)
{
tr_cur->ta = pat;
tr_cur->tb = pbt;
tr_cur->tc = pct;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -