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

📄 flyengine.cpp

📁 是3D游戏一书中所讲的游戏引擎fly3D 包括fly3D引擎的源码及应用此引擎开发出来的游戏实例 有fly3D引擎的教程,易于step by step跟学
💻 CPP
📖 第 1 页 / 共 4 页
字号:
#include "../Fly3D.h"

FLY_API flyEngine *flyengine=0;
FLY_API HWND hFlyWnd=0;
FLY_API HINSTANCE hFlyInst=0;

FLY_API void init_engine(HWND hWnd,HINSTANCE hInst,int appid)
{
	free_engine();
	set_engine(new flyEngine,hWnd,hInst,appid);
}

FLY_API void set_engine(flyEngine *eng,HWND hWnd,HINSTANCE hInst,int appid)
{
	flyengine=eng;
	flyengine->appid=appid;
	hFlyWnd=hWnd;
	hFlyInst=hInst;
}

FLY_API void free_engine()
{
	if (flyengine)
		delete flyengine;
	flyengine=0;
}

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
    switch (ul_reason_for_call)
	{
		case DLL_PROCESS_ATTACH:
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
		case DLL_PROCESS_DETACH:
			break;
    }
    return TRUE;
}

flyEngine::flyEngine()
{
	cur_step=cur_step_base=0;
	cur_frame=cur_frame_base=0;
	start_time=cur_time=cur_dt=0;
	intropic=introtime=0;

	player=0;
	cam=0;
	excludecollision=0;
	stepobj=0;

	nelemdraw=0;
	facedraw=0;
	nfacedraw=0;
	facedrawtransp=0;
	nfacedrawtransp=0;

	status_msg_time=0;
		
	bboxdiag=viewmaxdist=viewmindist=camangle=aspect=geomdetail=
		curveerr=lmpxsize=detailtile=cartoonwidth=shadowdepth=0;
	
	nodedrawcount=nodeonly=pvsoff=fog=mpdelay=antialias=
		amblight=mapmode=shadows=noinput=wireframe=mute=mouse=
		clearbk=moving=crosshairpic=crosshairsize=appid=multitexture=
		detailpic=hwlights=stencil=cartoonpic=cartoonpicbsp=0;

	active_obj0=last_active_obj=0;
	stock_obj0=0;
	model_obj0=0;
	sound_obj0=0;
	bezier_curve0=0;
	bezier_patch0=0;
	shadow_obj=0;
	hitobj=0;
	hitmesh=0;
	hitface=0;

	status=0;
	fontspic=0;
	consolepic=0;

	vert=vertcolor=vertnormal=0;
	nvert=0;

	faces=0;
	nfaces=0;

	edges=0;
	nedges=0;
	faceedges=0;

	bsp=0;
	npiclib=0;
	nlm=lmbase=nlmpic=0;
	fmbase=0;

	pvs=0;
	leaf=0;
	nleaf=pvssize=pvsrowsize=0;
	
	reset();

	appid=FLYAPPID_NONE;
	start_time=timeGetTime();

	strcpy(flysdkpath,GetCommandLine());
	if (flysdkpath[0]=='\"')
	{
		strcpy(flysdkpath,&flysdkpath[1]);
		if (strchr(flysdkpath,'\"')) 
			*strchr(flysdkpath,'\"')=0;
	}
	if (strrchr(flysdkpath,'\\'))
		*(strrchr(flysdkpath,'\\')+1)=0;
	else 
	{
		GetCurrentDirectory(255,flysdkpath);
		strcat(flysdkpath,"\\");
	}
	strlwr(flysdkpath);
}

