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

📄 loadobj.cpp

📁 用VC++与OPENGL研发的粒子系统的模拟程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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 + -