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

📄 loadobj.cpp

📁 用VC++与OPENGL研发的粒子系统的模拟程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
					if (total > 2)
					{
						tr_cur->na = pan;
						tr_cur->nb = pbn;
						tr_cur->nc = pcn;
					}
					break;
				}
			}
			else continue;
		}
	}
	// 为顶点序列分配存储空间
	vx = new float [m_vtotal];
	vy = new float [m_vtotal];
	vz = new float [m_vtotal];
	// 为法向量分配存储空间
	vnx = new float [m_vntotal];
	vny = new float [m_vntotal];
	vnz = new float [m_vntotal];
	// 为纹理坐标序列分配存储空间
	tx = new float [m_vttotal];
	ty = new float [m_vttotal];
	i = 0;
	// 保存并删除顶点序列
	vrt_cur = vrt;
	while (vrt_cur)
	{
		vx[i] = vrt_cur->x;
		vy[i] = vrt_cur->y;
		vz[i] = vrt_cur->z;
		i++;

		vrt_temp = vrt_cur->next;
		delete vrt_cur;
		vrt_cur = vrt_temp;
	}

	i = 0;
	// 保存和删除方向量序列
	nrm_cur = nrm;
	while (nrm_cur)
	{
		vnx[i] = nrm_cur->x;
		vny[i] = nrm_cur->y;
		vnz[i] = nrm_cur->z;
		i++;

		nrm_temp = nrm_cur->next;
		delete nrm_cur;
		nrm_cur = nrm_temp;
	}
	// 保存和删除纹理坐标序列
	i = 0;
	tc_cur = tc;
	while (tc_cur)
	{
		tx[i] = tc_cur->x;
		ty[i] = tc_cur->y;
		i++;

		tc_temp = tc_cur->next;
		delete tc_cur;
		tc_cur = tc_temp;
	}
	return -1;
}

int CLoadOBJ::LoadMtlFile(FILE *f, CTexture *tex_obj)
{
	char buffer[512];
	char *str;
	char *name;
	struct SMat *cur_mat = NULL;
	struct SMat *temp_mat = NULL;

	while (!feof(f))
	{
		fgets(buffer, 512, f);
		str = NormalizeString(buffer);

		for (ULONG i=0; i<strlen(str); i++)
		{
			if (str[i] == ' ')
			{
				str[i] = 0;
				if (!strcmp(str, "newmtl"))
				{
					name = &str[i+1];
					// 添加新的材质
					if (!Materials)
					{
						Materials = new SMat;
						cur_mat = Materials;
					}
					else
					{
						temp_mat = new SMat;
						cur_mat->next = temp_mat;
						cur_mat = temp_mat;
					}
					cur_mat->next = NULL;

					cur_mat->MatName = new char [strlen(name)+1];
					strcpy(cur_mat->MatName, name);
					cur_mat->texture = -1;
				} else
				if (!strcmp(str, "map_Kd")) 
				{
					cur_mat->texture = tex_obj->AddNewTexture(&str[i+1]); // Load this texture from file
					if (cur_mat->texture == -1) return -1;
				}
				else 
				if (!strcmp(str, "Ka"))
				{
					ParseFloat(&str[i+1], &cur_mat->ar, &cur_mat->ag, &cur_mat->ab);
				}
				else 
				if (!strcmp(str, "Kd"))
				{
					ParseFloat(&str[i+1], &cur_mat->dr, &cur_mat->dg, &cur_mat->db);
				}
				else 
				if (!strcmp(str, "Ks"))
				{
					ParseFloat(&str[i+1], &cur_mat->sr, &cur_mat->sg, &cur_mat->sb);
				}
				else break;
			}
			else continue;
		}
	}
	return -1;
}


int CLoadOBJ::LoadFromFile(char *lpszName, CTexture *tex_obj)
{
	FILE *f, *fmtl;
	f = fopen(lpszName, "rb");

	m_lpMtlName = new char[strlen(lpszName)+1];
	strcpy(m_lpMtlName, lpszName);
	m_lpMtlName[strlen(m_lpMtlName)-1] = 'l';
	m_lpMtlName[strlen(m_lpMtlName)-2] = 't';
	m_lpMtlName[strlen(m_lpMtlName)-3] = 'm';
	fmtl = fopen(m_lpMtlName, "rb");
	LoadMtlFile(fmtl, tex_obj);
	LoadObjFile(f);
	fclose(fmtl);
	fclose(f);

	return 0;
}

SMat *CLoadOBJ::GetMaterialByName(char *lpszName)
{
	SMat *temp;

	temp = Materials;
	while (temp)
	{
		if (!strcmp(temp->MatName, lpszName)) return temp;
		temp = temp->next;
	}
	return NULL;
}


static void setMaterial(float ambr, float ambg, float ambb,
                 float difr, float difg, float difb,
                 float specr, float specg, float specb,
                 float shine)
{
	float mat[4];

	mat[0] = ambr; mat[1] = ambg; mat[2] = ambb; mat[3] = 1.0;
	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat);
	mat[0] = difr; mat[1] = difg; mat[2] = difb; mat[3] = 1.0;
	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat);
	mat[0] = specr; mat[1] = specg; mat[2] = specb; mat[3] = 1.0;
	glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat);
	glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shine*128.0f);
}

