www.pudn.com > QuadTreeLOD4cs.rar > Loaders.cpp, change:2003-06-12,size:10124b


//==================================================================// 
//==================================================================// 
//= Loaders.cpp ====================================================// 
//==================================================================// 
//= Original coder: Trent Polack (ShiningKnight) ===================// 
//==================================================================// 
//==================================================================// 
 
#include "loaders.h" 
#include <stdio.h> 
#include "math.h" 
//------------------------------------------------------------------// 
//------------------------------------------------------------------// 
//- DEFINITIONS ----------------------------------------------------// 
//------------------------------------------------------------------// 
//------------------------------------------------------------------// 
 
//------------------------------------------------------------------// 
//- bool LoadTGA(char*, GLfloat, GLfloat) --------------------------// 
//------------------------------------------------------------------// 
//- Description: This function loads a truevision TARGA into the   -// 
//-				 CTexture class object that it represents.		   -// 
//------------------------------------------------------------------// 
//- Big thanks to NeHe for this one								   -// 
//------------------------------------------------------------------// 
 
 
 
//------------------------------------------------------------------// 
//- bool LoadBMP(char*, GLfloat, GLfloat) --------------------------// 
//------------------------------------------------------------------// 
//- Description: This function loads a Windows Bitmap into the	   -// 
//-				 CTexture class object that it represents.		   -// 
//------------------------------------------------------------------// 
//- Big thanks to NeHe for this one								   -// 
//------------------------------------------------------------------// 
 
 
 
//------------------------------------------------------------------// 
//------------------------------------------------------------------// 
//- CMD2 CODE -------------------------------------------------------// 
//------------------------------------------------------------------// 
//------------------------------------------------------------------// 
 
//------------------------------------------------------------------// 
//- bool Load(char*) -----------------------------------------------// 
//------------------------------------------------------------------// 
//- Description: This funtion loads a Quake 2 model (.md2) into the-// 
//-				 program!  .md2s are great, because there are a TON-// 
//-				 out there (www.polycount.com mainly), and they	   -// 
//-				 include keyframes inside of them!				   -// 
//------------------------------------------------------------------// 
//- Big thanks to Justin "Blackscar" Eslinger for this one...      -// 
//- though I only used a little bit of his base code, and even that-// 
//- I had to edit heavily... So I don't see why I'm giving him     -// 
//- any credit what-so-ever.  Oh well, he's a cool guy anyway. :D  -// 
//------------------------------------------------------------------// 
bool CMD2::Load(char* filename) 
{ 
	FILE* file; 
	MD2_HEADER header; 
	 
	//Open the .md2 model file 
	if((file= fopen(filename, "rb"))==NULL) 
	{ 
		::MessageBox(NULL,"error open md2 file.","error",MB_OK); 
		::ExitProcess(1); 
		return false; 
	} 
	 
	//Read in the header 
	fread(&header, sizeof(MD2_HEADER), 1, file); 
	 
	//Create space for the frame information 
	m_pFrames= new char[header.m_nFrameSize*header.nFrames]; 
	 
	//Check to see if it allocated correctly 
	if(m_pFrames==NULL) 
		return false; 
	 
	//Zoom to the correct spot in the file 
	fseek(file, header.offsetFrames, SEEK_SET); 
	fread(m_pFrames, header.m_nFrameSize*header.nFrames, 1, file); 
	 
	//Create space for the GL command information (whether or not to use tri strips, or tri fans) 
	m_pGLCommands= new long [header.nGlCommands]; 
	 
	//Check to see if it allocated correctly 
	if(m_pGLCommands==NULL) 
		return false; 
	 
	//Zoom to the correct spot in the file 
	fseek(file,		  header.offsetGlCommands, SEEK_SET); 
	fread(m_pGLCommands, header.nGlCommands*sizeof(long), 1, file);	 
	//Move the important information from the header, to the permanent class info. 
	m_nFrames	 = header.nFrames; 
	endFrame = m_nFrames; 
	m_nGlCommands= header.nGlCommands; 
	m_nFrameSize	 = header.m_nFrameSize; 
	m_nTriangles = header.nTriangles; 
	fclose(file);	 
	return true; 
} 
 
