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

📄 tomsd3dlib.cpp

📁 游戏编程精粹2第四章源码
💻 CPP
字号:
/* 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"
 */


#include "TomsD3DLib.h"




// Used by the universal blit.
// By TomF.
#if DXVERSION==7
DWORD SamplePoint ( int iX, int iY, DDSURFACEDESC2 &ddsdSrc )
#else
DWORD SamplePoint ( int iX, int iY, int iBitsPerPixel, D3DSURFACE_DESC &ddsdSrc, D3DLOCKED_RECT &locked_rect )
#endif
{
	// Clamp to texture size.
	if ( iX < 0 )
	{
		iX = 0;
	}
#if DXVERSION==7
	else if ( iX >= (signed)ddsdSrc.dwWidth )
	{
		iX = (signed)ddsdSrc.dwWidth - 1;
	}
#else
	else if ( iX >= (signed)ddsdSrc.Width )
	{
		iX = (signed)ddsdSrc.Width - 1;
	}
#endif
	if ( iY < 0 )
	{
		iY = 0;
	}
#if DXVERSION==7
	else if ( iY >= (signed)ddsdSrc.dwHeight )
	{
		iY = (signed)ddsdSrc.dwHeight - 1;
	}
#else
	else if ( iY >= (signed)ddsdSrc.Height )
	{
		iY = (signed)ddsdSrc.Height - 1;
	}
#endif


	DWORD dwRes;

#if DXVERSION==7
	switch ( ddsdSrc.ddpfPixelFormat.dwRGBBitCount )
	{
	case 8:
		dwRes = (DWORD)( *( (BYTE*)ddsdSrc.lpSurface + (iX) + (iY) * ddsdSrc.lPitch ) );
		break;
	case 15:
	case 16:
		dwRes = (DWORD)( *(WORD*)( (BYTE*)ddsdSrc.lpSurface + (iX) * 2 + (iY) * ddsdSrc.lPitch ) );
		break;
	case 32:
		dwRes = *(DWORD*)( (BYTE*)ddsdSrc.lpSurface + (iX) * 4 + (iY) * ddsdSrc.lPitch );
		break;
	default:
		ASSERT ( FALSE );
		break;
	}
#else
	switch ( iBitsPerPixel )
	{
	case 8:
		dwRes = (DWORD)( *(WORD*)( (BYTE*)locked_rect.pBits + (iX) + (iY) * locked_rect.Pitch ) );
		break;
	case 16:
		dwRes = (DWORD)( *(WORD*)( (BYTE*)locked_rect.pBits + (iX) * 2 + (iY) * locked_rect.Pitch ) );
		break;
	case 32:
		dwRes = *(DWORD*)( (BYTE*)locked_rect.pBits + (iX) * 4 + (iY) * locked_rect.Pitch );
		break;
	default:
		ASSERT ( FALSE );
		break;
	}
#endif

	return dwRes;

}


