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

📄 3dsload.cpp

📁 这是书上的代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
  	while((pc=dgetpos()) < p) {		dread(&id, sizeof(id));		dread(&len, sizeof(len));		switch((unsigned int)id) {			case CHUNK_OBJMESH: /*0x3D3D*/				ReadObjMeshBlocks(pc+len); 				break;			case CHUNK_KEYFRAMER:/*0xB000*/
				//此处可以加入对关键帧信息的读取函数			default: 
				dsetpos(pc+len);		}	}}//从文件中读入一个H3dsScene数据结构
//这里是3DS场景读取的主函数,函数首先从文件中读入3DS文件标识,即基本块标识,若标识不正确
//则说明不是一个合法的3DS文件。否则按3DS文件的组织,读入其主块信息。/* Reads in a H3dsScene from the disk */H3dsScene *HRead3dsScene(void *ptr, int what, dword size) {	int retval = setjmp(EnvState);  	if(ptr==0)		return 0;  	if(what==0)		InFile=(FILE *) ptr;	else		return 0;  	/* Initialize the global var Scene & fill with zeroes */
	//初始化全局数据结构Scene,并将其初值置为0	if ((Scene=(H3dsScene *) malloc(sizeof(H3dsScene)))==0)		return 0;	memset(Scene, 0, sizeof(H3dsScene));	Scene->material = 0;	Scene->NumMaterials = 0;	if(retval==0) {		/* Return address set, start loading 3DS data. */
		//返回地址集合,开始装入3DS数据		word id;		dword len, pc;		//读入3DS文件标识		pc=dgetpos();		dread(&id, sizeof(id));		dread(&len, sizeof(len));
		//标识不正确,非3DS文件		if((int)id!=CHUNK_MAIN) {/*0x4D4D*/
			//将分配到的空间释放			HFree3dsScene(Scene);			AfxMessageBox("所打开的文件可能不是一个合法的3DS文件.");			return 0;		}		ReadMainBlocks(pc+len);	}	else {		/* There was an error, free the allocated mem and return NULL. */
		//读取数据出错,也将分配到的空间释放。		HFree3dsScene(Scene);		return 0;	}  	return Scene;}//将内部数据结构填充到一个易于读取的数据结构中//Feed our internal data to the outgl.cpp functionsvoid Convert_to_OUTGL() {	int x,y,z;
	int faceindex;	int current;	int MaterialNum;	void *ptr;
	float32 *m;	float32 swap;	OUTGL_RGB ambient, diffuse, specular;	OUTGL_VERTEX v;	OUTGL_TRIANGLE tri;	char *name;
	MaterialNum=Scene->NumMaterials;//add by jiangzibin
	ptr=NULL;
	m=0;	//Start with the material properties	//If the model has default materials in it, substitute an all-white material
	//如果模型使用默认材质,则将默认材质定义为一个全白色的材质。
		if (defaultmaterialwarning) {
		ambient.red = \		ambient.green = \		ambient.blue = 1.0;		ambient.alpha = 1.0;		diffuse.red = \		diffuse.green = \		diffuse.blue = 1.0;		diffuse.alpha = 1.0;		specular.red = \		specular.green = \		specular.blue = 1.0;		specular.alpha = 1.0;		OutGLAddMaterial(ambient, diffuse, specular, "WG_DEFAULT", "", 1);	}
		//将每个材质的名称及其属性填入OutGL结构中	//Feed each material and its properties to OutGL	for (x=0; x<Scene->NumMaterials; x++) {
		H3dsMat *mat = &Scene->material[x];		ambient.red = mat->ambient.red;		ambient.green = mat->ambient.green;		ambient.blue = mat->ambient.blue;		ambient.alpha = 1.0;		diffuse.red = mat->diffuse.red;		diffuse.green = mat->diffuse.green;		diffuse.blue = mat->diffuse.blue;		diffuse.alpha = 1.0;		specular.red = mat->specular.red;		specular.green = mat->specular.green;		specular.blue = mat->specular.blue;		specular.alpha = 1.0;		OutGLAddMaterial(ambient, diffuse, specular, mat->name, mat->texture.texturename,\
			mat->doublesided);	}