void CLoadOBJ::Explosion()
{
	STriangleBlockFull *temp_e, *e_tb_cur;
	STriangleFull *temp_f, *cur_f;
	// 删除老的爆炸信息
	while (e_tb)
	{
		temp_e = 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 = temp_e;
	}

	e_tb = NULL;
	Explosion_Flag = 1;
	STriangleBlock *temp;
	STriangle *temp1;
	// 生成新的爆炸信息
	temp = tb;
	while (temp)
	{
		if (e_tb == NULL)
		{
			e_tb = new STriangleBlockFull;
			e_tb_cur = e_tb;
		}
		else
		{
			temp_e = new STriangleBlockFull;
			e_tb_cur->next = temp_e;
			e_tb_cur = temp_e;
		}
		e_tb_cur->next = NULL;
		e_tb_cur->tr = NULL;

		temp1 = temp->tr;
		while (temp1)
		{
			if (e_tb_cur->tr == NULL)
			{
				e_tb_cur->tr = new STriangleFull;
				cur_f = e_tb_cur->tr;
			}
			else
			{
				temp_f = new STriangleFull;
				cur_f->next = temp_f;
				cur_f = temp_f;
			}

			cur_f->next = NULL;
			
			cur_f->x1 = vx[temp1->a-1];
			cur_f->y1 = vy[temp1->a-1];
			cur_f->z1 = vz[temp1->a-1];
			
			cur_f->x2 = vx[temp1->b-1];
			cur_f->y2 = vy[temp1->b-1];
			cur_f->z2 = vz[temp1->b-1];

			cur_f->x3 = vx[temp1->c-1];
			cur_f->y3 = vy[temp1->c-1];
			cur_f->z3 = vz[temp1->c-1];
			float alpha, theta;
			float coef;
			alpha = ((float)(rand() % 360)*pi)/180;
			theta = ((float)(rand() % 360)*pi)/180;
			coef = (float)(rand() % 100)/100;
			cur_f->ofs_x = coef*cos(alpha)*cos(theta);
			cur_f->ofs_y = coef*sin(alpha)*cos(theta);
			cur_f->ofs_z = coef*sin(theta);
			cur_f->delete_coef = (rand() % 40);
			temp1 = temp1->next;
		}
		temp = temp->next;		
	}
}

void CLoadOBJ::Explosion_Step(float coef)
{
	STriangleBlock *temp;
	STriangle *temp1;
	STriangleBlockFull *temp_e;
	STriangleFull *temp1_e;
	temp = tb;
	temp_e = e_tb;
	while (temp)
	{
		temp1 = temp->tr;
		temp1_e = temp_e->tr;
		while (temp1)
		{
			temp1_e->x1 += temp1_e->ofs_x*coef;
			temp1_e->x2 += temp1_e->ofs_x*coef;
			temp1_e->x3 += temp1_e->ofs_x*coef;

			temp1_e->y1 += temp1_e->ofs_y*coef;
			temp1_e->y2 += temp1_e->ofs_y*coef;
			temp1_e->y3 += temp1_e->ofs_y*coef;

			temp1_e->z1 += temp1_e->ofs_z*coef;
			temp1_e->z2 += temp1_e->ofs_z*coef;
			temp1_e->z3 += temp1_e->ofs_z*coef;
			
			temp1_e->delete_coef--;

			temp1 = temp1->next;
			temp1_e = temp1_e->next;
		}
		temp = temp->next;
		temp_e = temp_e->next;
	}
}

void CLoadOBJ::Explosion_End()
{
	Explosion_Flag = 0;
}

void CLoadOBJ::Draw()
{
	STriangleBlock *temp;
	STriangle *temp1;
	if (Explosion_Flag)
	{
		DrawExplode();
		return;
	}
	temp = tb;
	while (temp)
	{
		if (temp->mat->texture != -1) glBindTexture(GL_TEXTURE_2D, temp->mat->texture);
		glColor3f(temp->mat->ar, temp->mat->ag, temp->mat->ab);
		glBegin(GL_TRIANGLES);
		temp1 = temp->tr;
		while (temp1)
		{
			glTexCoord2f(tx[temp1->ta-1], ty[temp1->ta-1]);
			glVertex3f(vx[temp1->a-1], vy[temp1->a-1], vz[temp1->a-1]);
			
			glTexCoord2f(tx[temp1->tb-1], ty[temp1->tb-1]);
			glVertex3f(vx[temp1->b-1], vy[temp1->b-1], vz[temp1->b-1]);

			glTexCoord2f(tx[temp1->tc-1], ty[temp1->tc-1]);
			glVertex3f(vx[temp1->c-1], vy[temp1->c-1], vz[temp1->c-1]);
			
			temp1 = temp1->next;
		}
		glEnd();
		temp = temp->next;		
	}
	glEnd();
}

void CLoadOBJ::DrawExplode()
{
	STriangleBlock *temp;
	STriangle *temp1;
	STriangleBlockFull *temp_e;
	STriangleFull *temp1_e;

	temp = tb;
	temp_e = e_tb;
	while (temp)
	{
		if (temp->mat->texture != -1) glBindTexture(GL_TEXTURE_2D, temp->mat->texture);
		glColor3f(temp->mat->ar, temp->mat->ag, temp->mat->ab);
		glBegin(GL_TRIANGLES);
		temp1 = temp->tr;
		temp1_e = temp_e->tr;
		while (temp1)
		{
			if (temp1_e->delete_coef > 0)
			{
				glTexCoord2f(tx[temp1->ta-1], ty[temp1->ta-1]);
				glVertex3f(temp1_e->x1, temp1_e->y1, temp1_e->z1);
			
				glTexCoord2f(tx[temp1->tb-1], ty[temp1->tb-1]);
				glVertex3f(temp1_e->x2, temp1_e->y2, temp1_e->z2);

				glTexCoord2f(tx[temp1->tc-1], ty[temp1->tc-1]);
				glVertex3f(temp1_e->x3, temp1_e->y3, temp1_e->z3);
			}
			
			temp1 = temp1->next;
			temp1_e = temp1_e->next;
		}
		glEnd();
		temp = temp->next;
		temp_e = temp_e->next;
	}
	glEnd();
}

⌨️ 快捷键说明

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