//------------------------------------------------------------------// 
//- void Render(int) -----------------------------------------------// 
//------------------------------------------------------------------// 
//- Description: This function renders an .md2 model with the given-// 
//-				 frame of animation.							   -// 
//------------------------------------------------------------------// 
//- Ok, now I really owe Justin a big one for this... His code     -// 
//-	seems to be the only one that took advantage of the gl commands-// 
//- that are within the md2 file (for speed)!					   -// 
//------------------------------------------------------------------// 
void CMD2::Render(int numFrame) 
{ 
	MD2_FRAME_PTR	currentFrame; 
	MD2_MODELVERTEX vertList[100]; 
	CVertex			v1; 
	CVertex			v2; 
	CVertex			v3; 
	long*			command; 
	float			texcoord[2]; 
	int				loop; 
	int				vertIndex; 
	int				type; 
	int				numVertex; 
	int				index; 
	 
	//Get the current frame and gl command information 
	currentFrame= (MD2_FRAME*) ((char*)m_pFrames+m_nFrameSize*numFrame); 
	command		= m_pGLCommands; 
	 
	//Make sure that the command doesn't equal 0, and if it doesn't lets start rendering! 
	while((*command)!=0) 
	{ 
		if(*command>0)	//This is a triangle strip 
		{ 
			numVertex= *command;  
			command++;  
			type= 0; 
		} 
		else			//This is a triangle fan 
		{ 
			numVertex= - *command;  
			command++;  
			type= 1; 
		} 
		 
		if(numVertex<0) 
			numVertex= -numVertex; 
		 
		index= 0; 
		//Fill the vertex list information 
		for(loop=0; loop<numVertex; loop++) 
		{ 
			vertList[index].u= *((float*)command);  
			command++; 
			vertList[index].v= *((float*)command);  
			command++; 
			 
			vertIndex= *command;  
			command++; 
			 
			vertList[index].x= ( (currentFrame->vertices[vertIndex].vertex[0]*  
				currentFrame->scale[0])+  
				currentFrame->translate[0]); 
			vertList[index].z= -((currentFrame->vertices[vertIndex].vertex[1]*  
				currentFrame->scale[1])+  
				currentFrame->translate[1]); 
			vertList[index].y= ( (currentFrame->vertices[vertIndex].vertex[2]*  
				currentFrame->scale[2])+  
				currentFrame->translate[2]); 
			index++; 
		} 
		 
		//If the .md2 was optimized for use with triangle strips... 
		if(type==0) 
		{ 
			glBegin(GL_TRIANGLE_STRIP); 
			for(loop=0; loop<index; loop++) 
			{ 
				v1.vertex[0]=(vertList[loop].x); 
				v1.vertex[1]=(vertList[loop].y); 
				v1.vertex[2]=(vertList[loop].z); 
				 
				texcoord[0]= vertList[loop].u; 
				texcoord[1]= vertList[loop].v; 
				 
				glTexCoord2fv(texcoord); 
				glVertex3fv(v1.vertex); 
			} 
			glEnd(); 
		} 
		 
		//If the .md2 was made for use with triangle fans... 
		else 
		{ 
			glBegin(GL_TRIANGLE_FAN); 
			for(loop=0; loop<index; loop++) 
			{ 
				v1.vertex[0]=(vertList[loop].x); 
				v1.vertex[1]=(vertList[loop].y); 
				v1.vertex[2]=(vertList[loop].z); 
				 
				texcoord[0]= vertList[loop].u; 
				texcoord[1]= vertList[loop].v; 
				 
				glTexCoord2fv(texcoord); 
				v1.SendToOGL(); 
			} 
			glEnd(); 
		} 
	//	char buf[255]; 
	//	sprintf(buf,"x y z  = %f %f %f\n",v1.vertex[0],v1.vertex[1],v1.vertex[2]); 
	//	OutputDebugString(buf); 
	} 
	} 
