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

📄 bitmap.h

📁 3D游戏场景编辑器
💻 H
📖 第 1 页 / 共 2 页
字号:

The Bitmap contains one or two pixel-sets representing an image.  The "primary" is
a fast-blitting version of the image, and the "secondary" is a storage version
(eventually wavelet compressed) which can be used to rebuild the primary if it is
freed or damaged.  Both cary a generalized format.

Let's do an example.  I want to load a bitmap, set it up for drawing with the
genesis Engine, and then blit some interactive stuff into it.

************************************************************************/

#if 0
// {
//-----------------------------------------------------------------------------

void Init(geEngine * Engine);
void Shutdown(void);
void Draw(void);
void DrawPolite(void);

static geBitmap * myBM = NULL;
static geEngine * myEngine = NULL;

void Init(geEngine * Engine)
{
geBoolean success;
geBitmap_Info Info;

	myEngine = Engine;	// this is not looked well upon; for ease of demonstration only!
	assert(Engine);

	myBM = geBitmap_CreateFromFileName(NULL,"mybitmap.bmp");

	// CreateFromFile can load windows BMP files, or custom GeBm files.

	assert(myBM);

	// get the main info; I don't care about the secondary, so leave it NULL

	success = geBitmap_GetInfo(myBM,&Info,NULL);
	assert(success);

	// make sure I loaded a bitmap in the format I understand !

	if ( Info.Format == GE_PIXELFORMAT_8BIT_PAL )
	{
		// I want palette index 255 to act as transparency, so I must use SetColorKey

		success = geBitmap_SetColorKey(myBM,GE_TRUE,255);
		assert(success);

		// just for fun, let's modify the palette:
		if (1)
		{
		geBitmap_Palette * Pal;

			// get the palette ; I don't care if its primary or secondary, so
			/// I don't use the Info.Palette field

			Pal = geBitmap_GetPalette(myBM);
			assert(Pal);

			// I'm only fiddling one entry, so don't bother with a full Lock() UnLock()
			//  sequence on the palette

			// make palette index zero bright red; we use alpha = 255 for opaque

			success = geBitmap_Palette_SetEntryColor(Pal,0,255,0,0,255);
			assert(success);

			// tell the bitmap system you've changed the palette; this function
			//  is smart enough to not do unecessary copies or whatever.

			success = geBitmap_SetPalette(myBM,Pal);
			assert(success);
		}

	}
	else
	{
		// otherwise, treat black as transparent, in whatever format I have

		success = geBitmap_SetColorKey(myBM,GE_TRUE,gePixelFormat_ComposePixel(Info.Format,0,0,0,0));
		assert(success);
	}	

	// note that I did NOT use SetFormat.  SetFormat may do a conversion, and since the original
	//	bitmap was created without colorkey, it would have been converted to a new format but
	//	kept its property of having no colorkey!
	// (SetFormat will fiddle the bits and whatever way necessary to keep bitmaps as visually similar
	//		as possible)

	// I want to fiddle the fast format in 565 later, so cue the bitmap to try to give me that format.

	success = geBitmap_SetPreferredFormat(myBM,GE_PIXELFORMAT_16BIT_565_RGB);
	assert(success);

	// Add it to the engine so it can be used for drawing.

	success = geEngine_AddBitmap(myEngine,myBM);
	assert(success);
}

void Shutdown(void)
{
geBoolean WasDestroyed;

	assert(myBM);
	
	// clean up

	geEngine_RemoveBitmap(myEngine,myBM);

	WasDestroyed = geBitmap_Destroy(&myBM);

	// someone else might have done _CreateRef on our bitmap,
	//  so we can't be sure it's actually destroyed.
	// this code is still ready to be run again with a new call to Init()

	//assert(WasDestroyed);

	myBM = NULL;
	myEngine = NULL;
}

