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

📄 md3.cpp

📁 direct3d游戏编程基础源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	for(int j = 0; j < iNumMeshes; j++)
	{
			delete[] pMd3Meshes[j].pTexNames;
			delete[] pMd3Meshes[j].pTriangles;
			delete[] pMd3Meshes[j].pfTextureCoords;
			delete[] pMd3Meshes[j].vMeshFrames;
	}

	if (iNumMeshes)
		delete[] pMd3Meshes;
}

//-----------------------------------------------------------------------------
// Name: InitDeviceObjects(LPDIRECT3DDEVICE8 lpD3Ddevice)
// Desc: Handles the vertex buffer and textures stuff
//-----------------------------------------------------------------------------
void CMD3Model::InitDeviceObjects(LPDIRECT3DDEVICE8 lpD3Ddevice)
{
	CreateVB(lpD3Ddevice);
	CreateTextures(lpD3Ddevice);
}

//-----------------------------------------------------------------------------
// Name: InitDeviceObjects(LPDIRECT3DDEVICE8 lpD3Ddevice)
// Desc: Handles the vertex buffer and textures stuff
//-----------------------------------------------------------------------------
void CMD3Model::DeleteDeviceObjects()
{
	DeleteVB();
	DeleteTextures();
}

//----------------------------------------------------------------
// Name: CreateVB()
// Desc: Creates vertex buffer with all meshframes one 
//       after another.
//----------------------------------------------------------------
void CMD3Model::CreateVB(LPDIRECT3DDEVICE8 lpD3Ddevice)
{
	DWORD m_dwNumofVertices = 0;
	int iVertexNum;

	// get the indices number to provide the size of the vertex buffer
	for(int k = 0; k < iNumMeshes; k++)
			for(int i = 0; i < pMd3Meshes[k].iNumTriangles; i++)
				for(int j = 0; j < 3; j++)
				m_dwNumofVertices++;

	// create vertex buffer
    lpD3Ddevice->CreateVertexBuffer(m_dwNumofVertices * sizeof(MD3VERTEXBUFFERSTRUCT),
                                    D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED,
                                    &m_pVB);
    MD3VERTEXBUFFERSTRUCT* v;
	m_dwNumofVertices = 0;
	int iAnimationFrameNum = 0;

    m_pVB->Lock( 0, 0, (BYTE**)&v, 0 );
	for(k = 0; k < iNumMeshes; k++)
	{
		for(int i = 0; i < pMd3Meshes[k].iNumTriangles; i++)
		{
			for(int j = 0; j < 3; j++)
			{
				iVertexNum = pMd3Meshes[k].pTriangles[i][j];

				v[m_dwNumofVertices].p= D3DXVECTOR3(
				   pMd3Meshes[k].vMeshFrames[iAnimationFrameNum][iVertexNum].x,	
  				   pMd3Meshes[k].vMeshFrames[iAnimationFrameNum][iVertexNum].y, 
				   pMd3Meshes[k].vMeshFrames[iAnimationFrameNum][iVertexNum].z);
				v[m_dwNumofVertices].tu = pMd3Meshes[k].pfTextureCoords[iVertexNum].u;
				v[m_dwNumofVertices].tv = pMd3Meshes[k].pfTextureCoords[iVertexNum].v;
				m_dwNumofVertices++;
			}
		}
	}
	m_pVB->Unlock();

}

//-----------------------------------------------------------------------------
// Name: DeleteVB()
// Desc: Destroys the vertex buffer for the model
//-----------------------------------------------------------------------------
void CMD3Model::DeleteVB()
{
	if (m_pVB != NULL)
		SAFE_RELEASE( m_pVB );
}

