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

📄 md3.cpp

📁 direct3d游戏编程基础源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// -----------------------------------------------------
// File: md3.cpp
// Description: methods to load and render a *.md3 file
//
// Author: Wolfgang Engel (wolf@direct3d.net)
// Internet: www.direct3d.net
// Last modified: 20. December 2000
//
// Copyright (c) 1999-2001 Wolfgang Engel wolf@direct3d.net
// -----------------------------------------------------
#include "md3.h"

// custom vertex structure
// Quake 3 uses hardware transformation, but not hardware lighting
struct MD3VERTEXBUFFERSTRUCT
{
    D3DXVECTOR3 p;
    FLOAT       tu, tv;
};

// Our custom FVF, which describes our custom vertex structure
#define FVF_MD3VERTEXBUFFERSTRUCT (D3DFVF_XYZ|D3DFVF_TEX1)

//-----------------------------------------------------------------------------
// Name: CMD3Model()
// Desc: The konstructor
//-----------------------------------------------------------------------------
CMD3Model::CMD3Model()
{
	m_pVB = NULL;  // vertex buffer
	iNumMeshes = 0;
}

//-----------------------------------------------------------------------------
// Name: CMD3Model()
// Desc: The konstructor
//-----------------------------------------------------------------------------
CMD3Model::~CMD3Model()
{
	DeleteModel();
}


