1.概述
在Windows上繪圖方式,跟美術大師繪圖差不多。美術繪畫,首先要具備以下工具:畫板,畫布,畫筆,畫刷。同樣,Windows上也有相關的概念。繪圖裝置DeviceContext(DC),點陣圖Bitmap,畫筆Pen,畫刷brush。他們一一對應。
2.畫板
在Windows中被稱作裝置上下文(Device Context,DC),我習慣稱之為繪圖裝置。但是Windows的“畫板”與美術大師手中的“畫板”不一樣,Windows中的“畫板”實質上是一個工具的集合體,將畫布、畫筆、畫刷、繪畫方式全部綜合管理起來,然後,所有的繪畫操作都將在這上面進行。
1)系統繪圖裝置。系統有預設的繪圖,我們可以直接使用它進行一系列的繪圖操作。
獲取系統繪圖裝置:
HDC GetDC( HWND hWnd // 視窗控制代碼。即指定獲得那個視窗的繪圖裝置。 );
如:
HDC hDC = GetDC(g_hWnd); Rectangle(hDC,0,0,100,100);//繪製矩形 ....
使用完畢後要歸還給視窗:
int ReleaseDC( HWND hWnd, // handle to window HDC hDC // handle to DC );
2)建立畫板。通常我們不直接使用系統畫板,因為系統畫板直接和顯示器關聯,在上面一邊畫,就會一邊顯示到視窗,由於在繪製的時候,中間有時間差(我們可能經過若干次繪製,才繪製完一個地圖),而遊戲程式需要反覆的擦除、重繪,所以常常會造成畫面劇烈閃爍。為了解決這個問題,我們會建立一個輔助畫板,在幕後繪製完畢後,一次性的將它顯示到螢幕上,因為顯示的時間非常快,所以就看不到閃爍。
建立輔助繪圖裝置:
HDC CreateCompatibleDC( HDC hdc // 指向一個已經存在的DC,如果該值傳入0,則系統會建立一個存貯DC。 );
存貯DC(輔助繪圖裝置),在建立完畢後,它的大小隻有一個畫素,我們沒辦法直接往他上面直接繪圖,我們還需要往它上面貼一張畫布。
使用完畢後記得要釋放資源:
BOOL DeleteDC( HDC hdc // handle to DC );
例:
HDC memDC = CreateCompatibleDC(0); //建立輔助繪圖裝置 SelectObject(memDC,hBitmap); //將畫布貼到繪圖裝置上 Rectangle(memDC,x1,y1,x2,y2); //繪製矩形 HDC hDC = GetDC(g_hWnd); //獲得系統繪圖裝置 copy memDC to hDC //複製到系統裝置上顯示 ReleaseDC(g_hWnd,hDC); //歸還系統繪圖裝置 DeleteDC(memDC); //釋放輔助繪圖裝置
3.畫布
畫布其實就是點陣圖。點陣圖的作用非常強大,在此我只介紹它的普通用法——充當畫布。其他作用,後面再介紹。
建立掩碼點陣圖(畫布):
HBITMAP CreateCompatibleBitmap( HDC hdc, //指向繪圖裝置,最好是系統的繪圖裝置 int nWidth, // 點陣圖寬度 int nHeight // 點陣圖高度 );
釋放資源:
BOOL DeleteObject( HGDIOBJ hObject // handle to graphic object );
4.畫筆
畫筆就不用解釋了,Windows的畫筆和美術大師的差不多。
建立畫筆:
HPEN CreatePen( int fnPenStyle, // 畫筆風格。直線:PS_SOLID,點線:PS_DOT int nWidth, // 畫筆寬度。決定了畫出來的線條粗細 COLORREF crColor // 畫筆顏色 );
釋放資源:
BOOL DeleteObject( HGDIOBJ hObject // handle to graphic object );
顏色:可由紅綠藍三種顏色按程度混合起來構成。
如COLORREF cr = RGB(255,0,255),此時cr是粉紅色(紅色+藍色)。COLORREF實際上是無符號長整型的別名,RGB將紅綠藍三個數值整合成一個無符號長整型數。
COLORREF RGB( BYTE byRed, //紅色分量0~255,值越大表面程度越深。 BYTE byGreen, // 綠色分量0~255 BYTE byBlue // 藍色分量0~255 );
5.畫刷
建立畫刷:
HBRUSH CreateSolidBrush( COLORREF crColor // brush color value );
釋放資源:
BOOL DeleteObject( HGDIOBJ hObject // handle to graphic object );
6.繪畫
畫布、畫筆、畫刷建立好之後,要是分別使用API,將它們選入繪圖裝置。當然,繪圖裝置,有自己的預設畫刷和畫筆。
HGDIOBJ SelectObject( HDC hdc, // 直線繪圖裝置 HGDIOBJ hgdiobj // 指向GDI物件。就是畫刷、畫筆、點陣圖等。 );
返回值是舊有的相關內容。
一些常用繪圖API:
1)繪製矩形。
BOOL Rectangle( HDC hdc, // 繪圖裝置 int nLeftRect, // 矩形區域左上角x座標 int nTopRect, // 矩形區域左上角y座標 int nRightRect, //矩形區域右下角x座標 int nBottomRect // 矩形區域右下角y座標 );
2)填充區域。用畫刷來填充區域,經常用來擦除整個視窗。
int FillRect( HDC hDC, // 繪圖裝置 CONST RECT *lprc, // 矩形區域 HBRUSH hbr // 填充畫刷 );
區域結構:
typedef struct _RECT { LONG left; //矩形左邊(左上角x座標) LONG top; //矩形頂邊(左上角y座標) LONG right; //矩形右邊(右下角x座標) LONG bottom; //矩形底邊(右下角y座標) } RECT, *PRECT;
獲得視窗客戶區區域:
BOOL GetClientRect( HWND hWnd, // handle to window LPRECT lpRect // client coordinates );
3)繪圖裝置之間的複製。
BOOL BitBlt( HDC hdcDest,//目標繪圖裝置 int nXDest, // 目標區域左上角x座標 int nYDest, //目標區域左上角y座標 int nWidth, // 目標區域寬度 int nHeight,// 目標區域高度 HDC hdcSrc, // 源繪圖裝置 int nXSrc, // 源區域左上角x座標 int nYSrc, // 源區域左上角y座標 DWORD dwRop // 操作碼。常用SRCCOPY(複製)。 );
可以簡單的理解這個API:將源繪圖裝置複製給目標繪圖裝置。從幕後畫布複製給前景畫布。從幕後繪圖裝置複製給顯示器。複製的區域,就是上面指定的。
如:BitBlt(hDC,0,0,g_nWidth,g_nHeight,memDC,0,0,SRCCOPY);4)其他常用API
文書處理
建立字型:CreateFont,CreatePointFont,SelectObject(.,font)。
顯示文字:Textout,DrawText
設定文字顏色:SetTextColor ,GetTextColor
設定背景:SetBkColor,SetBkMode(設定背景模式,TRANSPARENT為透明)
繪製
點:SetPixel,SetPixelV,GetPixel。
線:MoveToEx-LinTo。
圓:Ellipse
多邊形:Polygon
弧:Arc
點陣圖處理
從檔案載入點陣圖/圖示/游標:LoadImage
從資源載入點陣圖:LoadBitmap
獲得點陣圖資訊:GetObject
繪圖裝置間的複製複製
直接模式:BitBlt
拉伸複製:StretchBlt
透明處理:TranparentBlt,需要加 Msimg32.lib庫。
半透明處理(Alpha混合):AlpaBlend
其他
獲得系統屬性:GetSystemMetrics,一些很重要的資訊。
獲得滑鼠螢幕座標:GetCursorPos,需使用座標轉換轉換為視窗座標
座標轉換:ClientToScreen,ScreenToClient
獲得鍵盤鍵狀態:GetAsyncKeyState
獲得整個鍵盤資訊:GetKeyboardState
訊息框:MessageBox
一個完整的程式碼示例:
#include "app.h" int g_nWidth = 600;//視窗寬度 int g_nHeight = 480;//視窗高度 void init()//遊戲初始化 { } void update()//邏輯更新 { } void render()//畫面渲染 { HDC hDC = GetDC(getHWnd()); //獲得系統繪圖裝置 HDC memDC = CreateCompatibleDC(0); //建立輔助繪圖裝置 HBITMAP bmpBack = CreateCompatibleBitmap(hDC,g_nWidth,g_nHeight);//建立掩碼點陣圖(畫布) SelectObject(memDC,bmpBack); //將畫布貼到繪圖裝置上 HPEN penBack = CreatePen(PS_SOLID,1,RGB(255,0,255));//建立畫筆 SelectObject(memDC,penBack); //將畫筆選到繪圖裝置上 HBRUSH brushBack = CreateSolidBrush(RGB(255,255,255));//建立畫刷 SelectObject(memDC,brushBack); //將畫刷選到繪圖裝置上 //擦除背景 RECT rcClient;//區域結構 GetClientRect(getHWnd(),&rcClient);//獲得客戶區域 HBRUSH brushTemp = (HBRUSH)GetStockObject(WHITE_BRUSH);//獲得庫存物體,白色畫刷。 FillRect(memDC,&rcClient,brushTemp);//填充客戶區域。 // HBRUSH brushObj = CreateSolidBrush(RGB(0,255,0));//建立物體畫刷 //繪製維網格,矩形畫法。 int dw = 30; int rows = g_nHeight/dw; int cols = g_nWidth/dw; for (int r=0; r<rows; ++ r) { for (int c=0; c<cols; ++c) { if (r == c) { SelectObject(memDC,brushObj); } else { SelectObject(memDC,brushBack); } Rectangle(memDC,c*dw,r*dw,(c+1)*dw,(r+1)*dw); } } DeleteObject(brushObj); // BitBlt(hDC,0,0,g_nWidth,g_nHeight,memDC,0,0,SRCCOPY);//複製到系統裝置上顯示 DeleteObject(penBack); //釋放畫筆資源 DeleteObject(brushBack);//釋放畫刷資源 DeleteObject(bmpBack); //釋放點陣圖資源 DeleteDC(memDC); //釋放輔助繪圖裝置 ReleaseDC(getHWnd(),hDC); //歸還系統繪圖裝置 Sleep(1); } void clear()//資源釋放 { } //主函式 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE , LPSTR , int ) { if(!initApp(hInstance,L"貪吃蛇遊戲",g_nWidth,g_nHeight)) { return 0; } //初始化遊戲 init(); //遊戲迴圈 mainLoop(); //釋放資源 clear(); return 0; }
原文地址:https://blog.csdn.net/celte/article/details/10243309
原文地址:http://blog.csdn.net/you_lan_hai/article/details/6911497