#if DXVERSION==7
// A universal blit. Slow, but handles most formats, and does conversions and different filter modes, etc.
// By Tomf.
BOOL UniversalBlit ( LPDIRECTDRAWSURFACEn pddsSrc, LPDIRECTDRAWSURFACEn pddsDst,
							UblitFilter ufMin,
							UblitFilter ufMag )
{
	DDSURFACEDESC2	ddsdSrc, ddsdDst;

	D3DInit ( ddsdSrc );
	D3DInit ( ddsdDst );

	if ( pddsSrc == NULL )
	{
		ASSERT ( FALSE );
		return FALSE;
	}
	if ( pddsDst == NULL )
	{
		ASSERT ( FALSE );
		return FALSE;
	}

	pddsSrc->GetSurfaceDesc ( &ddsdSrc );
	pddsDst->GetSurfaceDesc ( &ddsdDst );

	DDPIXELFORMAT ddpfSrc = ddsdSrc.ddpfPixelFormat;
	DDPIXELFORMAT ddpfDst = ddsdDst.ddpfPixelFormat;

	// Only handle RGB formats at the moment.
	ASSERT ( ( ddpfSrc.dwFlags & DDPF_RGB ) != 0 );
	ASSERT ( ( ddpfDst.dwFlags & DDPF_RGB ) != 0 );

	// Are minning or magging?
	UblitFilter ufFilter;
	if ( ddsdSrc.dwWidth * ddsdSrc.dwHeight >= ddsdDst.dwWidth * ddsdDst.dwHeight )
	{
		// Minimising.
		ufFilter = ufMin;
	}
	else
	{
		// Magnifying.
		ufFilter = ufMag;
	}


	DWORD dwPixelSizeSrc;
	DWORD dwPixelSizeDst;

	switch ( ddpfSrc.dwRGBBitCount )
	{
	case 8:
		dwPixelSizeSrc = 1;	// In bytes.
		break;
	case 15:
	case 16:
		dwPixelSizeSrc = 2;	// In bytes.
		break;
	case 32:
		dwPixelSizeSrc = 4;	// In bytes.
		break;
	default:
		// Nothing else handled for now.
		ASSERT ( FALSE );
		return FALSE;
		break;
	}


	switch ( ddpfDst.dwRGBBitCount )
	{
	case 8:
		dwPixelSizeDst = 1;	// In bytes.
		break;
	case 15:
	case 16:
		dwPixelSizeDst = 2;	// In bytes.
		break;
	case 32:
		dwPixelSizeDst = 4;	// In bytes.
		break;
	default:
		// Nothing else handled for now.
		ASSERT ( FALSE );
		return FALSE;
		break;
	}


	HRESULT hres;
	hres = pddsSrc->Lock ( NULL, &ddsdSrc, DDLOCK_READONLY | DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL );
	ASSERT ( SUCCEEDED ( hres ) );
	hres = pddsDst->Lock ( NULL, &ddsdDst, DDLOCK_WRITEONLY | DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL );
	ASSERT ( SUCCEEDED ( hres ) );


	float fXScale = (float)ddsdSrc.dwWidth / (float)ddsdDst.dwWidth;
	float fYScale = (float)ddsdSrc.dwHeight / (float)ddsdDst.dwHeight;
	BYTE *pbDstLine = (BYTE*)ddsdDst.lpSurface;
	for ( int iY = 0; iY < (signed)ddsdDst.dwHeight; iY++ )
	{
		BYTE *pbDst = pbDstLine;
		pbDstLine += ddsdDst.lPitch;
		for ( int iX = 0; iX < (signed)ddsdDst.dwWidth; iX++ )
		{
			float fXSrc = (float)iX * fXScale;
			float fYSrc = (float)iY * fYScale;
			int iXSrc = (int)fXSrc;
			int iYSrc = (int)fYSrc;

			FloatColour fcRes;

			switch ( ufFilter )
			{
			case UBLIT_FILTER_POINT:
				// Just sample from the top-left corner of the sample area.
				fcRes = ConvertPixelDataToFloat ( SamplePoint ( iXSrc, iYSrc, ddsdSrc ), ddsdSrc.ddpfPixelFormat );
				break;
			case UBLIT_FILTER_BILINEAR:
				// Sample the four points and filter them.
				FloatColour fc00 = ConvertPixelDataToFloat ( SamplePoint ( iXSrc + 0, iYSrc + 0, ddsdSrc ), ddsdSrc.ddpfPixelFormat );
				FloatColour fc01 = ConvertPixelDataToFloat ( SamplePoint ( iXSrc + 0, iYSrc + 1, ddsdSrc ), ddsdSrc.ddpfPixelFormat );
				FloatColour fc10 = ConvertPixelDataToFloat ( SamplePoint ( iXSrc + 1, iYSrc + 0, ddsdSrc ), ddsdSrc.ddpfPixelFormat );
				FloatColour fc11 = ConvertPixelDataToFloat ( SamplePoint ( iXSrc + 1, iYSrc + 1, ddsdSrc ), ddsdSrc.ddpfPixelFormat );
				float fXLerp = fXSrc - (float)( iXSrc );
				float fYLerp = fYSrc - (float)( iYSrc );
				ASSERT ( ( fXLerp >= 0.0f ) && ( fXLerp < 1.0f ) );
				ASSERT ( ( fYLerp >= 0.0f ) && ( fYLerp < 1.0f ) );
				fc00 = fc00 * ( 1.0f - fXLerp ) + fc10 * ( fXLerp );
				fc01 = fc01 * ( 1.0f - fXLerp ) + fc11 * ( fXLerp );
				fcRes = fc00 * ( 1.0f - fYLerp ) + fc01 * ( fYLerp );
				break;
			}

			DWORD dwResult = ConvertFloatToPixelData ( fcRes, ddpfDst );

			switch ( dwPixelSizeDst )
			{
			case 2:
				*((WORD *)pbDst) = (WORD)( dwResult & 0xffff );
				break;
			case 4:
				*((DWORD *)pbDst) = dwResult;
				break;
			}

			pbDst += dwPixelSizeDst;
		}
	}

	hres = pddsSrc->Unlock ( NULL );
	ASSERT ( SUCCEEDED ( hres ) );
	hres = pddsDst->Unlock ( NULL );
	ASSERT ( SUCCEEDED ( hres ) );

	return TRUE;
}
#endif //#if DXVERSION==7


⌨️ 快捷键说明

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