ラスタオペレーション


ROPと描画

高度な描画操作の一つとして、ラスタオペレーションがあります
今回は、これを説明しましょう //高度なグラフィックシステムの開発に必ず役に立つでしょう

ピクセルの描画は、描画される前にある二つの値が比較されます
それは、描画される色(ソース)と画面の色(ディスティネーション)です

簡単に考えて、白を0黒を1として比較すれば
描画しようとしている色と画面の色を比較して、その結果で描画命令を実行するとすれば
ピクセルレベルの操作を全体的に、しかも簡易に行うことができるのです

このようなピクセルレベルのビットの操作をラスタオペレーション(ROP)と呼ばれ
2つのピクセルを操作することをバイナリラスタオペレーション(ROP2)と呼びます
2つのピクセルとは、描画する色と画面の色の二つです

さて、このラスタオペレーションで一体何ができるのでしょうか
例えば、画面の色が白の時は黒を出力し、画面の色が黒の時は白を出力するというような
排他的な論理演算による操作などは、このラスタオペレーションで行うことができます

ラスタオペレーションの設定をするにはSetROP2()ファンクションを使います
ただし、この設定はラスタデバイスのみで有効です //ディスプレイはラスタデバイス

int SetROP2(HDC hdc , int fnDrawMode);

hdcには、デバイスコンテキストのハンドルを指定します
fnDrawModeには、前景モードを定数で指定します
戻り値は、以前設定されていた前景モード、失敗した時は0を返します

これは、デフォルトでR2_COPYPENになっています
R2_COPYPENは、画面の色に描画色を重ね、同色の場合はそのままにします
例えばこの動作を反転させるにはR2_NOTCOPEPENに設定します
すると描画する色と反転した色になります

また、R2_XORPENなども非常に便利です
これは、描画する色と画面の色が同じ場合はその色を反転するというものです
他の定数はこのページの下部のリファレンスを参照してください
#include <windows.h>

LRESULT CALLBACK WndProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp) {
	HDC hdc;
	PAINTSTRUCT ps;

	switch (msg) {
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	case WM_PAINT:
		hdc = BeginPaint(hwnd , &ps);
		SetROP2(hdc , R2_XORPEN);
		Rectangle(hdc , 10 , 10 , 200 , 50);
		Ellipse(hdc , 100 , 25 , 300 , 100);
		EndPaint(hwnd , &ps);
		return 0;
	}
	return DefWindowProc(hwnd , msg , wp , lp);
}

int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance ,
			PSTR lpCmdLine , int nCmdShow ) {
	HWND hwnd;
	MSG msg;
	WNDCLASS winc;

	winc.style		= CS_HREDRAW | CS_VREDRAW;
	winc.lpfnWndProc	= WndProc;
	winc.cbClsExtra	= winc.cbWndExtra	= 0;
	winc.hInstance		= hInstance;
	winc.hIcon		= LoadIcon(NULL , IDI_APPLICATION);
	winc.hCursor		= LoadCursor(NULL , IDC_ARROW);
	winc.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);
	winc.lpszMenuName	= NULL;
	winc.lpszClassName	= TEXT("KITTY");

	if (!RegisterClass(&winc)) return -1;

	hwnd = CreateWindow(
			TEXT("KITTY") , TEXT("Kitty on your lap") ,
			WS_OVERLAPPEDWINDOW | WS_VISIBLE ,
			CW_USEDEFAULT , CW_USEDEFAULT ,
			CW_USEDEFAULT , CW_USEDEFAULT ,
			NULL , NULL , hInstance , NULL
	);

	if (hwnd == NULL) return -1;

	while(GetMessage(&msg , NULL , 0 , 0)) DispatchMessage(&msg);
	return msg.wParam;
}


同色のピクセルは反転されているのがわかりますね
このように、ピクセルの描画を相対的に論理演算して操作することができます

現在の前景モードを得るにはGetROP2()を用いてください


SetROP2()

int SetROP2(HDC hdc , int fnDrawMode);

前景モードを設定します

hdc - デバイスコンテキストのハンドルを指定します
fnDrawMode - 前景モードを指定します

戻り値 - 以前の前景モードの値を返します。失敗した時は0

前景モードは、次の定数から指定します

定数解説
R2_BLACK ピクセルは、常に 0 です
R2_COPYPEN ピクセルは、描画する色です
R2_MASKNOTPEN ピクセルは、画面の色と、描画する色を反転した色の
両方に共通な色の組み合わせです
R2_MASKPEN ピクセルは、描画する色と、画面の色の
両方に共通な色の組み合わせです
R2_MASKPENNOT ピクセルは、描画する色と、画面の色の
両方に共通な色の組み合わせです
R2_MERGENOTPEN ピクセルは、画面の色と、描画する色を反転した色の組み合わせです
R2_MERGEPEN ピクセルは、描画する色と、画面の色の組み合わせです
R2_MERGEPENNOT ピクセルは、描画する色と、画面の色を反転した色の組み合わせです
R2_NOP ピクセルは、変更されません
R2_NOT ピクセルは、スクリーンの色を反転した色です
R2_NOTCOPYPEN ピクセルは、描画する色を反転した色です
R2_NOTMASKPEN ピクセルは、R2_MASKPEN の色を反転した色です
R2_NOTMERGEPEN ピクセルは、R2_MERGEPEN の色を反転した色です
R2_NOTXORPEN ピクセルは、R2_XORPEN の色を反転した色です
R2_WHITE ピクセルは、常に 1 です
R2_XORPEN ピクセルは、描画する色と、画面の色との組み合わせですが
両方に共通する色は除きます

GetROP2()

int GetROP2(HDC hdc);

指定したデバイスコンテキストの前景モードを返します

hdc - デバイスコンテキストのハンドルを指定します

戻り値 - 成功すると前傾モードを表す数値、失敗すると0



前のページへ戻る次のページへ