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;
}