//-----------------------------------------------------------------------------
// Name: CreateModel()
// Desc: Loads the *.md3 file
//-----------------------------------------------------------------------------
BOOL CMD3Model::CreateModel( char *fname, LPDIRECT3DDEVICE8 lpD3Ddevice)
{
	MD3HEADER		md3Header;
	MD3MESHFILE		md3MeshFile;
	FILE *md3File;

	DWORD m_dwNumberofVertices = 0;		// to fprintf the number of vertices
	DWORD m_dwNumberofTriangles = 0;	// to fprintf the number of triangles

	// if there are old vertex buffers and textures: delete them
	DeleteVB();
	DeleteTextures();
	DeleteModel();		// delete old model data

	// open file
    md3File = fopen( fname, "rb" );
	if( !md3File )
		return FALSE;

	// create and open log file
	LogFile = fopen("md3 geometry data.txt","w");

	// read MD3HEADER
	fread( &md3Header, sizeof( MD3HEADER ) ,1, md3File );

	fprintf(LogFile,"--- MD3 Header --- \n");
	fprintf(LogFile,"id: %s\niVersion: %d\n", md3Header.id, md3Header.iVersion);
	fprintf(LogFile,"Name of file: %s\n", md3Header.cFileName);
	fprintf(LogFile,"Number of bone frames: %d\n", md3Header.iBoneFrameNum);
	fprintf(LogFile,"Number of tags: %d\n", md3Header.iTagNum);
	fprintf(LogFile,"Number of meshes: %d\n", md3Header.iMeshNum);
	fprintf(LogFile,"Max. number of textures: %d\n", md3Header.iMaxTextureNum);
	fprintf(LogFile,"Header size: %d\n", md3Header.iHeaderSize);
	fprintf(LogFile,"Starting position of tag data: %d\n", md3Header.iTagStart);
	fprintf(LogFile,"End tag data: starting position of mesh data: %d\n", md3Header.iMeshStart);
	fprintf(LogFile,"Size of file: %d\n\n", md3Header.iFileSize);


	if (//(strcmp(md3Header.id,"IDP3")==0)&&
		(md3Header.iHeaderSize == 108)&&
		(md3Header.iFileSize > md3Header.iTagStart)&&
		(md3Header.iFileSize > md3Header.iMeshStart)&&
		(md3Header.iVersion == 15))
	{
	//---------------------------------------------------------------------------
	// Reads in the following order
	//	1. read bone frames
	//	2. read tags
	//	3. read meshes
	//---------------------------------------------------------------------------

	// read MD3BONEFRAME
	md3BoneFrame = new MD3BONEFRAME[md3Header.iBoneFrameNum];
	for(int i = 0; i < md3Header.iBoneFrameNum; i++)
	{
		fread( &md3BoneFrame[i], sizeof( MD3BONEFRAME ), 1, md3File );
	}
	delete[] md3BoneFrame;	// we won't use it here

	fprintf(LogFile,"--- Tags --- \n");

	// if there are tags: get them
	md3Tags = (MD3TAG**)new MD3TAG[md3Header.iBoneFrameNum];
	if (md3Header.iTagNum != 0)
	{
		for (i=0;i < md3Header.iBoneFrameNum;i++)
		{
			md3Tags[i] = (MD3TAG*)new MD3TAG[md3Header.iTagNum];
//			fprintf(LogFile,"\nBone Frame Num: %d\n", i);

			for (int j=0;j < md3Header.iTagNum; j++)
			{
				fread( &md3Tags[i][j], sizeof( MD3TAG ), 1, md3File );
//				fprintf(LogFile,"Tag name: %s\n", md3Tags[i][j].cTagName);
			}
		}
		delete[] md3Tags;	// we won't use it here
	}

	// read MD3MESHes
	iNumMeshes = md3Header.iMeshNum;
	pMd3Meshes = new MD3MESH[iNumMeshes];

	fprintf(LogFile,"\n--- MD3 Meshes ---\n");
	for(int j = 0; j < iNumMeshes; j++)
	{
		// Read MD3MESHFILE
		fread( &md3MeshFile, sizeof( MD3MESHFILE ), 1, md3File );

		// Log MD3MESHFILE
		fprintf(LogFile,"id: %s\n", md3MeshFile.cId);
		fprintf(LogFile,"Name of mesh: %s\n", &md3MeshFile.cName);
		fprintf(LogFile,"Number of mesh frames: %d\n", md3MeshFile.iMeshFrameNum);
		fprintf(LogFile,"Number of textures: %d\n", md3MeshFile.iTextureNum);
		fprintf(LogFile,"Number of vertices: %d\n", md3MeshFile.iVertexNum);
		fprintf(LogFile,"Number of triangles: %d\n", md3MeshFile.iTriangleNum);
		fprintf(LogFile,"Starting position of triangle data: %d\n", md3MeshFile.iTriangleStart);
		fprintf(LogFile,"Header size: %d\n", md3MeshFile.iHeaderSize);
		fprintf(LogFile,"Starting position of texture coordiantes data: %d\n", md3MeshFile.iTecVecStart);
		fprintf(LogFile,"Starting position of vertex data: %d\n", md3MeshFile.iVertexStart);
		fprintf(LogFile,"Size of MD3MESHFILE: %d\n", &md3MeshFile.iMeshSize);

		strcpy (pMd3Meshes[j].cName, md3MeshFile.cName);

		//-------------------------------------------------------------------------
		// Loading the mesh data in the following order:
		// 1. texnames
		// 2. triangles
		// 3. texcoords
		// 4. vertices
		//-------------------------------------------------------------------------
		pMd3Meshes[j].iNumTextures = md3MeshFile.iTextureNum;
		pMd3Meshes[j].pTexNames = new TEXNAMES[pMd3Meshes[j].iNumTextures];
		// always one mesh >= one texture
		for(i = 0; i < pMd3Meshes[j].iNumTextures; i++)
		{
			/* a few graphic tools write the wrong texture path
			   in the *.md3 file. Instead of 
			   models\players\conni
			   they write
			    odels\players\conni
			   with a space at the beginning. fread() ends reading
			   when a space shows up. The hack is reading in the 
			   whole stuff with fgetc() ... a little bit slower.
			   This one takes me hours :-( .
			*/
			char cTemp[68];
			for (int w = 0; w < 68; w++)
			{
			  cTemp[w] = fgetc(md3File);
			}
			cTemp[0] = 'M';				// hack !!!!!!!
	 		strcpy (pMd3Meshes[j].pTexNames[i], cTemp);
		}

		// triangles
		pMd3Meshes[j].pTriangles= new TRIANGLEVERT[md3MeshFile.iTriangleNum];
		DWORD x, y, z;
		for(i = 0; i < md3MeshFile.iTriangleNum; i++)
		{
			// Another hack:
			// some tools do not produce the right triangle data here.
			// This is normally the case at the end of the 
			// triangle data stream. 
			// I try to filter out the grab by using a high and low 
			// limit, which I have choosed by try and error.
			// BTW.: Loading the corrupted md3 file into milkshape and 
			//		 saving it unchanged helps a lot :-) 
			if (((x = ReadLong(md3File))< 0) || (x > 20000))
				x = 0;
			if (((y = ReadLong(md3File))< 0) || (y > 20000))
				y = 0;
			if (((z = ReadLong(md3File))< 0) || (z > 20000))
				z = 0;
			pMd3Meshes[j].pTriangles[i][0]= x;
			pMd3Meshes[j].pTriangles[i][1]= y;
			pMd3Meshes[j].pTriangles[i][2]= z;
		}

		// texture coordinates
		pMd3Meshes[j].pfTextureCoords = new TEXCOORDS [md3MeshFile.iVertexNum];
		for(i = 0; i < md3MeshFile.iVertexNum; i++)
		{
			pMd3Meshes[j].pfTextureCoords[i].u = ReadFloat(md3File);
			pMd3Meshes[j].pfTextureCoords[i].v = ReadFloat(md3File);
		}

		// vertices ...
		pMd3Meshes[j].vMeshFrames= new VMESHFRAME[md3MeshFile.iMeshFrameNum];
		for(i = 0; i < md3MeshFile.iMeshFrameNum; i++)
		{
			pMd3Meshes[j].vMeshFrames[i] = new D3DXVECTOR3[md3MeshFile.iVertexNum];

			for(int w = 0; w < md3MeshFile.iVertexNum; w++)
			{
				/* To handle a file from a right handed coordinates 
				   system, you might exchange the y and z value.
				*/
				pMd3Meshes[j].vMeshFrames[i][w].x = ReadShort(md3File) / 64.0f;
				pMd3Meshes[j].vMeshFrames[i][w].z = ReadShort(md3File) / 64.0f;
				pMd3Meshes[j].vMeshFrames[i][w].y = ReadShort(md3File) / 64.0f;
				ReadShort(md3File); // unknown
			}
		}
		pMd3Meshes[j].iNumVertices = md3MeshFile.iVertexNum;
		pMd3Meshes[j].iMeshFrameNum = md3MeshFile.iMeshFrameNum;
		pMd3Meshes[j].iNumTriangles = md3MeshFile.iTriangleNum;

		m_dwNumberofVertices += pMd3Meshes[j].iNumVertices;
		m_dwNumberofTriangles += pMd3Meshes[j].iNumTriangles;


		// md3 file read length
		int End = ftell(md3File);
		fprintf(LogFile,"End of Mesh in md3File at: %d\n\n", End);
	} //for nummeshes


	// close the *.md3 file
    fclose(md3File);

	}
	else
		return FALSE;

	fprintf(LogFile,"\n--- Model statistic ---\n");
	fprintf(LogFile,"Number of vertices: %d\n", m_dwNumberofVertices);
	fprintf(LogFile,"Number of triangles: %d\n", m_dwNumberofTriangles);

	// close the LogFile
	fclose(LogFile);

	// creates vertex buffer and textures
	CreateVB(lpD3Ddevice);
	CreateTextures(lpD3Ddevice);

  return TRUE;
}

//-----------------------------------------------------------------------------
// Name: DeleteModel()
// Desc: de allocate memory
//-----------------------------------------------------------------------------
void CMD3Model::DeleteModel()
{
/*
	if (md3BoneFrame)
		delete[] md3BoneFrame;

	if (md3Tags)
		delete[] md3Tags;
*/

⌨️ 快捷键说明

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