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

📄 tomsd3dlib.h

📁 游戏编程精粹2第四章源码
💻 H
📖 第 1 页 / 共 2 页
字号:
	// Rellocate some vertices.
	// Return is TRUE on success.
	bool		ReallocVertices ( int iNumVertices )
	{
		ASSERT ( dwFVFType != 0 );
		ASSERT ( iSizeOfVertex > 0 );
		pvCurrentVert = realloc ( pvCurrentVert, iNumVertices * iSizeOfVertex );
		if ( pvCurrentVert != NULL )
		{
			return ( TRUE );
		}
		else
		{
			return ( FALSE );
		}
	}

	// Free the vertices.
	void		FreeVertices ( void )
	{
		if ( pvCurrentVert != NULL )
		{
			free ( pvCurrentVert );
			pvCurrentVert = NULL;
		}
	}

	// Individual vertex component pointer getters.
	D3DVECTOR	&Position ( void )
	{
		ASSERT ( iOffsetPosition != -1 );
		return ( *(D3DVECTOR *)( (char *)pvCurrentVert + iOffsetPosition ) );
	}
	float		&X ( void )
	{
		ASSERT ( iOffsetPosition != -1 );
		return ( *(float *)( (char *)pvCurrentVert + iOffsetPosition + 0 * sizeof ( float ) ) );
	}
	float		&Y ( void )
	{
		ASSERT ( iOffsetPosition != -1 );
		return ( *(float *)( (char *)pvCurrentVert + iOffsetPosition + 1 * sizeof ( float ) ) );
	}
	float		&Z ( void )
	{
		ASSERT ( iOffsetPosition != -1 );
		return ( *(float *)( (char *)pvCurrentVert + iOffsetPosition + 2 * sizeof ( float ) ) );
	}
	float		&RHW ( void )
	{
		ASSERT ( iOffsetRHW != -1 );
		return ( *(float *)( (char *)pvCurrentVert + iOffsetRHW ) );
	}
	float		&BlendWeight ( int iWeightNum )
	{
		ASSERT ( iOffsetBlendWeights != -1 );
		ASSERT ( iWeightNum < iNumBlendWeights );
#if DXVERSION==8
		// The last weight isn't a weight, it's indices, when LASTBETA_UBYTE4 is set.
		ASSERT ( ( ( dwFVFType & D3DFVF_LASTBETA_UBYTE4 ) == 0 ) || ( iWeightNum < iNumBlendWeights - 1 ) );
#endif
		return ( *(float *)( (char *)pvCurrentVert + iOffsetBlendWeights + iWeightNum * sizeof ( float ) ) );
	}
#if DXVERSION==8
	DWORD		&BlendIndices ( void )
	{
		ASSERT ( iOffsetBlendWeights != -1 );
		ASSERT ( iNumBlendWeights > 0 );
		ASSERT ( ( dwFVFType & D3DFVF_LASTBETA_UBYTE4 ) != 0 );
		// Last "blend weight" is the packed indices.
		return ( *(DWORD *)( (char *)pvCurrentVert + iOffsetBlendWeights + ( iNumBlendWeights - 1 ) * sizeof ( float ) ) );
	}
	BYTE		&BlendIndex ( int iIndexNum )
	{
		ASSERT ( iOffsetBlendWeights != -1 );
		ASSERT ( iNumBlendWeights > 0 );
		ASSERT ( ( dwFVFType & D3DFVF_LASTBETA_UBYTE4 ) != 0 );
		// Last "blend weight" is the packed indices.
		ASSERT ( iIndexNum < 4 );
		return ( *(BYTE *)( (char *)pvCurrentVert + iOffsetBlendWeights + iIndexNum + ( iNumBlendWeights - 1 ) * sizeof ( float ) ) );
	}
