游戏编程基础002---半透明效果(001透明效果已集成在002中,故不在冗余)

WEB项目做累了, 学习下游戏的基础设计, 开发平台VS2008SP1

项目下载:http://download.csdn.net/detail/liu_liu213/4010496

/***术语解释***********************************************************/
/*
1.
GDI(Graphics Device Interface) 图形设备接口
画笔 画刷都是GDI中定义的图形对象
HPEN CreatePen(int,int, COLORREF);
HBRUSH CreateHatchBrush(int, COLOREF) //阴影画刷
HHRUSH CreateSolidBrush(COLOREF)	//单色画刷
必须在DC中选中它们才有效
HGDIOBJ SelectObject(HDC hdc, HGDIOBJ gdi对象)
GDI对象还有:位图、字体、区域及调色板,在不使用时使用
BOOL DeleteObject(HGDIOBJ GDI)


2.
Device Context 设备内容,就是程序可以进行绘图的地方;
在WM_PAINT中使用BeginPaint(hWnd, &ps)得到窗口DC
在消息之外,可通过GetDC(WHND hWnd) 取得DC

3.
handle是Windows系统中用来识别各种不同资源的一个句柄
*/
/************************************************************************/


/***半透明操作步骤*******************************************************/
/*
步骤一:取得位图结构
int GetObject(HANDLE h, //GDI对象
			int c, //结构大小
			LPVOID pv ); //结构变量

结构变量如下:
typedef struct tagBITMAP
{
	LONG        bmType;  //位图类型,必须为0
	LONG        bmWidth;  //位图宽度
	LONG        bmHeight; //位图长度
	LONG        bmWidthBytes; //每一列像素所占Byte数
	WORD        bmPlanes;      //颜色平面数
	WORD        bmBitsPixel;	//像素的位数
	LPVOID      bmBits;		//位图内存指针
} BITMAP, *PBITMAP, NEAR *NPBITMAP, FAR *LPBITMAP;

GetObject(bitmp, siezeof(BITMAP), &bm);

步骤二:建立暂存数组
取得位图结构,接着必须先建立以暂存数据来存储位图中所有像素颜色值
unsigned char *pr = new unsigned char[bm.bmHeight * bm.bmWidthBytes];
因unsiged char变量类型大小是1Byte,故每元素大小也为1Byte(8bits),
以24bits色位图来说,其中B(蓝)G(绿)R(红)三原色各占8bits

步骤三:取得位图位值
LONG GetBitmapBits(HBIMAP,  //位图
					LONG,	//要取得的Byte数
					LPVOID,) //存储的数值指针

GetBitmapBits(bitmap, bm.bmHeight * bm.bmWidthBytes, px);

步骤四:合成像素值
取得位图所有像素值后,接着安装不透明度来设定半透明区域内的每个像素的颜色


步骤五:重设位图颜色
根据暂存数组的内容重新设定位图的颜色
LONG SetBitmapBits( HBITMAP,
					DWORD
					CONST VOID)

最后就剩下贴图操作了
*/
/************************************************************************//


#include "stdafx.h"

//全局变量声明
HINSTANCE hInst;
HBITMAP bg, girl;
HDC mdc;

const int xstart = 50; //定义半透明贴图的起始坐标
const int ystart = 20;

//全局函数
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
void MyPaint(HDC);

//****程序入口**************************************
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
	MSG msg;

	MyRegisterClass(hInstance);

	//运行初始化函数
	if (!InitInstance (hInstance, nCmdShow)) 
	{
		return FALSE;
	}

	//消息循环
	while (GetMessage(&msg, NULL, 0, 0)) 
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return msg.wParam;
}

//****定义及注册窗口类别函数*************************
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX); 
	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= (WNDPROC)WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= NULL;
	wcex.hCursor		= NULL;
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= NULL;
	wcex.lpszClassName	= "canvas";  //类别名称
	wcex.hIconSm		= NULL;

	return RegisterClassEx(&wcex);
}