//-----------------------------------------------------------------------------
// Name: CreateTextures(LPDIRECT3DDEVICE8 lpD3Ddevice)
// Desc: Creates all the textures of a mesh
// How to open a texture for a *.md3 file:
//	1. The number and the path of the textures is stored in 
//	   the *.md3 file. The number of provided textures is stored on 
//	   a per mesh basis. 
//	2. The name of the texture should be provided in the *.skin 
//	   files. Try to get it.
//	3. If there's no texture entry in the *.md3 file and it exists 
//	   no *.skin file, try to catch the texture by searching through 
//	   the directory, where the *.md3 file is located. 
//	4. If there's no texture entry in the *.md3 file, a *.skin file
//	   is non-existance and the texture is not located in the directory
//	   where the *.md3 file is located ... try to talk to your graphic 
//	   artist :-)
//-----------------------------------------------------------------------------
void CMD3Model::CreateTextures(LPDIRECT3DDEVICE8 lpD3Ddevice)
{
	// create and open log file
	LogFile = fopen("md3 textures.txt","w");

	fprintf(LogFile,"--- Textures --- \n");
	fprintf(LogFile,"Number of meshes: %d\n", iNumMeshes);

	for(int j = 0; j < iNumMeshes; j++)
	{
		pMd3Meshes[j].pTexturesInterfaces = 
			new LPDIRECT3DTEXTURE8[pMd3Meshes[j].iNumTextures];

		fprintf(LogFile,"Number of textures in mesh %s: %d\n", 
				pMd3Meshes[j].cName ,pMd3Meshes[j].iNumTextures);

		// load and create pMd3Meshes->iNumTextures
		for (int i = 0; i < pMd3Meshes[j].iNumTextures; i++)
		{
			// temporary: holds the texture path, which is stored in *.md3
			CHAR *cTempTexturePath;
			
			// to store the texture name f.e. plasma.tga without path
			// because D3DTextr_CreateTextureFromFile() only accepts
			// textures this way
			CHAR *cTextureName;
		
			cTempTexturePath = pMd3Meshes[j].pTexNames[i];
			int length=strlen(cTempTexturePath);

			// hardcode alert !!
			// models/players/ == 15 chars
			// if the texture path is shorter than 15 chars, there isn't
			// any entry in the *.md3 file at all ... 
			if (length > 15) 
			{
				int count = 0;
				int iTempLength = length;

				// count down until /
				while (cTempTexturePath[iTempLength--] != '/')
					count++;

				// allocate memory for the texture name
				cTextureName = new CHAR[count];

				// copy the texture name
				while (count--)
				{
					cTextureName[count] = cTempTexturePath[length];
					length--;
				}

				// show the used texture path and texture name 
				fprintf(LogFile,"texture path: %s\n", cTempTexturePath);
				fprintf(LogFile,"texture name: %s\n\n", cTextureName);

				if( FAILED( D3DXCreateTextureFromFile(lpD3Ddevice, 
											cTextureName, 
											&pMd3Meshes[j].pTexturesInterfaces[i])))
				{
					fprintf(LogFile,"D3DXCreateTextureFromFile: could not create texture: %s\n", cTextureName);
	
					pMd3Meshes[j].iNumTextures = 0;
					pMd3Meshes[j].pTexturesInterfaces[i] = 0;
				}
				delete[] cTextureName;
			}
			/* else 
				1. open skin file, read tex name and load texture as above
				2. try to catch the texture from the directory, where the md3 file
				resides, with the name of this file as tex name.
			*/
			else
			{
				pMd3Meshes[j].iNumTextures = 0;
				pMd3Meshes[j].pTexturesInterfaces[i] = 0;
			}

		}
  }
	// close the LogFile
	fclose(LogFile);
}

//-----------------------------------------------------------------------------
// Name: DestroyTextures()
// Desc: Destroys the textures created by CreateTextures()
//-----------------------------------------------------------------------------
void CMD3Model::DeleteTextures()
{
	for(int j = 0; j < iNumMeshes; j++)
	{
	  // destroy textures
	  for (int i = 0; i < pMd3Meshes[j].iNumTextures; i++)
	  {
		SAFE_RELEASE(pMd3Meshes[j].pTexturesInterfaces[i]);
	  }
	}
}

//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Renders the model
//-----------------------------------------------------------------------------
void CMD3Model::Render(LPDIRECT3DDEVICE8 lpD3Ddevice)
{
	for(int k = 0; k < iNumMeshes; k++)
	{
		DWORD dwStartVertex;
		if (k != 0)
		  dwStartVertex += pMd3Meshes[k-1].iNumTriangles * 3;
		else 
		  dwStartVertex = 0;

		if (pMd3Meshes[k].iNumTextures > 0)
		{
			for (int i = 0; i < pMd3Meshes[k].iNumTextures; i++)
			{
			lpD3Ddevice->SetTexture( 0, pMd3Meshes[k].pTexturesInterfaces[i]);
			lpD3Ddevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
			lpD3Ddevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );

			lpD3Ddevice->SetVertexShader( FVF_MD3VERTEXBUFFERSTRUCT);
			lpD3Ddevice->SetStreamSource( 0, m_pVB, sizeof(MD3VERTEXBUFFERSTRUCT) );
			lpD3Ddevice->DrawPrimitive( D3DPT_TRIANGLELIST, dwStartVertex, pMd3Meshes[k].iNumTriangles);
			}
		}
		else // just in case there are no textures in the mesh
		{
			lpD3Ddevice->SetTexture( 0, 0);

			lpD3Ddevice->SetVertexShader( FVF_MD3VERTEXBUFFERSTRUCT);
			lpD3Ddevice->SetStreamSource( 0, m_pVB, sizeof(MD3VERTEXBUFFERSTRUCT) );
			lpD3Ddevice->DrawPrimitive( D3DPT_TRIANGLELIST, dwStartVertex, pMd3Meshes[k].iNumTriangles);
		}
	}
}

//----------------------------------------------------------------------------
// Name: ReadLong()
// Desc: reads a long from FILE
//----------------------------------------------------------------------------
long CMD3Model::ReadLong(FILE* File)
{
	unsigned char x[4];
	fread(x, sizeof(x), 1, File);
	return (x[3] << 24) + (x[2] << 16) + (x[1] << 8) + x[0];
}

//----------------------------------------------------------------------------
// Name: ReadShort()
// Desc: reads a short from FILE
//----------------------------------------------------------------------------
short CMD3Model::ReadShort(FILE* File)
{
	unsigned char x[2];
	fread(x, sizeof(x), 1, File);
	return (x[1] << 8) + x[0];
}

//----------------------------------------------------------------------------
// Name: ReadFloat()
// Desc: reads a float from FILE
//----------------------------------------------------------------------------
float CMD3Model::ReadFloat(FILE* File)
{
	unsigned char x[4];
	unsigned long l;
	fread(x, sizeof(x), 1, File);
	l = (x[3] << 24) + (x[2] << 16) + (x[1] << 8) + x[0];
	return *(float *)&l;
}

⌨️ 快捷键说明

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