void flyEngine::reset()
{
	int i;
	bsp_object *d;
	mesh *o;
	sound *s;
	bezier_curve *c;
	bezier_patch *p;

	while(active_obj0)
		{
		d=(bsp_object *)active_obj0->next_obj;
		delete active_obj0;
		active_obj0=d;
		}
	last_active_obj=0;
	while(stock_obj0)
		{
		d=(bsp_object *)stock_obj0->next_obj;
		delete stock_obj0;
		stock_obj0=d;
		}
	while(model_obj0)
		{
		o=(mesh *)model_obj0->next_obj;
		delete model_obj0;
		model_obj0=o;
		}
	while(sound_obj0)
		{
		s=(sound *)sound_obj0->next_obj;
		delete sound_obj0;
		sound_obj0=s;
		}
	while(bezier_curve0)
		{
		c=(bezier_curve *)bezier_curve0->next_obj;
		delete bezier_curve0;
		bezier_curve0=c;
		}
	while(bezier_patch0)
		{
		p=(bezier_patch *)bezier_patch0->next_obj;
		delete bezier_patch0;
		bezier_patch0=p;
		}

	if (bsp) 
		delete bsp;
	bsp=0;

	if (vert)
		delete vert;
	vert=0;

	if (vertnormal)
		delete vertnormal;
	vertnormal=0;

	if (vertcolor)
		delete vertcolor;
	vertcolor=0;

	if (faces)
		delete faces;
	faces=0;

	if (edges)
		delete edges;
	edges=0;

	if (faceedges)
		delete faceedges;
	faceedges=0;

	nvert=0;
	nfaces=0;
	nedges=0;

	if (npiclib)
		for( i=0;i<npiclib;i++ )
			delete piclib[i];
	npiclib=0;

	if (pvs)
		delete pvs;
	pvs=0;
	pvssize=0;
	pvsrowsize=0;

	if (leaf)
		delete leaf;
	leaf=0;
	nleaf=0;

	if (facedraw)
		delete facedraw;
	facedraw=0;

	if (facedrawtransp)
		delete facedrawtransp;
	facedrawtransp=0;

	for( i=0;i<nlmpic;i++ )
		{
		delete lmpic[i];
		delete fmpic[i];
		}
	for( i=0;i<nlm;i++ )
		{
		delete lm[i];
		delete fm[i];
		}
	nlm=0;
	nlmpic=0;
	lmbase=0;
	fmbase=0;

	dll.reset();

	fontspic=-1;
	crosshairpic=-1;
	detailpic=-1;
	intropic=-1;
	consolepic=-1;
	cartoonpicbsp=-1;
	cartoonpic=-1;

	bspfile[0]=0;
	flydatapath[0]=0;
	flyfile[0]=0;
	flyfilename[0]=0;
	console_command[0]=0;
	status_msg[0]=0;
	status_msg_time=0;

	nodedrawcount=nfacedraw=nfacedrawtransp=0;

	cur_frame=cur_frame_base=0;
	cur_step=cur_step_base=0;
	cur_time=cur_dt=0;

	filter.vec(0,0,0);
	background.vec(0,0,0);
	clearbk=1;
	introtime=2000;

	cam=0;
	player=0;
}

void flyEngine::compute_normals()
{
	// simple and fast vertex normals
	int i,j;
	if (vertnormal)
		delete vertnormal;
	vertnormal=new vector[nvert];
	memset(vertnormal,0,sizeof(vector)*nvert);
	for( j=0;j<nfaces;j++ )
	{
		vertnormal[faces[j].vert[0]-vert]+=faces[j].normal;
		vertnormal[faces[j].vert[1]-vert]+=faces[j].normal;
		vertnormal[faces[j].vert[2]-vert]+=faces[j].normal;
	}
	for( i=0;i<nvert;i++ )
		vertnormal[i].normalize();

	for( i=0;i<nfaces;i++ )
		for( j=0;j<3;j++ )
			faces[i].vertnormal[j]=vertnormal[faces[i].vert[j]-vert];
/*
	// more accurate and slower vertex normals
	if (vertnormal)
		delete vertnormal;
	vector *nn=new vector[nfaces];
	vertnormal=new vector[nvert];
	int i,j,k,nc;
	for( i=0;i<nvert;i++ )
		{
		nc=0;
		for( j=0;j<nfaces;j++ )
			if (faces[j].vert[0]==&vert[i] ||
				faces[j].vert[1]==&vert[i] ||
				faces[j].vert[2]==&vert[i])
				{
				for( k=0;k<nc;k++ )
					if (vec_dot(faces[j].normal,nn[k])>0.999848f)
						break;
				if (k==nc)
					nn[nc++]=faces[j].normal;
				}
		vertnormal[i].null();
		if (nc)
			{
			for( k=0;k<nc;k++ )
				vertnormal[i]+=nn[k];
			vertnormal[i].normalize();
			}
		}
	for( i=0;i<nfaces;i++ )
		for( j=0;j<3;j++ )
			faces[i].vertnormal[j]=vertnormal[faces[i].vert[j]-vert];
	delete nn;
*/
	// bound box
	bbox1.vec(BIG,BIG,BIG);
	bbox2.vec(-BIG,-BIG,-BIG);

	for( i=0;i<nvert;i++ )
	{
		if (vert[i].x>bbox2.x)
			bbox2.x=vert[i].x;
		if (vert[i].y>bbox2.y)
			bbox2.y=vert[i].y;
		if (vert[i].z>bbox2.z)
			bbox2.z=vert[i].z;

		if (vert[i].x<bbox1.x)
			bbox1.x=vert[i].x;
		if (vert[i].y<bbox1.y)
			bbox1.y=vert[i].y;
		if (vert[i].z<bbox1.z)
			bbox1.z=vert[i].z;
	}

	bboxdiag=(bbox2-bbox1).length();
	bboxC=(bbox1+bbox2)*0.5f;
}