float CMD2::GetPercent() 
{ 
	static lastT = GetTickCount(); 
	float speed = 200.0; 
	static nowT = 0; 
	nowT = GetTickCount(); 
	if(nowT-lastT>speed) 
	{ 
		m_nCurrentFrame = (m_nCurrentFrame+1)%endFrame; 
		m_nNextFrame = (m_nCurrentFrame+1)%endFrame; 
		lastT = nowT; 
		return 1; 
	} 
	else 
	{ 
		return (nowT-lastT)/speed; 
	} 
} 
void CMD2::Animate() 
{ 
	MD2_FRAME_PTR	pCurrentFrm; 
	MD2_FRAME_PTR	pNextFrm; 
	CVertex			v1,v2; 
	long*			pCommand; 
	int				vertIndex; 
	int				type; 
	int				numVertex; 
	 
	//Get the current frame and gl pCommand information 
	pCurrentFrm= (MD2_FRAME*) ((char*)m_pFrames+m_nFrameSize*m_nCurrentFrame); 
	pNextFrm = (MD2_FRAME*) ((char*)m_pFrames+m_nFrameSize*m_nNextFrame); 
	pCommand		= m_pGLCommands; 
	float t = GetPercent(); 
	while((*pCommand)!=0) 
	{ 
		if(*pCommand>0)	//This is a triangle strip 
		{ 
			numVertex= *pCommand;  
			pCommand++;  
			type= 0; 
		} 
		else			//This is a triangle fan 
		{ 
			numVertex= - *pCommand;  
			pCommand++;  
			type= 1; 
		} 
		 
		if(numVertex<0) 
			numVertex= -numVertex; 
		 
		//Fill the vertex list information 
		if(type==0) 
			glBegin(GL_TRIANGLE_STRIP); 
		else  
			glBegin(GL_TRIANGLE_FAN); 
		for(int loop=0; loop<numVertex; loop++) 
		{ 
			float u= *((float*)pCommand);  
			pCommand++; 
			float v= *((float*)pCommand);  
			pCommand++; 
			 
			vertIndex= *pCommand;  
			pCommand++; 
			v1.vertex[0] =  pCurrentFrm->vertices[vertIndex].vertex[0]* pCurrentFrm->scale[0] +  
				pCurrentFrm->translate[0]; 
			v1.vertex[1] = pCurrentFrm->vertices[vertIndex].vertex[2]* pCurrentFrm->scale[2]+  
				pCurrentFrm->translate[2]; 
			v1.vertex[2] = -(pCurrentFrm->vertices[vertIndex].vertex[1]* pCurrentFrm->scale[1]+  
				pCurrentFrm->translate[1]); 
			v2.vertex[0] =  pNextFrm->vertices[vertIndex].vertex[0]* pNextFrm->scale[0] +  
				pNextFrm->translate[0]; 
			v2.vertex[1] = pNextFrm->vertices[vertIndex].vertex[2]* pNextFrm->scale[2]+  
				pNextFrm->translate[2]; 
			v2.vertex[2] = -(pNextFrm->vertices[vertIndex].vertex[1]* pNextFrm->scale[1]+  
				pNextFrm->translate[1]);						 
			glTexCoord2f(u,v); 
			glVertex3f(v1.vertex[0]+t*(v2.vertex[0]-v1.vertex[0]), 
				v1.vertex[1]+t*(v2.vertex[1]-v1.vertex[1]), 
				v1.vertex[2]+t*(v2.vertex[2]-v1.vertex[2]));	 
		} 
		glEnd(); 
	} 
}