//	AfxMessageBox("Break Here");	//再将每个顶点和多边形的信息填入OutGL结构中,需注意顶点的填入顺序	//Then do the vertices and polygons	//Order is important!	current = 0;
	
	for (x=0; x<Scene->meshobjs; x++) {
		H3dsMeshObj *meshobj = &Scene->meshobjlist[x];		//交换y,z坐标		//Swap y and z (.3ds wierdness)		for (y=0; y<meshobj->NumVerts; y++) {			swap = meshobj->vertlist[y].y;			meshobj->vertlist[y].y = meshobj->vertlist[y].z;			meshobj->vertlist[y].z = swap;		}		//将顶点信息填入OutGL结构中去		//Feed the vertices to outgl		for (y=0; y<meshobj->NumVerts; y++) {			v.x = meshobj->vertlist[y].x;			v.y = meshobj->vertlist[y].y;			v.z = meshobj->vertlist[y].z;			if (meshobj->NumMaps) {				v.u = meshobj->maplist[y].u;				v.v = meshobj->maplist[y].v;			}
			else {				v.u = 0;				v.v = 0;			}
						OutGLAddVertex(v);		}				for (y=0; y<meshobj->NumBindings; y++) {			name = meshobj->bindings[y].name;			for (z=0; z<meshobj->bindings[y].NumFaces; z++) {
				//将多边形反向,即三角形(0,1,2)=>(0,2,1)				// Flip the polygon orientation by using points (0,2,1)
				faceindex=meshobj->bindings[y].faces[z];				tri.p0 = meshobj->facelist[faceindex].p0 + current;				tri.p1 = meshobj->facelist[faceindex].p2 + current;				tri.p2 = meshobj->facelist[faceindex].p1 + current;				OutGLAddPolygon(tri, name);			}		}
				current += meshobj->NumVerts;	}	//将OutGL中所有内容包装起来	//Wrap everything up in the outgl object
	OutGLFinishModel();
}     /**********************************************************************************************  Function to read in the .3DS file *filename and assign its contents to  the polygon and object classes. This kicks the whole 3DS parsing off.  *********************************************************************************************/
//读入3DS文件,并将它的所有内容赋给多边形和物体类M3DSObject* Load3DSObject(char *filename)
{	FILE *inf;	H3dsScene *scene;
	long size;  	doublesided = defaultmaterialwarning = 0;	//以二进制方式打开文件	/* Open & prepare input file */	if(!(inf = fopen(filename, "rb"))) {
		CString str;
		str.Format("打开文件 %s 时失败了",filename);
		AfxMessageBox(str);		return NULL;	}		if(fseek(inf, 0, SEEK_END)) {
		fclose(inf);		return NULL;	}		if((size=ftell(inf)) == -1L) {
		fclose(inf);		return NULL;	}	rewind(inf);	//读入文件将其内容放入scene中去	/* Read in the file and place it in *scene */	if((scene = HRead3dsScene(inf, 0, size)) == 0) {
		fclose(inf);		return NULL;	}
		fclose(inf);	/* Convert our internal data structure to outgl's structure */
	//将内部数据转换为OutGL的结构
	if (!(Obj3DS = (M3DSObject *) malloc(sizeof(M3DSObject)))) 
		return NULL;
	Obj3DS->NumPolygon=0;
	Obj3DS->NumVertex=0;
	Convert_to_OUTGL();
	HFree3dsScene(scene);
	

	Obj3DS->NumVertex=NumVertex;
	Obj3DS->VertexLists=VertexList;
	Obj3DS->NumPolygon=NumPolyLists;
	Obj3DS->strip=0;
	Obj3DS->PolygonLists=PolyList;

	Unitize3DSObject(Obj3DS);

	//存储空间由Obj3DS释放
	NumVertex=0;
	VertexList=NULL;
	NumPolyLists=0;
	PolyList=NULL;

  	return Obj3DS;}