int flyEngine::collision_bsp(bsp_node *n,vector& p1,vector& p2,int elemtype,float rad)
{
	if (n->leaf!=-1)
	{
		bsp_object *e=n->elem;
		vector rd=p2-p1;
		float dist=1.0f,d;
		mesh *m;
		vector ip;
		int f;
		
		hitobj=0;

		while(e)
		{
			if	(e!=flyengine->excludecollision && 
				(elemtype==0 || e->type==elemtype))
			{
				m=e->ray_intersect(p1,rd,ip,d,f,rad);
				if (m && d<dist)
				{
					dist=d;
					hitobj=e;
					hitip=ip;
					hitface=f;
					hitmesh=m;
				}
			}
			e=e->next_elem;
		}

		if (hitobj)
			return 1;
		else return 0;
	}

	float d1=vec_dot(n->normal,p1)+n->d0, 
		d2=vec_dot(n->normal,p2)+n->d0;
	
	if(d1<-rad && d2<-rad)
		if (n->child[1])
			return collision_bsp(n->child[1],p1,p2,elemtype,rad);
		else return 0;
	else 
	if(d1>rad && d2>rad)
		if (n->child[0])
			return collision_bsp(n->child[0],p1,p2,elemtype,rad);
		else return 0;
	else 
		{
		if (d1>0)
			{
			if (n->child[0])
				if (collision_bsp(n->child[0],p1,p2,elemtype,rad))
					return 1;
			if (n->child[1])
				if (collision_bsp(n->child[1],p1,p2,elemtype,rad))
					return 1;
			}
		else
			{
			if (n->child[1])
				if (collision_bsp(n->child[1],p1,p2,elemtype,rad))
					return 1;
			if (n->child[0])
				if (collision_bsp(n->child[0],p1,p2,elemtype,rad))
					return 1;
			}

		return 0;
		}
}

void flyEngine::compute_edges()
{
	if (edges)
		delete edges;
	edges=new int[nfaces*3*5];
	if (faceedges)
		delete faceedges;
	faceedges=new int[nfaces*3];
	nedges=0;
	int i1,i2;
	int i,j,nc,k;

	for( i=0;i<nfaces;i++ )
		for( j=0;j<3;j++ )
		{
			i1=faces[i].vert[j]-vert;
			i2=faces[i].vert[(j+1)%3]-vert;
			nc=0;
			for( k=0;k<nedges;k++,nc+=5 )
				if ((i1==edges[nc] && i2==edges[nc+1]) ||
					(i1==edges[nc+1] && i2==edges[nc]))
					break;
			if (k==nedges)
			{
				edges[nc]=i1;
				edges[nc+1]=i2;
				edges[nc+2]=i;
				edges[nc+3]=-1;
				edges[nc+4]=0;
				faceedges[i*3+j]=nedges;
				nedges++;
			}
			else 
			{
				faceedges[i*3+j]=k;
				if ((faces[i].color-faces[edges[nc+2]].color).length()<0.1f)
					edges[nc+3]=i;
			}
		}
}