#endif
	D3DVECTOR	&Normal ( void )
	{
		ASSERT ( iOffsetNormal != -1 );
		return ( *(D3DVECTOR *)( (char *)pvCurrentVert + iOffsetNormal ) );
	}
	float		&NX ( void )
	{
		ASSERT ( iOffsetNormal != -1 );
		return ( *(float *)( (char *)pvCurrentVert + iOffsetNormal + 0 * sizeof ( float ) ) );
	}
	float		&NY ( void )
	{
		ASSERT ( iOffsetNormal != -1 );
		return ( *(float *)( (char *)pvCurrentVert + iOffsetNormal + 1 * sizeof ( float ) ) );
	}
	float		&NZ ( void )
	{
		ASSERT ( iOffsetNormal != -1 );
		return ( *(float *)( (char *)pvCurrentVert + iOffsetNormal + 2 * sizeof ( float ) ) );
	}
	float		&Psize ( void )
	{
		ASSERT ( iOffsetPsize != -1 );
		return ( *(float *)( (char *)pvCurrentVert + iOffsetPsize ) );
	}
	DWORD		&Colour ( int iColourNum )		// Counted from 0.
	{
		// Only two colours at max ATM.
		ASSERT ( iColourNum < 2 );
		ASSERT ( iOffsetColour[iColourNum] != -1 );
		return ( *(DWORD *)( (char *)pvCurrentVert + iOffsetColour[iColourNum] ) );
	}
	DWORD		&Diff ( void )
	{
		return ( Colour ( 0 ) );
	}
	DWORD		&Spec ( void )
	{
		return ( Colour ( 1 ) );
	}
	D3DTEXCOORD	&TexCoord ( int iTexCoordNum )	// Counted from 0.
	{
		ASSERT ( iTexCoordNum < iNumTexCoords );
		ASSERT ( iOffsetTexCoord[iTexCoordNum] != -1 );
		return ( *(D3DTEXCOORD *)( (char *)pvCurrentVert + iOffsetTexCoord[iTexCoordNum] ) );
	}
	float		&U0 ( void )
	{
		return ( TexCoord(0).fU );
	}
	float		&V0 ( void )
	{
		return ( TexCoord(0).fV );
	}
	float		&U1 ( void )
	{
		return ( TexCoord(1).fU );
	}
	float		&V1 ( void )
	{
		return ( TexCoord(1).fV );
	}


	// Now some more nice overloaded operators.

	// Conversion to void*
	operator void*()
	{
		return ( (void *)pvCurrentVert );
	}

	// Subscript - may be positive or negative.
	// NOTE! This is awesomely inefficient unless the compiler is smart. :-(
	MyFVFPointer operator[] ( const int iOffset )
	{
		MyFVFPointer ret = *this;
		ret.pvCurrentVert = GetVertex ( iOffset );
		return ret;
	}

	// Addition.
	MyFVFPointer &operator+= ( const int iOffset )
	{
		pvCurrentVert = GetVertex ( iOffset );
		return ( *this );
	}

	// Subtraction.
	MyFVFPointer &operator-= ( const int iOffset )
	{
		pvCurrentVert = GetVertex ( -iOffset );
		return ( *this );
	}

	// Next (prefix).
	MyFVFPointer &operator++ ( void )
	{
		pvCurrentVert = GetVertex ( 1 );
		return ( *this );
	}

	// Prev (prefix).
	MyFVFPointer &operator-- ( void )
	{
		pvCurrentVert = GetVertex ( -1 );
		return ( *this );
	}

};