static GLfloat OutputAbs(GLfloat f){
	if(f<0)
		return -f;
	return f;
}
static GLfloat OutputMax(GLfloat a,GLfloat b){
	if(b>a)
		return b;
	return a;
}
static float	m_center[3], m_minXYZ[3], m_maxXYZ[3], m_range[3];
static float	m_scaleFactor;
//将3DS模型归一化,即将模型平移到原点,并缩放到每个坐标均在[-1,1]
//范围的立方体中。
void Unitize3DSObject(M3DSObject *object)
{
	if(object==NULL)
		return;
	if(object->VertexLists==NULL)
		return;
	GLfloat maxx,minx,maxy,miny,maxz,minz;
	GLfloat cx,cy,cz,w,h,d;
	GLfloat scale;
	minx=miny=minz=(GLfloat)1E+20;
	maxx=maxy=maxz=(GLfloat)1E-20;
	for(unsigned int i=0;i<object->NumVertex;i++){
		if(maxx<object->VertexLists[i].x)
			maxx=object->VertexLists[i].x;
		if(minx>object->VertexLists[i].x)
			minx=object->VertexLists[i].x;

		if(maxy<object->VertexLists[i].y)
			maxy=object->VertexLists[i].y;
		if(miny>object->VertexLists[i].y)
			miny=object->VertexLists[i].y;

		if(maxz<object->VertexLists[i].z)
			maxz=object->VertexLists[i].z;
		if(minz>object->VertexLists[i].z)
			minz=object->VertexLists[i].z;
	}
	//计算模型的宽度、高度和深度
	w=OutputAbs(maxx)+OutputAbs(minx);
	h=OutputAbs(maxy)+OutputAbs(miny);
	d=OutputAbs(maxz)+OutputAbs(minz);
	//计算模型的中心
	cx=(maxx+minx)/2.0f;
	cy=(maxy+miny)/2.0f;
	cz=(maxz+minz)/2.0f;
	//计算归一化所需的缩放比例
	scale=2.0f/OutputMax(OutputMax(w,h),d);
	m_scaleFactor=scale;
	m_minXYZ[0]=-w*scale;
	m_minXYZ[1]=-h*scale;
	m_minXYZ[2]=-d*scale;
	m_maxXYZ[0]= w*scale;
	m_maxXYZ[1]= h*scale;
	m_maxXYZ[2]= d*scale;
	m_range[0]=2*w*scale;
	m_range[1]=2*h*scale;
	m_range[2]=2*d*scale;
	m_center[0]=m_center[1]=m_center[2]=0;
	//先平移到原点,再缩放
	for(unsigned int m=0;m<object->NumVertex;m++){
		object->VertexLists[m].x-=cx;
		object->VertexLists[m].y-=cy;
		object->VertexLists[m].z-=cz;

		object->VertexLists[m].x*=scale;
		object->VertexLists[m].y*=scale;
		object->VertexLists[m].z*=scale;
	}
}
void GetMinMax3DS(float min[3], float max[3], float *scaleFactor)
{
	min[0]=m_minXYZ[0];
	min[1]=m_minXYZ[1];
	min[2]=m_minXYZ[2];

	max[0]=m_maxXYZ[0];
	max[1]=m_maxXYZ[1];
	max[2]=m_maxXYZ[2];

	*scaleFactor=m_scaleFactor;
}
H3dsMat *FindMaterial(char *name){
	for(int i=0;i<Scene->NumMaterials;i++){
		if(strcmp(Scene->material->name,name)==0){
			return Scene->material;
		}
	}
	return NULL;
}

void Draw3DSObject(M3DSObject *object)
{
	/* Draw sparse triangles */
	glInterleavedArrays(GL_T2F_N3F_V3F, 0,object->VertexLists);
	for (unsigned int m=0; m<object->NumPolygon; m++) {
		glMaterialfv(GL_FRONT, GL_AMBIENT,  (GLfloat *) &object->PolygonLists[m].ambient);
		glMaterialfv(GL_FRONT, GL_DIFFUSE,  (GLfloat *) &object->PolygonLists[m].diffuse);
		glMaterialfv(GL_FRONT, GL_SPECULAR, (GLfloat *) &object->PolygonLists[m].specular);

		glDrawElements(GL_TRIANGLES, 
			object->PolygonLists[m].NumTriangles*3, 
			GL_UNSIGNED_INT, 
			object->PolygonLists[m].CrunchedTriangleIndexList);
	}    
}
void Free3DSObject(M3DSObject *object)
{
	unsigned int i;
	unsigned int nv=object->NumVertex;
	free(object->VertexLists);
	object->VertexLists=NULL;
	for (i=0; i<object->NumPolygon; i++) {
		free (object->PolygonLists[i].TriangleIndexList);
		object->PolygonLists[i].TriangleIndexList=NULL;
		free (object->PolygonLists[i].CrunchedTriangleIndexList);
		object->PolygonLists[i].CrunchedTriangleIndexList=NULL;
	}
	free(object);
	object=NULL;

	OUTGL_TRIANGLENODE *TempPtr, *LList;
	for (i=0; i<nv; i++) {
		LList = CommonTriangleList[i];
		while (LList) {
			TempPtr = LList;
			LList = LList->next;
			free (TempPtr);
		}
	}
	free (CommonTriangleList);
	CommonTriangleList=NULL;

}

⌨️ 快捷键说明

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