サンプルコードのダウンロード
では、まずサンプルコードをダウンロードし、解凍してください。
私はVisual C++6.0でコンパイルしているので、お持ちの方はVisual C++でプロジェクトファイルを開いてください(「effec_05.dsw」をダブルクリックすれば開けます)。
圧縮ファイルに含まれる「effec_05.exe」をダブルクリックし、実行してみてください(何かキーを押すと終了します)。
どうでしょう?画面が切り替わり、写真が表示され、その明度が徐々に変わっていくのが解ると思います。
というわけで、今回はパレットを操作して画像のメイドを変更するぜっ!(壊
明度のお勉強
さて、明度を変更するというテクニックはよく見かけますよね?
例えばゲームで何か表示していて、次のシーン(場面)に移りたい場合に、画面を段々暗くし(フェード・アウト)、画面が真っ暗な間に次の画像を読み込んでおき(まだ表示はしない)準備が終わったら段々明るくしていき(フェード・イン)新しいシーンが始まる・・・というのがあります。
まず、こういったものは「パレットを操作」して明度を変更していると考えて良いでしょう。
というか、256色環境で明度を変更する方法はパレット操作以外まず無いです(近似色検索という解答は未定義)。
では、パレットをどうやって変化させたらいいか、についでですが、簡単です。
明るくしたければ各RGB値を増やしてやればいいし、暗くしたければRGB値を減らしてやればいいのです。
例えばRGB値が(100,25,30)だとして、1明るくしたいのなら各RGB値に1を足して(101,26,31)という感じ。
ただ、ここで注意してもらいたいのが、各RGB値は0~255でなければならないと言うことです。255を越えた場合は255、0より小さくなった場合は
0という風にです。あとはこの作業を256色パレット全てに行えばいい・・・はずですが、
パレット0番と255番は白・黒固定色なので、それ以外を全て変更すればいいのです。
今回はもうちょっと突っ込んでおきましょうかね。
例えば
int bright=50; //明度を変更する値(50は適当 BYTE red=230; //パレットの値(赤のみ) BYTE = unsigned char red+=bright; if(red>255) red=255; if(red<0) red=0;
というような事はしないようにしてくださいね。
今週のコードチェック(壊
今回の主なコードはコレ。
略
//----------[ パレットの明るさ変更 ]------------------------------------------------------------
//面倒なのでマクロでやってまう(良い子はマネしないでね)
#define SET_PAL(dest,src,bright) do{int v=src+bright;if(v>255)v=255;if(v<0)v=0;dest=v;}while(0)
void SetPaletteBright(int bright){
PALETTEENTRY pal_tmp[256];
for(int i=1;i<255;i++){ //0:黒固定 1:白固定
SET_PAL(pal_tmp[i].peRed ,peEntry[i].peRed ,bright);
SET_PAL(pal_tmp[i].peGreen,peEntry[i].peGreen,bright);
SET_PAL(pal_tmp[i].peBlue ,peEntry[i].peBlue ,bright);
}
//垂直帰線待ち(ちらつき防止)
VsyncWait();
//更新
lpPalette->SetEntries(0,1,254,&pal_tmp[1]);
}
パレットの設定については「DirectDraw基礎 第6回」でやりました。
また垂直帰線については「DirectDraw基礎 第14回」でやりました。
略
//----------[ メイン関数 ]----------------------------------------------------------------------
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow){
略
//DirectDraw開始
StartDirectDraw(hw);
//パレット設定
LoadPalette("bridge.bmp");
//ビットマップをバックバッファへ読み込む
LoadBitmap(lpBack,"bridge.bmp",0,0,320,240);
//フリッピング(画面へ表示)
Flip();
DWORD tim;
int bright=0,b_add=1;
while(1){
//疑似タイマー処理
tim=timeGetTime();
//明るさ変更
bright+=b_add;
if(bright6gt;=255 || bright<=-255)
b_add=-b_add;
SetPaletteBright(bright);
do{
//メッセージループ
while(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)){
if(!GetMessage(&msg,NULL,0,0))
Quit();
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}while(timeGetTime()<tim+16); //1000/60=16.666(60FPS)
}
return(FALSE);
}
見て解るとおり、一度画面に写真を表示したら、後はパレットを変更しているだけです。
明度を変更する関数でマクロを使ってしまったので、初心者にはちょっと解りにくいかもしれませんが、これを機、マクロの勉強をしてみてください。マクロを使うとホント楽なので・・・
あ、ちなみにビデオカードによっては、この「パレットを設定」する時間がやたらかかるものがあるので、「パレットを使えば高速に出来る!」とか思いこまないようにしてください。