void Draw(void)
{
geBitmap * Lock;
geBoolean success;
geBitmap_Info Info;
uint16 *bits,*bptr;
int x,y;

	// lets fiddle the bits.
	// we need to lock the bitmap for write.
	//	LockForWrite is an exclusive lock, unlike LockForRead which is non-blocking
	// request our favorite format, and only lock Mip 0 (the full size bitmap)

	success = geBitmap_LockForWriteFormat(myBM,&Lock,0,0,GE_PIXELFORMAT_16BIT_565_RGB);
	if ( ! success )
	{
		// well, we tried to be nice; if we were very polite, we would do a LockForWrite
		// here, and try to fiddle the bits in whatever format we got; However, we aren't
		// that polite, so we just do a _SetFormat
		//
		// note that we are destroying the original bitmap by changing its format
		// we should only do this if we are going to draw into the bitmap

		success = geBitmap_SetFormat(myBM,GE_PIXELFORMAT_16BIT_565_RGB,GE_TRUE,0,NULL);
		assert(success);

		// now we should be able to get the bits we want, *but* they may not be the
		// primary (fast) format; oh well, it's the best we can do...
		// (if you must have the fastest bits, then use only _LockForWrite, never LockForWriteFormat,
		// which might have to do a conversion)

		success = geBitmap_LockForWriteFormat(myBM,&Lock,0,0,GE_PIXELFORMAT_16BIT_565_RGB);
		assert(success);
	}

	// now Lock is our bitmap in 565
	// we do a GetInfo because the Lock's info could be different than
	//	the original bitmap's (particularly the Palette & the Stride)

	success = geBitmap_GetInfo(Lock,&Info,NULL);
	assert(success);

	// you can only call _GetBits on a locked bitmap

	bits = geBitmap_GetBits(Lock);
	assert( bits );

	bptr = bits;
	for(y=0; y < Info.Height; y++)
	{
		for(x=0; x < Info.Width; x++)
		{
		uint16 R,G,B;
			// make a silly 565 gradient
			R = x & 0x1F;
			G = x & 0x3F;
			B = y & 0x1F;

			*bptr++ = (R<<11) + (G<<5) + B;
		}

		// note that bptr is a word pointer, and Stride is in pixels :

		bptr += Info.Stride -  Info.Width;
	}
	bits = bptr = NULL;

	// you call Unlock on all the mips you locked - not on the original bitmap!

	success = geBitmap_UnLock(Lock);
	assert(success);

	// now, we only fiddled the full-size Mip, and there might be more,
	//  so lets percolate the changes into the smaller mips:

	success = geBitmap_RefreshMips(myBM);
	assert(success);

	// a null rect means use the whole bitmap;
	// Engine_DrawBitmap blits a 2d decal to the framebuffer (fast)

	success = geEngine_DrawBitmap(myEngine,myBM,NULL,0,0);
	assert(success);

}

void DrawPolite(void)
{
geBitmap * Lock;
geBoolean success;
geBitmap_Info Info;
void *bits;
int x,y;

	// this function does the same thing as Draw() , but is more polite
	// lock in the fastest format (whatever it is)
	// because we did SetPreferred, this should be 565_RGB, but might not be

	success = geBitmap_LockForWrite(myBM,&Lock,0,0);
	assert(success);

	success = geBitmap_GetInfo(Lock,&Info,NULL);
	assert(success);

	bits = geBitmap_GetBits(Lock);
	assert( bits );

	if ( Info.Format == GE_PIXELFORMAT_16BIT_565_RGB )
	{
	uint16 *wptr;

		// our favorite format

		wptr = bits;
		for(y=0; y < Info.Height; y++)
		{
			for(x=0; x < Info.Width; x++)
			{
			uint16 R,G,B;
				// make a silly 565 gradient
				R = x & 0x1F;
				G = x & 0x3F;
				B = y & 0x1F;

				*wptr++ = (R<<11) + (G<<5) + B;
			}
			wptr += Info.Stride -  Info.Width;
		}
	}
	else
	{
	uint8 * bptr;

		// oh well, do our best
		// bitmaps must have had a good reason to not give us the format we preferred,

		bptr = bits;
		for(y=0; y < Info.Height; y++)
		{
			for(x=0; x < Info.Width; x++)
			{
			uint32 R,G,B;

				// put a color in any format

				R = (x & 0x1F)<<3;
				G = (x & 0x3F)<<2;
				B = (y & 0x1F)<<3;

				// we use alpha of 255 for opaque

				gePixelFormat_PutColor(Info.Format,&bptr,R,G,B,255);
			}

			bptr += (Info.Stride -  Info.Width) * gePixelFormat_BytesPerPel(Info.Format);
		}
	}
	bits = NULL;

	// same as before:

	success = geBitmap_UnLock(Lock);
	assert(success);

	success = geBitmap_RefreshMips(myBM);
	assert(success);

	success = geEngine_DrawBitmap(myEngine,myBM,NULL,0,0);
	assert(success);

}

// end tutorial on the Bitmap system
//-----------------------------------------------------------------------------
// }

/***********************************************************************************/

#endif
#ifdef __cplusplus
}
#endif


#endif


⌨️ 快捷键说明

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