// Fill the matViewport matrix from the
// viewport data in vpViewport.
// Very useful for concatenating the whole
// vertex transform pipeline.
// TomF.
#if DXVERSION==8
static void MakeMatrixFromViewport ( D3DMATRIX &matViewport, D3DVIEWPORT8 &vpViewport )
#else
static void MakeMatrixFromViewport ( D3DMATRIX &matViewport, D3DVIEWPORT7 &vpViewport )
#endif
{

#if DXVERSION==8
	float fHalfWidth = vpViewport.Width * 0.5f;
	float fHalfHeight = vpViewport.Height * -0.5f;
#else
	float fHalfWidth = vpViewport.dwWidth * 0.5f;
	float fHalfHeight = vpViewport.dwHeight * -0.5f;
#endif

	matViewport._11 = fHalfWidth;
	matViewport._12 = 0.0f;
	matViewport._13 = 0.0f;
	matViewport._14 = 0.0f;

	matViewport._21 = 0.0f;
	matViewport._22 = fHalfHeight;
	matViewport._23 = 0.0f;
	matViewport._24 = 0.0f;

#if DXVERSION==8
	matViewport._31 = 0.0f;
	matViewport._32 = 0.0f;
	matViewport._33 = vpViewport.MaxZ - vpViewport.MinZ;
	matViewport._34 = 0.0f;

	matViewport._41 = vpViewport.X + fHalfWidth;
	matViewport._42 = vpViewport.Y - fHalfHeight;
	matViewport._43 = vpViewport.MinZ;
	matViewport._44 = 1.0f;
#else
	matViewport._31 = 0.0f;
	matViewport._32 = 0.0f;
	matViewport._33 = vpViewport.dvMaxZ - vpViewport.dvMinZ;
	matViewport._34 = 0.0f;

	matViewport._41 = vpViewport.dwX + fHalfWidth;
	matViewport._42 = vpViewport.dwY - fHalfHeight;
	matViewport._43 = vpViewport.dvMinZ;
	matViewport._44 = 1.0f;
#endif
}




// Multi-format support. Not very fast, but useful. TomF.

struct FloatColour
{
	float fA, fR, fG, fB;

	FloatColour operator+( FloatColour fc )
	{
		fc.fA += this->fA;
		fc.fR += this->fR;
		fc.fG += this->fG;
		fc.fB += this->fB;
		return fc;
	}

	FloatColour operator*( float fScale )
	{
		FloatColour fc;
		fc.fA = this->fA * fScale;
		fc.fR = this->fR * fScale;
		fc.fG = this->fG * fScale;
		fc.fB = this->fB * fScale;
		return fc;
	}
};



#if DXVERSION>=8

// Fake up the essential DDPIXELFORMAT data from DX8 FORMAT info.
struct DX8PIXELFORMAT
{
	DWORD dwFlags;
	DWORD dwRBitMask;
	DWORD dwGBitMask;
	DWORD dwBBitMask;
	DWORD dwRGBAlphaBitMask;
};

// Make these up, as they are not in DX8.
#define DDPF_RGB 0x1
#define DDPF_ALPHAPIXELS 0x2

#endif //#if DXVERSION==8



#if DXVERSION>=8
static FloatColour ConvertPixelDataToFloat ( DWORD dwSrc, const DX8PIXELFORMAT &ddpfSrc )
#else
static FloatColour ConvertPixelDataToFloat ( DWORD dwSrc, const DDPIXELFORMAT &ddpfSrc )
#endif
{
	FloatColour fc;
	ASSERT ( ( ddpfSrc.dwFlags & DDPF_RGB ) != 0 );
	fc.fR = ( (float)( dwSrc & ddpfSrc.dwRBitMask        ) / (float)ddpfSrc.dwRBitMask );
	fc.fG = ( (float)( dwSrc & ddpfSrc.dwGBitMask        ) / (float)ddpfSrc.dwGBitMask );
	fc.fB = ( (float)( dwSrc & ddpfSrc.dwBBitMask        ) / (float)ddpfSrc.dwBBitMask );
	fc.fA = ( (float)( dwSrc & ddpfSrc.dwRGBAlphaBitMask ) / (float)ddpfSrc.dwRGBAlphaBitMask );
	return fc;
}

#if DXVERSION>=8
static DWORD ConvertFloatToPixelData ( const FloatColour &fc, const DX8PIXELFORMAT &ddpfDst )
#else
static DWORD ConvertFloatToPixelData ( const FloatColour &fc, const DDPIXELFORMAT &ddpfDst )
#endif
{
	ASSERT ( ( ddpfDst.dwFlags & DDPF_RGB ) != 0 );
	DWORD dwRes = 0;
	dwRes |= ( (DWORD)( fc.fR * (float)( ddpfDst.dwRBitMask        ) ) & ddpfDst.dwRBitMask );
	dwRes |= ( (DWORD)( fc.fG * (float)( ddpfDst.dwGBitMask        ) ) & ddpfDst.dwGBitMask );
	dwRes |= ( (DWORD)( fc.fB * (float)( ddpfDst.dwBBitMask        ) ) & ddpfDst.dwBBitMask );
	dwRes |= ( (DWORD)( fc.fA * (float)( ddpfDst.dwRGBAlphaBitMask ) ) & ddpfDst.dwRGBAlphaBitMask );
	return dwRes;
}