void flyEngine::draw_bsp(int mode)
{
	nodedrawcount=0;
	nelemdraw=0;
	memset(nelemlatedraw,0,sizeof(int)*MAX_LATEDRAW_LAYERS);
	nfacedraw=0;
	nfacedrawtransp=0;
	
	draw_bsp(bsp);

	if (mode)
	{
		if (edges==0)
			compute_edges();
		draw_static_faces_cartoon(facedraw,nfacedraw);
		draw_bsp_edges();
	}
	else
	{
		if (nfacedraw)
			draw_static_faces(facedraw,nfacedraw);
		if (nfacedrawtransp)
			draw_static_faces(facedrawtransp,nfacedrawtransp);
	}

	int i,j;
	for( i=0;i<nelemdraw;i++ )
		elemdraw[i]->draw();
	for( j=0;j<MAX_LATEDRAW_LAYERS;j++ )
		for( i=0;i<nelemlatedraw[j];i++ )
			elemlatedraw[j][i]->draw();
}

void flyEngine::draw_bsp(bsp_node *n)
{
	if (n->leaf!=-1)
		{
		if (cam->node==0 || (nodeonly && n!=cam->node))
			return;
		if (pvsoff || PVS_TEST(cam->node->leaf,n->leaf))
			{
			bsp_object *e=n->elem;
			while(e)
				{
				if (e->type==TYPE_STATIC_MESH)
					{
					static_mesh *o=(static_mesh *)e;
					o->objmesh->lastdraw=cur_frame;
					for( int i=0;i<o->objmesh->nf;i++ )
						if (o->objmesh->faces[i]->lastdraw!=cur_frame)
						{
						if (FP_BITS(o->objmesh->faces[i]->color.w)==FP_ONE_BITS)
							facedraw[nfacedraw++]=o->objmesh->faces[i]->indx;
						else if (FP_BITS(o->objmesh->faces[i]->color.w)!=0)
							facedrawtransp[nfacedrawtransp++]=o->objmesh->faces[i]->indx;
						o->objmesh->faces[i]->lastdraw=cur_frame;
						}
					}
				else 
					elemlatedraw[e->latedraw&7][nelemlatedraw[e->latedraw&7]++]=e;
				e=e->next_elem;
				}
			nodedrawcount++;
			}
		return;
		}

	float x1,x2;
	int i;

	x1=n->distance(frustrum[0]);
	for( i=1;i<5;i++ )
		{
		x2=n->distance(frustrum[i]);
		if (x1*x2<=0)
			break;
		}
	if (i==5)
		if (x1>0)
		{
			if (n->child[0]) 
				draw_bsp(n->child[0]);
		}
		else 
		{ 
			if (n->child[1]) 
				draw_bsp(n->child[1]);
		}
	else 
		if (x1<0)
			{
			if (n->child[1]) 
				draw_bsp(n->child[1]);
			if (n->child[0]) 
				draw_bsp(n->child[0]);
			}
		else 
			{
			if (n->child[0]) 
				draw_bsp(n->child[0]);
			if (n->child[1]) 
				draw_bsp(n->child[1]);
			}
}

int flyEngine::step()
{		
	static int dt,t0=timeGetTime()-start_time;

	// compute elapsed time
	cur_time=timeGetTime()-start_time;
	dt=cur_time-t0;
	if (dt>0)
		{
		t0=cur_time;
		if (dt<1000)
			{
			step(dt);
			return dt;
			}
		}
	return 0;
}

void flyEngine::step(int dt)
{
	if (flyengine->player==0 || flyengine->cam==0 || flyengine->bsp==0)
		return;

	// process console commands
	if (flyengine->console_command[0])
		{
		char *c=flyengine->console_command;
		do
			{
			flyengine->con.command_exec(c);
			c=strchr(c,';');
			if (c)
				*(c++)=0;
			} 
		while(c);
		}
	flyengine->console_command[0]=0;

	int i;
	// if not in server mode
	if (directx->mpmode!=FLYMP_SERVER)
	{
	// get input
	if (noinput)
		{
		memset(directx->diks,0,sizeof(directx->diks));
		memset(&directx->dims,0,sizeof(directx->dims));
		}

⌨️ 快捷键说明

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