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

📄 surfaceformat.cpp

📁 这个是symbian下的一个蛮庞大的3D游戏源代码!对于学习3D开发的人有很大的帮助!
💻 CPP
字号:
#include <gr/SurfaceFormat.h>
#include <assert.h>
#include <config.h>


namespace gr
{


const char* const FORMAT_NAMES[] =
{
	/** The surface format is unknown. */
	"UNKNOWN",
	/** 24-bit RGB pixel format. */
	"R8G8B8",
	/** 24-bit RGB pixel format. */
	"B8G8R8",
	/** 32-bit RGB pixel format with alpha. */
	"A8R8G8B8",
	/** 32-bit RGB pixel format where 8 bits are reserved for each color. */
	"X8R8G8B8",
	/** 32-bit RGB pixel format where 8 bits are reserved for each color.  */
	"X8B8G8R8",
	/** 32-bit RGB pixel format with alpha.  */
	"A8B8G8R8",
	/** 16-bit RGB pixel format. (PS2) */
	"R5G6B5",
	/** 16-bit RGB pixel format. */
	"R5G5B5",
	/** 4-bit palettized pixel format. (PC/PS2) */
	"P4",
	/** 8-bit palettized pixel format. (PC/PS2)	*/
	"P8",
	/** 16-bit pixel format where 5 bits are reserved for color and 1 bit is reserved for transparency. */
	"A1R5G5B5",
	/** 16-bit RGB pixel format where 4 bits are reserved for each color. */
	"X4R4G4B4",
	/** 16-bit RGB pixel format. */
	"A4R4G4B4",
	/** 16-bit pixel format where 5 bits are reserved for color and 1 bit is reserved for transparency. */
	"A1B5G5R5",
	/** 8-bit RGB texture format. (PS2) */
	"R3G3B2",
	/** 8-bit RGB texture format. */
	"R3G2B3",
	/** 8-bit alpha-only. */
	"A8",
	/** 16-bit RGB pixel format with alpha.	*/
	"A8R3G3B2",
	/** 16-bit RGB pixel format with alpha.	*/
	"A8R3G2B3",
	/** "32", depth using 24 bits and stencil 8 bits */
	"D24S8",
};

/** 
 * Descriptions of surface formats: 
 * {format, bitcount, red mask, green mask, blue mask, alpha mask}. 
 */
static const uint32_t FORMATDESC[][6] = 
{
	{SurfaceFormat::SURFACE_UNKNOWN   ,  0, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
	{SurfaceFormat::SURFACE_R8G8B8    , 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000},
	{SurfaceFormat::SURFACE_B8G8R8    , 24, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000},
	{SurfaceFormat::SURFACE_A8R8G8B8  , 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000},
	{SurfaceFormat::SURFACE_X8R8G8B8  , 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000},
	{SurfaceFormat::SURFACE_X8B8G8R8  , 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000},
	{SurfaceFormat::SURFACE_A8B8G8R8  , 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000},
	{SurfaceFormat::SURFACE_R5G6B5    , 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000},
	{SurfaceFormat::SURFACE_R5G5B5    , 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00000000},
	{SurfaceFormat::SURFACE_P4		 ,  4,  0x00000000, 0x00000000, 0x00000000, 0x00000000},
	{SurfaceFormat::SURFACE_P8		 ,  8,  0x00000000, 0x00000000, 0x00000000, 0x00000000},
	{SurfaceFormat::SURFACE_A1R5G5B5  , 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00008000},
	{SurfaceFormat::SURFACE_X4R4G4B4  , 16, 0x00000f00, 0x000000f0, 0x0000000f, 0x00000000},
	{SurfaceFormat::SURFACE_A4R4G4B4  , 16, 0x00000f00, 0x000000f0, 0x0000000f, 0x0000f000},
	{SurfaceFormat::SURFACE_A1B5G5R5  , 16, 0x0000001f, 0x000003e0, 0x00007c00, 0x00008000},
	{SurfaceFormat::SURFACE_R3G3B2    ,  8, 0x000000e0, 0x0000001c, 0x00000003, 0x00000000},
	{SurfaceFormat::SURFACE_R3G2B3    ,  8, 0x000000e0, 0x00000018, 0x00000007, 0x00000000},
	{SurfaceFormat::SURFACE_A8        ,  8, 0x00000000, 0x00000000, 0x00000000, 0x000000ff},
	{SurfaceFormat::SURFACE_A8R3G3B2  , 16, 0x000000e0, 0x0000001c, 0x00000003, 0x0000ff00},
	{SurfaceFormat::SURFACE_A8R3G2B3  , 16, 0x000000e0, 0x00000018, 0x00000007, 0x0000ff00},
};

/** Number of supported surface formats. */
static const int FORMATS = sizeof(FORMATDESC)/sizeof(FORMATDESC[0]);


/** 
 * Returns left zero bit count before first non-zero bit.
 */
static inline int maskToShift( uint32_t mask )
{
	int count = 0;
	uint32_t testBit = 1;
	if ( 0 == mask )
		return 32;

	while ( 0 == (mask & testBit) )
	{
		++count;
		testBit += testBit;
	}
	return count;
}

/** 
 * Returns number of non-zero bits in the dword.
 */
static inline int countBits( uint32_t mask )
{
	int count = 0;
	uint32_t testBit = 1;
	while ( 0 != testBit )
	{
		if ( 0 != (mask&testBit) )
			++count;
		testBit += testBit;
	}
	return count;
}


SurfaceFormat::SurfaceFormat() :
	m_type( SurfaceFormat::SURFACE_UNKNOWN )
{
	assert( SURFACE_LAST == FORMATS );
}

SurfaceFormat::SurfaceFormat( SurfaceFormatType type ) :
	m_type( type )
{
	assert( (SurfaceFormatType)FORMATDESC[type][0] == type );
	assert( SURFACE_LAST == FORMATS );
}

SurfaceFormat::SurfaceFormat( int bitCount, uint32_t redMask, uint32_t greenMask, uint32_t blueMask, uint32_t alphaMask )
{
	m_type = SurfaceFormat::SURFACE_UNKNOWN;

	for ( int i = 0 ; i < FORMATS ; ++i )
	{
		if ( FORMATDESC[i][1] == (uint32_t)bitCount &&
			FORMATDESC[i][2] == (uint32_t)redMask &&
			FORMATDESC[i][3] == (uint32_t)greenMask &&
			FORMATDESC[i][4] == (uint32_t)blueMask &&
			FORMATDESC[i][5] == (uint32_t)alphaMask )
		{
			m_type = (SurfaceFormat::SurfaceFormatType)FORMATDESC[i][0];
		}
	}
}

SurfaceFormat::SurfaceFormatType SurfaceFormat::type() const
{
	return m_type;
}

int SurfaceFormat::bitsPerPixel() const
{
	return (int)FORMATDESC[m_type][1];
}

int SurfaceFormat::paletteEntries() const
{
	if ( SURFACE_P8 == m_type )
		return 256;
	else if ( SURFACE_P4 == m_type )
		return 16;
	else
		return 0;
}

void SurfaceFormat::copyPixels( void* dst, const SurfaceFormat& dstpalfmt, const void* dstpal, 
	const SurfaceFormat& srcfmt, const void* src, const SurfaceFormat& srcpalfmt, const void* srcpal,
	int pixels ) const
{
	assert( srcfmt.m_type != SURFACE_UNKNOWN );
	assert( srcpalfmt.m_type != SURFACE_P4 && srcpalfmt.m_type != SURFACE_P8 );
	assert( dstpalfmt.m_type != SURFACE_P4 && dstpalfmt.m_type != SURFACE_P8 );
	assert( !srcpalfmt.palettized() );
	assert( !srcpalfmt.palettized() );
	assert( srcpalfmt.m_type == SURFACE_UNKNOWN || srcpal );
	assert( dstpalfmt.m_type == SURFACE_UNKNOWN || dstpal );

	if ( !srcfmt.palettized() )
		srcpal = 0;
	if ( !palettized() )
		dstpal = 0;

	const uint8_t*		srcbytes		= reinterpret_cast<const uint8_t*>( src );
	const uint8_t*		srcpalbytes		= reinterpret_cast<const uint8_t*>( srcpal );
	const int			srcpalentries	= srcfmt.paletteEntries();
	const int			srcbitcount		= FORMATDESC[srcfmt.m_type][1];
	int					srcsubpix		= 0;
	const int			srcbitoffs		= (8-srcbitcount) & 7;
	const uint32_t*		srcfmtdesc		= &FORMATDESC[ (srcpal ? srcpalfmt.m_type : srcfmt.m_type) ][1];
	const uint32_t*		srcmask			= &srcfmtdesc[1];
	int					srcbits[4];
	int					srcshift[4];
	uint32_t 			srcval[4];
	const int 			srcpixbitcount	= srcfmtdesc[0];
	const int			srcpixsize		= srcpixbitcount >> 3;
	const uint8_t* 		srcpixbytes;

	uint8_t*			dstbytes		= reinterpret_cast<uint8_t*>( dst );
	const uint8_t*		dstpalbytes		= reinterpret_cast<const uint8_t*>( dstpal );
	const int			dstpalentries	= paletteEntries();
	const int			dstbitcount		= FORMATDESC[m_type][1];
	int					dstsubpix		= 0;
	const uint32_t*		dstfmtdesc		= &FORMATDESC[ (dstpal ? dstpalfmt.m_type : m_type) ][1];
	const uint32_t*		dstmask			= &dstfmtdesc[1];
	int					dstbits[4];
	int					dstshift[4];
	uint32_t 			dstval[4];
	const int 			dstpixbitcount	= dstfmtdesc[0];
	const int			dstpixsize		= dstpixbitcount >> 3;
	const uint8_t* 		dstpixbytes;

	// compute aux channel variables
	for ( int i = 0 ; i < 4 ; ++i )
	{
		srcbits[i] = countBits( srcmask[i] );
		srcshift[i] = maskToShift( srcmask[i] );
		dstbits[i] = countBits( dstmask[i] );
		dstshift[i] = maskToShift( dstmask[i] );
	}

	for ( int i = 0 ; i < pixels ; ++i )
	{
		// apply palette if any
		if ( srcpal )
		{
			int ix = (*srcbytes >> (srcbitoffs-srcsubpix&7)) & (srcpalentries-1);
			//dbg::Debug::println( "srcbyte 0x%x results in index %i with subpix %i", (uint32_t)*srcbytes, ix, srcsubpix );
			assert( (unsigned)ix < (unsigned)srcpalentries ); // color index out of source palette range
			srcpixbytes = srcpalbytes + ix*srcpixsize;
		}
		else
		{
			srcpixbytes = srcbytes;
		}
		
		// read pixel data
		uint32_t srcpix = *srcpixbytes;
		switch ( srcpixbitcount )
		{
		case 32:	srcpix |= (uint32_t)srcpixbytes[3] << 24; // fall-through -> 24
		case 24:	srcpix |= (uint32_t)srcpixbytes[2] << 16; // fall-through -> 16
		case 16:	srcpix |= (uint32_t)srcpixbytes[1] << 8; break;
		}
		
		// convert pixel to R8G8B8A8
		for ( int k = 0 ; k < 4 ; ++k )
			srcval[k] = ( (srcpix & srcmask[k]) >> srcshift[k] ) << (8-srcbits[k]);
		//dbg::Debug::println( "srcval = (0x%X,0x%X,0x%X,0x%X)", srcval[0], srcval[1], srcval[2], srcval[3] );
		
		// convert R8G8B8A8 to destination format
		uint32_t dstpix = uint32_t(-1);
		if ( dstpal )
		{
			// find best match in dst palette
			int mindist = 1<<30;
			dstpixbytes = dstpalbytes;
			//dbg::Debug::println( "searching dst palette[%i]", dstpalentries );
			for ( int n = 0 ; n < dstpalentries ; ++n )
			{
				// read dst palette data
				uint32_t pix = *dstpixbytes;
				switch ( dstpixbitcount )
				{
				case 32:	pix |= (uint32_t)dstpixbytes[3] << 24; // fall-through -> 24
				case 24:	pix |= (uint32_t)dstpixbytes[2] << 16; // fall-through -> 16
				case 16:	pix |= (uint32_t)dstpixbytes[1] << 8; break;
				}

				// convert dst palette data and compute distance to target color
				int dist = 0;
				for ( int k = 0 ; k < 4 ; ++k )
				{
					dstval[k] = ( (pix & dstmask[k]) >> dstshift[k] ) << (8-dstbits[k]);
					dist += (dstval[k]-srcval[k]) * (dstval[k]-srcval[k]);
				}
				//dbg::Debug::println( "dstval = (0x%X,0x%X,0x%X,0x%X)", dstval[0], dstval[1], dstval[2], dstval[3] );
				
				// find closest color
				if ( dist < mindist )
				{
					mindist = dist;
					dstpix = n;
					if ( 0 == mindist )
						break;
				}
				
				dstpixbytes += dstpixsize;
			}
		}
		else
		{
			// convert channels to destination format
			for ( int k = 0 ; k < 4 ; ++k )
			{
				uint32_t dstv = ( srcval[k] >> (8-dstbits[k]) ) << dstshift[k];
				dstpix = (dstpix & ~dstmask[k]) | dstv;
				if ( 0 == srcbits[k] )
					dstpix |= dstmask[k];
			}
		}
		
		// write data
		switch ( dstbitcount )
		{
		case 32:	dstbytes[3] = (uint8_t)( dstpix >> 24 ); // fall-through -> 24
		case 24:	dstbytes[2] = (uint8_t)( dstpix >> 16 ); // fall-through -> 16
		case 16:	dstbytes[1] = (uint8_t)( dstpix >> 8 ); // fall-through -> 8
		case 8:		dstbytes[0] = (uint8_t)( dstpix ); break;
		case 4:		dstbytes[0] = (uint8_t)( dstbytes[0] & (~(0xF << dstsubpix)) );
					dstbytes[0] = (uint8_t)( dstbytes[0] + (dstpix << dstsubpix) );
		}

		srcsubpix += srcbitcount;
		srcbytes += srcsubpix>>3;
		srcsubpix &= 7;
		
		dstsubpix += dstbitcount;
		dstbytes += dstsubpix>>3;
		dstsubpix &= 7;
	}
}

const char* SurfaceFormat::toString() const
{
	assert( m_type < SURFACE_LAST );
	return FORMAT_NAMES[m_type];
}


} // gr


⌨️ 快捷键说明

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