プログラミングのメモ帳(C/C++/HSP)

日々のプログラミングで気づいた点や小技集を紹介します。(Windows 10/XP/Vista、VC2017、HSP)

オフ・スクリーンの作成法

2011年06月10日 12時35分00秒 | グラフィック関連

簡単なアニメーションやゲームなどを作成したとき、キャラクタの数が多いと画面がちらつく事があります。
この解決策と具体的な便利関数と使い方を紹介します。

以前に「ダブル・バッファリングの方法(1)」と「ダブル・バッファリングの方法(2)」で紹介した関数バージョンです。
ここで紹介する便利関数は次の3つです。

  1. funcCreateMemDC()
  2. funcDeleteMemDC()
  3. funcGetSizeMemDC()

プロトタイプ宣言

HDC CreateCompatibleDC(
    HDC     hDC         // デバイスコンテキストのハンドル
);

HBITMAP CreateCompatibleBitmap(
    HDC     hDC,        // デバイスコンテキストのハンドル
    int     nWidth,     // ビットマップの横幅
    int     nHeight     // ビットマップの高さ
);

オフ・スクリーンの作成

extern HDC funcCreateMemDC( HDC hDC, LONG sx, LONG sy, DWORD dwRop )
{
    HDC     hMemDC;
    HBITMAP hBitmap;
    
    hMemDC      = CreateCompatibleDC( hDC );
    hBitmap     = CreateCompatibleBitmap( hDC, sx, sy );
    SelectObject( hMemDC, hBitmap );
    SelectObject( hMemDC, GetStockObject(DC_PEN) );
    SelectObject( hMemDC, GetStockObject(DC_BRUSH) );
    DeleteObject( hBitmap );
    
    if ( dwRop != 0 ){
        PatBlt( hMemDC, 0, 0, sx, sy, dwRop );
    }
    return hMemDC;
}

オフ・スクリーンの破棄

extern BOOL funcDeleteMemDC( HDC hMemDC )
{
    return DeleteDC( hMemDC );
}

オフ・スクリーンのサイズ取得

extern BOOL funcGetSizeMemDC( HDC hMemDC, LONG *sx, LONG *sy )
{
    HGDIOBJ     hBitmap;
    BITMAP      BmpInfo;
    
    if ( (hBitmap = GetCurrentObject(hMemDC,OBJ_BITMAP)) != NULL ){
        GetObject( hBitmap, sizeof(BITMAP), &BmpInfo );
        *sx = BmpInfo.bmWidth;
        *sy = BmpInfo.bmHeight;
        return TRUE;
    }
    return FALSE;
}

使い方

//------------------------------------------------
// break付きのキーワード
//------------------------------------------------
#define CASE        break;case
#define DEFAULT     break;default

//------------------------------------------------
// 記号定数
//------------------------------------------------
#define MAX_WIDTH   (640)
#define MAX_HEIGHT  (480)

//------------------------------------------------
// ウインドウのプロシージャ関数
//------------------------------------------------
LRESULT CALLBACK mainWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    static HDC hMemDC;
    
    switch ( uMsg ){
        CASE WM_CREATE:
        {
            HDC hDC;
            
            // DCコンパチブルの作成
            hDC     = GetDC( hWnd );
hMemDC = funcCreateMemDC( hDC, MAX_WIDTH, MAX_HEIGHT, WHITENESS );
ReleaseDC( hWnd, hDC ); } CASE WM_CLOSE: // DCコンパチブルの破棄
funcDeleteMemDC( hMemDC );
DestroyWindow( hWnd ); CASE WM_DESTROY: PostQuitMessage( 0 ); CASE WM_PAINT: { HDC hDC; PAINTSTRUCT ps; LONG sx; LONG sy; // DCコンパチブルの描画 hDC = BeginPaint( hWnd, &ps );
funcGetSizeMemDC( hMemDC, &sx, &sy );
BitBlt( hDC, 0, 0, sx, sy, hMemDC, 0, 0, SRCCOPY ); EndPaint( hWnd, &ps ); } CASE WM_ERASEBKGND: // 何も処理しない⇒塗り潰した return 1; CASE WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: { UINT cx = (SHORT)LOWORD(lParam); UINT cy = (SHORT)HIWORD(lParam); SetDCPenColor( hMemDC, RGB(0xFF,0xFF,0x00) ); SetDCBrushColor( hMemDC, RGB(0x00,0x00,0xFF) ); Rectangle( hMemDC, cx, cy, (cx + 16*5), (cy + 16*3) ); InvalidateRect( hWnd, NULL, FALSE ); UpdateWindow( hWnd ); } CASE WM_RBUTTONUP: PatBlt( hMemDC, 0, 0, MAX_WIDTH, MAX_HEIGHT, WHITENESS ); InvalidateRect( hWnd, NULL, FALSE ); UpdateWindow( hWnd ); DEFAULT:return DefWindowProc( hWnd, uMsg, wParam, lParam ); } return 0; }

解説

  • WM_CREATEメッセージで funcCreateMemDC() 関数によりオフ・スクリーンを作成してます。
  • WM_CLOSEメッセージで funcDeleteMemDC() 関数によりオフ・スクリーンを破棄してます。
  • WM_PAINTメッセージで funcGetSizeMemDC() 関数によりオフ・スクリーンのサイズを取得してます。
  • WM_LBUTTONDOWNメッセージなどで長方形をオフ・スクリーンに描画してWM_PAINTメッセージで再描画させます。
  • WM_RBUTTONUPメッセージでオフ・スクリーンを消去してます。

関連記事


コメント (2)    この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« MSDNライブラリ(日本語版) | トップ | 赤坂玲音(ゼロからはじめるC... »
最新の画像もっと見る

2 コメント

コメント日が  古い順  |   新しい順
はじめまして。 (泥酔天婆)
2012-10-30 06:02:41
無謀にもプログラム言語など作ろうとしてる底辺プログラマでございます。この度ちらつき防止の勉強をしていたところ、ここに行き着きました。

方法1.2.そしてこのページの関数型と3つ見ましたが、ここの方法が一番自分のところに合ってる気がしますので使わせていただきますね。

返信する
泥酔天婆さんへ (ブログ管理人)
2012-10-30 22:07:10
はじめまして。

> 無謀にもプログラム言語など作ろうとしてる底辺プログラマでございます。
良いですね。
私も昔(1998年)にゲーム言語を製作しました。
ドラクエ風のRPGゲームで処理するゲーム言語(スクリプト言語)です。

> この度ちらつき防止の勉強をしていたところ、ここに行き着きました。
そうでしたか。

> 方法1.2.そしてこのページの関数型と3つ見ましたが、
> ここの方法が一番自分のところに合ってる気がしますので使わせていただきますね。
どうぞ。
C++を知ってるのならばクラスと作成すると便利ですよ。
返信する

コメントを投稿

グラフィック関連」カテゴリの最新記事