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

📄 tomsd3dlib.h

📁 游戏编程精粹2第四章源码
💻 H
📖 第 1 页 / 共 2 页
字号:
/* Copyright (C) Tom Forsyth, 2001. 
 * All rights reserved worldwide.
 *
 * This software is provided "as is" without express or implied
 * warranties. You may freely copy and compile this source into
 * applications you distribute provided that the copyright text
 * below is included in the resulting source code, for example:
 * "Portions Copyright (C) Tom Forsyth, 2001"
 */
// Useful D3D-related stuff.

#ifndef TOMSD3DLIB_INCLUDED
#define TOMSD3DLIB_INCLUDED



#ifndef DXVERSION
#error Please define DXVERSION to be 7 or 8 or something.
#endif




#if DXVERSION==7
#define DIRECT3D_VERSION 0x0700
#define DIRECTINPUT_VERSION 0x0700
#elif DXVERSION==8
#define DIRECT3D_VERSION 0x0800
// Let the header file tell you what the latest version is.
//#define DIRECTINPUT_VERSION 0x0800
#else
#error Define DXVERSION to be 7 or 8. No other versions supported ATM.
#endif

#define STRICT
#define D3D_OVERLOADS
#include <windows.h>
#include <math.h>
#include <stdio.h>
#include <dinput.h>
//#include "D3DApp.h"
//#include "D3DTextr.h"
#include "DXUtil.h"
//#include "D3DMath.h"
//#include "D3DFile.h"

#if DXVERSION==8
#include "D3D8types.h"
#include "D3dx8core.h"
#else
#include "D3Dtypes.h"
#endif

#include "TomsLib.h"
#include "TomsD3DLib.h"




//#define TRACE sizeof


#if DXVERSION==7

#define LPDIRECTDRAWSURFACEn LPDIRECTDRAWSURFACE7
#define LPDIRECTDRAWn LPDIRECTDRAW7
#define LPDIRECT3DDEVICEn LPDIRECT3DDEVICE7
#define D3DDEVICEDESCn D3DDEVICEDESC7
#define DDSURFACEDESCn DDSURFACEDESC2

#elif DXVERSION==8

#define LPDIRECTDRAWSURFACEn LPDIRECT3DSURFACE8
#define LPDIRECTDRAWn IDontExistAnyMore
#define LPDIRECT3DDEVICEn LPDIRECT3DDEVICE8
#define D3DDEVICEDESCn D3DCAPS8
// DDSURFACEDESC has been split up into stuff like D3DLOCKED_RECT and D3DSURFACE_DESC
#define DDSURFACEDESCn IDontExistAnyMoreInAUsefulWay

#else

#error Define DXVERSION to be 7 or 8. No other versions supported ATM.

#endif



#if DXVERSION==7
// Initialise a D3D-style object
template <class S> void D3DInit ( S &thing )
{
	ZeroMemory ( &thing, sizeof ( S ) );
	thing.dwSize = sizeof ( S );
}
#endif //#if DXVERSION==7


// Check the ref count of a D3D object.
// Only legal with debug runtime.
template <class S> int CheckD3DRefCount ( S &thing )
{
	thing->AddRef();
	return ( thing->Release() );
}





// A struct to handle 4-component texture coords.
struct D3DTEXCOORD
{
	float		fU;
	float		fV;
	float		fW;
	float		fT;
};



// A generalised FVF semi-smart pointer.
class MyFVFPointer
{
private:
	DWORD		dwFVFType;				// The D3D format.
	// These are byte offsets from the start of the vertex.
	// If an offset is -1, that item is not present.
	int			iOffsetPosition;
	int			iOffsetRHW;
	int			iOffsetBlendWeights;
	int			iOffsetNormal;
	int			iOffsetPsize;
	int			iOffsetColour[2];		// AKA "diffuse" and "specular"
	int			iOffsetTexCoord[8];

	int			iNumBlendWeights;		// Number of blend weights.
	int			iNumTexCoords;		// Number of texture sets.
	int			iSizeOfVertex;			// Size in bytes.

	void		*pvCurrentVert;			// The vertex this is currently pointing to.

public:

	// Sets the FVF type
	void		SetFVFType ( DWORD dwType )
	{
		int i;

		// Initialise everything.
		dwFVFType = dwType;
		iOffsetPosition = -1;
		iOffsetRHW = -1;
		iOffsetBlendWeights = -1;
		iOffsetNormal = -1;
		iOffsetPsize = -1;
		iOffsetColour[0] = -1;
		iOffsetColour[1] = -1;
		iSizeOfVertex = 0;
		iNumBlendWeights = 0;
		iNumTexCoords = 0;
		for ( i = 0; i < 8; i++ )
		{
			iOffsetTexCoord[i] = -1;
		}

		if ( dwType == 0 )
		{
			// NULL type - not set up yet.
			return;
		}

		// Now find the components that are present.
		int iOffset = 0;

		// Bits 1,2,3 all code for a position type.
		switch ( dwType & D3DFVF_POSITION_MASK )
		{
		case 0:
			// Invalid.
			ASSERT ( FALSE );
			break;
		case D3DFVF_XYZ:
			iOffsetPosition = iOffset;
			iOffset += 3 * sizeof ( float );
			iNumBlendWeights = 0;
			break;
		case D3DFVF_XYZRHW:
			ASSERT ( ( dwType & D3DFVF_NORMAL ) == 0 );
			iOffsetPosition = iOffset;
			iOffset += 3 * sizeof ( float );
			iOffsetRHW = iOffset;
			iOffset += 1 * sizeof ( float );
			iNumBlendWeights = 0;
			break;
		case D3DFVF_XYZB1:
			iOffsetPosition = iOffset;
			iOffset += 3 * sizeof ( float );
			iOffsetBlendWeights = iOffset;
			iNumBlendWeights = 1;
			iOffset += iNumBlendWeights * sizeof ( float );
			break;
		case D3DFVF_XYZB2:
			iOffsetPosition = iOffset;
			iOffset += 3 * sizeof ( float );
			iOffsetBlendWeights = iOffset;
			iNumBlendWeights = 2;
			iOffset += iNumBlendWeights * sizeof ( float );
			break;
		case D3DFVF_XYZB3:
			iOffsetPosition = iOffset;
			iOffset += 3 * sizeof ( float );
			iOffsetBlendWeights = iOffset;
			iNumBlendWeights = 3;
			iOffset += iNumBlendWeights * sizeof ( float );
			break;
		case D3DFVF_XYZB4:
			iOffsetPosition = iOffset;
			iOffset += 3 * sizeof ( float );
			iOffsetBlendWeights = iOffset;
			iNumBlendWeights = 4;
			iOffset += iNumBlendWeights * sizeof ( float );
			break;
		case D3DFVF_XYZB5:
			iOffsetPosition = iOffset;
			iOffset += 3 * sizeof ( float );
			iOffsetBlendWeights = iOffset;
			iNumBlendWeights = 5;
			iOffset += iNumBlendWeights * sizeof ( float );
			break;
		}

#if DXVERSION==7
		if ( dwType & D3DFVF_RESERVED1 )
		{
			// A special-case D3DLVERTEX. Make sure it's correct.
			ASSERT ( dwType == D3DFVF_LVERTEX );
			// No offset to mark, just a DWORD to skip.
			iOffset += sizeof ( float );
		}
#endif

		if ( dwType & D3DFVF_NORMAL )
		{
			iOffsetNormal = iOffset;
			iOffset += 3 * sizeof ( float );
		}
#if DXVERSION==8
		if ( dwType & D3DFVF_PSIZE )
		{
			iOffsetPsize = iOffset;
			iOffset += 1 * sizeof ( float );
		}
#endif
		if ( dwType & D3DFVF_DIFFUSE )
		{
			iOffsetColour[0] = iOffset;
			iOffset += 1 * sizeof ( DWORD );
		}
		if ( dwType & D3DFVF_SPECULAR )
		{
			iOffsetColour[1] = iOffset;
			iOffset += 1 * sizeof ( DWORD );
		}

		// Now do the textures.
		// Slight hardwiring because the D3D headers don't give quite enough info.
#if D3DFVF_TEXCOORDSIZE1(3) != ( 0x3 << ( 3 * 2 + 16 ) )
#error Hardwired FVF format flags do not match headers.
#endif
		iNumTexCoords = ( dwType & D3DFVF_TEXCOUNT_MASK ) >> D3DFVF_TEXCOUNT_SHIFT;
		DWORD dwTemp = dwType >> 16;
		for ( i = 0; i < iNumTexCoords; i++ )
		{
			// Set up the offsets.
			switch ( dwTemp & 0x3 )
			{
			case D3DFVF_TEXTUREFORMAT1:
				// 1 component.
				iOffsetTexCoord[i] = iOffset;
				iOffset += 1 * sizeof ( float );
				break;
			case D3DFVF_TEXTUREFORMAT2:
				// 1 component.
				iOffsetTexCoord[i] = iOffset;
				iOffset += 2 * sizeof ( float );
				break;
			case D3DFVF_TEXTUREFORMAT3:
				// 1 component.
				iOffsetTexCoord[i] = iOffset;
				iOffset += 3 * sizeof ( float );
				break;
			case D3DFVF_TEXTUREFORMAT4:
				// 1 component.
				iOffsetTexCoord[i] = iOffset;
				iOffset += 4 * sizeof ( float );
				break;
			default:
				// The maths fell over somewhere.
				ASSERT ( FALSE );
				break;
			}
			dwTemp >>= 2;
		}

		// The size of the whole vertex.
		iSizeOfVertex = iOffset;
#if DXVERSION==8
		// D3DX is almost useful!
		ASSERT ( (unsigned)iSizeOfVertex == D3DXGetFVFVertexSize ( dwFVFType ) );
#endif
	}