//****初始化*************************************
// 1.存储instance handle与全局变量中
// 2.建立并显示主窗口
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
	HWND hWnd;
	HDC hdc,bufdc;
	BITMAP bm1, bm2;
	HBITMAP bmp; //GDI临时变量


	hInst = hInstance;

	hWnd = CreateWindow("canvas", "绘图窗口" , WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

	if (!hWnd)
	{
		return FALSE;
	}

	MoveWindow(hWnd,10,10,600,450,true);
	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	bg = (HBITMAP)LoadImage(NULL, "bg.bmp", IMAGE_BITMAP, 600, 450, LR_LOADFROMFILE);
	bmp = (HBITMAP)LoadImage(NULL, "girlmask.bmp", IMAGE_BITMAP, 596, 329, LR_LOADFROMFILE);
	GetObject(bg, sizeof(BITMAP), &bm1); //取得bg图信息
	
	if (bm1.bmBitsPixel!=32 && bm1.bmBitsPixel!=24){
		MessageBox(NULL,"此程序只能在32bit或24bit显示模式中运行","",0);
		return FALSE;
	}

	hdc = GetDC(hWnd);
	mdc = CreateCompatibleDC(hdc);
	bufdc = CreateCompatibleDC(hdc);
	girl = CreateCompatibleBitmap(hdc, 298, 329);

	SelectObject(mdc, girl);

	//在mdc上进行透明处理
	SelectObject(bufdc, bg);
	BitBlt(mdc, 0, 0, 298,329, bufdc, xstart, ystart, SRCCOPY);
	SelectObject(bufdc, bmp);
	BitBlt(mdc, 0, 0, 298,329, bufdc, 298, 0, SRCAND);
	BitBlt(mdc, 0, 0, 298,329, bufdc, 0, 0, SRCPAINT);

	unsigned char *px1, *px2;
	//处理背景图
	px1 = new unsigned char[bm1.bmHeight * bm1.bmWidthBytes];
	GetBitmapBits(bg, bm1.bmHeight*bm1.bmWidthBytes, px1);

	//处理前景图
	//girl = (HBITMAP)LoadImage(NULL, "girl.bmp", IMAGE_BITMAP, 298, 329, LR_LOADFROMFILE);
	GetObject(girl, sizeof(BITMAP), &bm2);

	px2 = new unsigned char[bm2.bmHeight * bm2.bmWidthBytes];
	GetBitmapBits(girl, bm2.bmHeight*bm2.bmWidthBytes, px2);

	int xend, yend;
	int x,y,i;
	int rgb_b;
	int PxBytes = bm1.bmBitsPixel / 8;

	xend = xstart + 298;
	yend = ystart + 329;

	//处理背景图像素颜色
	for(y=ystart; y<yend; y++){
		for(x=xstart; x<xend; x++){
			rgb_b = y*bm1.bmWidthBytes + x*PxBytes;

			px1[rgb_b] = px1[rgb_b] * 0.7;
			px1[rgb_b+1] = px1[rgb_b+1] * 0.7;
			px1[rgb_b+2] = px1[rgb_b+2] * 0.7;

		}
	}

	//处理前景图像素颜色
	for(y=0; y<bm2.bmHeight; y++){
		for(x=0; x<bm2.bmWidth; x++){
			rgb_b = y*bm2.bmWidthBytes + x*PxBytes;
			i = (ystart+y) * bm1.bmWidthBytes + (xstart+x)*PxBytes;

			px2[rgb_b] = px2[rgb_b] *0.3 + px1[i];
			px2[rgb_b+1] = px2[rgb_b+1] *0.3 + px1[i+1];
			px2[rgb_b+1] = px2[rgb_b+1] *0.3 + px1[i+2];
		}
	}

	SetBitmapBits(girl, bm2.bmHeight*bm2.bmWidthBytes, px2);

	MyPaint(hdc);

	ReleaseDC(hWnd, hdc);
	delete[] px1;
	delete[] px2;

	return TRUE;
}

VOID MyPaint(HDC hdc)
{
//贴上背景图
	SelectObject(mdc, bg);
	BitBlt(hdc, 0, 0, 600, 450, mdc, 0, 0, SRCCOPY);

//贴上处理后的半透明图
	SelectObject(mdc, girl);
	BitBlt(hdc, xstart, ystart, 298, 329, mdc, 0, 0, SRCCOPY);

}

//****回调函数***********************************
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;
	HDC hdc;
	int i;
	switch (message) 
	{
		case WM_PAINT:						
			hdc = BeginPaint(hWnd, &ps);
			MyPaint(hdc);
			EndPaint(hWnd, &ps);
			break;
		case WM_DESTROY:	
			PostQuitMessage(0);
			break;
		default:							
			return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值