// Convert between two different formats. Both must be RGB.
#if DXVERSION>=8
static DWORD ConvertPixelData ( const DX8PIXELFORMAT &ddpfDst, DWORD dwSrc, const DX8PIXELFORMAT &ddpfSrc )
#else
static DWORD ConvertPixelData ( const DDPIXELFORMAT &ddpfDst, DWORD dwSrc, const DDPIXELFORMAT &ddpfSrc )
#endif
{
	FloatColour fc = ConvertPixelDataToFloat ( dwSrc, ddpfSrc );
	return ConvertFloatToPixelData ( fc, ddpfDst );
}


#if DXVERSION>=8
static const DX8PIXELFORMAT ddpfR8G8B8A8 = {
	DDPF_ALPHAPIXELS | DDPF_RGB,	// dwFlags
	0x00FF0000,						// dwRBitMask,
	0x0000FF00,						// dwGBitMask,
	0x000000FF,						// dwBBitMask,
	0xFF000000						// dwRGBAlphaBitMask
};
#else
static const DDPIXELFORMAT ddpfR8G8B8A8 = {
	sizeof ( DDPIXELFORMAT ),		// dwSize
	DDPF_ALPHAPIXELS | DDPF_RGB,	// dwFlags
	0,								// dwFourCC
	32,								// dwRGBBitCount,
	0x00FF0000,						// dwRBitMask,
	0x0000FF00,						// dwGBitMask,
	0x000000FF,						// dwBBitMask,
	0xFF000000						// dwRGBAlphaBitMask
};
#endif


// Convert from the given pixel format to A8R8G8B8
#if DXVERSION>=8
static DWORD ConvertPixelToA8R8G8B8 ( const DX8PIXELFORMAT &ddpf, DWORD dwSrc )
#else
static DWORD ConvertPixelToA8R8G8B8 ( const DDPIXELFORMAT &ddpf, DWORD dwSrc )
#endif
{
	return ConvertPixelData ( ddpfR8G8B8A8, dwSrc, ddpf );
}

// Convert from A8R8G8B8 to the given pixel format.
#if DXVERSION>=8
static DWORD ConvertPixelFromA8R8G8B8 ( const DX8PIXELFORMAT &ddpf, DWORD dwSrc )
#else
static DWORD ConvertPixelFromA8R8G8B8 ( const DDPIXELFORMAT &ddpf, DWORD dwSrc )
#endif
{
	return ConvertPixelData ( ddpf, dwSrc, ddpfR8G8B8A8 );
}



// An attempt at a "universal" blitter that handles any texture formats,
// and handles different filtering modes. Adapt as needed.

// Filter types.
enum UblitFilter
{
	UBLIT_FILTER_POINT,
	UBLIT_FILTER_BILINEAR,
};



#if DXVERSION==7
// Returns TRUE if successful, FALSE otherwise.
BOOL UniversalBlit ( LPDIRECTDRAWSURFACEn pddsSrc, LPDIRECTDRAWSURFACEn pddsDst,
							UblitFilter ufMin = UBLIT_FILTER_POINT,
							UblitFilter ufMag = UBLIT_FILTER_POINT );
#endif



#if DXVERSION==7
// Given a locked DD surface and its surface desc, returns the pixel data at the given coords.
// Clamps to the surface's size in X and Y.
DWORD SamplePoint ( int iX, int iY, DDSURFACEDESC2 &ddsdSrc );
#else
// Given a locked DD surface and its surface desc, returns the pixel data at the given coords.
// Clamps to the surface's size in X and Y.
DWORD SamplePoint ( int iX, int iY, int iBitsPerPixel, D3DSURFACE_DESC &ddsdSrc, D3DLOCKED_RECT &locked_rect );
#endif




#endif //#ifndef TOMSD3DLIB_INCLUDED



⌨️ 快捷键说明

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