	// Gets the FVF type
	DWORD		GetFVFType ( void )
	{
		return dwFVFType;
	}

	// Assignment - can only be done between FVF pointers of the same type.
	MyFVFPointer & operator= ( const MyFVFPointer &other )
	{
		ASSERT ( dwFVFType == other.dwFVFType );
		pvCurrentVert = other.pvCurrentVert;
		ASSERT ( 0 == memcmp ( (void *)this, (void *)&other, sizeof ( MyFVFPointer ) ) );
		return ( *this );
	}

	// Assignment from a void*
	MyFVFPointer & operator= ( void *ptr )
	{
		// Can only assign NULL to an untyped vertex.
		ASSERT ( ( dwFVFType != 0 ) || ( ptr == NULL ) );
		pvCurrentVert = ptr;
		return ( *this );
	}

	// Comparison - can only be done between FVF pointers of the same type.
	bool operator== ( const MyFVFPointer &other )
	{
		ASSERT ( dwFVFType == other.dwFVFType );
		if ( pvCurrentVert == other.pvCurrentVert )
		{
			ASSERT ( 0 == memcmp ( (void *)this, (void *)&other, sizeof ( MyFVFPointer ) ) );
			return ( TRUE );
		}
		else
		{
			return ( FALSE );
		}
	}

	// Constructor.
	MyFVFPointer ( DWORD dwType = 0 )
	{
		SetFVFType ( dwType );
	}

	// Constructor from type & pointer.
	MyFVFPointer ( DWORD dwType, void *ptr )
	{
		// Just a straight memberwise copy.
		SetFVFType ( dwType );
		pvCurrentVert = ptr;
	}

	// Copy constructors.
	MyFVFPointer ( MyFVFPointer &other )
	{
		// Just a straight memberwise copy.
		memcpy ( (void *)this, (void *)&other, sizeof ( MyFVFPointer ) );
	}


	// Destruction.
	~MyFVFPointer ( void ) {}


	// Gets the FVF size in bytes
	DWORD		GetFVFSize ( void )
	{
		return ( iSizeOfVertex );
	}

	// Set current vertex base
	void		SetCurVertex ( void *ptr )
	{
		ASSERT ( dwFVFType != 0 );
		pvCurrentVert = ptr;
	}
	// Get current vertex base
	void		*GetCurVertex ( void )
	{
		return ( pvCurrentVert );
	}
	// Move the vertex to the next one.
	void		NextVertex ( void )
	{
		pvCurrentVert = GetVertex ( 1 );
	}
	// Move the vertex to the previous one.
	void		PrevVertex ( void )
	{
		pvCurrentVert = GetVertex ( -1 );
	}
	// Indexed offset. Does not affect the current pointer.
	// iOffset is signed - can be -ve or +ve.
	void		*GetVertex ( int iOffset )
	{
		return ( (void *)( (char *)pvCurrentVert + iSizeOfVertex * iOffset ) );
	}

	// Allocate some vertices.
	// Return is TRUE on success.
	bool		AllocVertices ( int iNumVertices )
	{
		ASSERT ( dwFVFType != 0 );
		ASSERT ( iSizeOfVertex > 0 );
		pvCurrentVert = malloc ( iNumVertices * iSizeOfVertex );
		if ( pvCurrentVert != NULL )
		{
			return ( TRUE );
		}
		else
		{
			return ( FALSE );
		}
	}

⌨️ 快捷键说明

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