SetUseBackBufferTransColorFlag を使用して透過ウインドウを使用する際に半透明のものを描画する場合は、
「乗算済みアルファ」を使用しないと半透明描画したものについて正常な結果を得ることができません
< 半透明のものを透過ウインドウで綺麗に表示する手順 >
1.MakeScreen でアルファチャンネル付きの「描画対象にできる( SetDrawScreen の引数として渡せる )グラフィックハンドル」を作成
2.3Dモデルファイルを読み込み、MV1SetUseDrawMulAlphaColor( 3Dモデルハンドル, TRUE ) ; を実行して、描画時に
描画するピクセルのRGB値( カラー値 )に対してA値( アルファ値 )を乗算するようにする
3.画像ファイルを読み込む( LoadGraph を呼び出す )前に SetUsePremulAlphaConvertLoad( TRUE ) ; を実行しておいて、
読み込み時に画像の各ピクセルの RGB値に対してA値を乗算するようにしてから LoadGraph で画像ファイルを読み込む
( こうすることで読み込まれた画像は「乗算済みアルファ形式の画像」となります )
4.MakeARGB8ColorSoftImage で画面と同じ大きさのソフトイメージハンドルを作成しておく
5.SetTransColor で透過ウインドウの透過色として使用される色を設定する
( ただし今回の手法ではアルファ値を使用して透過させるので、なるべく使用されない色を透過色にする必要があります )
6.描画先を SetDrawScreen を使用して1で作成したグラフィックハンドルにする
7.メインループ開始
8.ClearDrawScreen で画面クリア( クリアカラーはデフォルトの R=0 G=0 B=0 A=0 である必要があります )
9.3Dモデルは MV1DrawModel で普通に描画
10.画像は「乗算済みアルファ形式の画像」専用の描画ブレンドモード DX_BLENDMODE_PMA_ALPHA に変更してから描画
11.描画結果を GetDrawScreenSoftImage で 4 で作成したソフトイメージハンドルに取り込む
12.UpdateLayerdWindowForPremultipliedAlphaSoftImage に 4 で作成したソフトイメージハンドルを渡して透過ウインドウの表示内容更新
13.7に戻る
乗算済みアルファについて詳しくはこちらをご覧ください
http://homepage2.nifty.com/natupaji/DxLib/lecture/PremulAlpha/PremulAlpha.html
あと、上記の説明で登場する MV1SetUseDrawMulAlphaColor という関数は今回追加した関数ですので、
お手数で申し訳ありませんがこちらのバージョンをダウンロードしてお使いください m(_ _)m
http://homepage2.nifty.com/natupaji/DxLib/DxLibVCTest.exe // VisualC++ 用
http://homepage2.nifty.com/natupaji/DxLib/DxLibBCCTest.exe // BorlandC++ 用
http://homepage2.nifty.com/natupaji/DxLib/DxLibGCC_DevCppTest.exe // Dev-C++ 用
http://homepage2.nifty.com/natupaji/DxLib/DxLibGCC_MinGWTest.exe // MinGW 用
http://homepage2.nifty.com/natupaji/DxLib/DxLibDotNet.zip // .NET用
http://homepage2.nifty.com/natupaji/DxLib/DxLibMakeTest.exe // ソース
(中身を既存のライブラリのファイルに上書きして、BCCをお使いの
場合は『再構築』を、VCをお使いの場合は『リビルド』を、
Dev-C++をお使いの方は「Rebuild All(Ctrl+F11)」をして下さい)
あと、上記の説明に沿って実際にプログラムを組んでみました
2D画像と3Dモデルの透明度を変化させつつ描画するサンプルです
よろしければご覧ください
#include "DxLib.h"
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
int ModelHandle ;
int GraphHandle ;
int ScreenHandle ;
int SoftImageHandle ;
int AlphaAdd ;
int Alpha ;
// ウインドウモードで起動
ChangeWindowMode( TRUE );
// 透過ウインドウ設定
SetUseBackBufferTransColorFlag( TRUE ) ;
// DXライブラリの初期化
if( DxLib_Init() < 0 ) return -1 ;
// 描画対象にできるアルファチャンネル付き画面を作成
ScreenHandle = MakeScreen( 640, 480, TRUE ) ;
// 画像を読み込む際にアルファ値をRGB値に乗算するように設定する
SetUsePremulAlphaConvertLoad( TRUE ) ;
// 画像の読み込み
GraphHandle = LoadGraph( "Test1.bmp" );
// 画面取り込み用のソフトウエア用画像を作成
SoftImageHandle = MakeARGB8ColorSoftImage( 640, 480 ) ;
// モデルの読み込み
ModelHandle = MV1LoadModel( "DxChara.x" );
// モデルの描画時にRGB値をA値で乗算する設定にする
MV1SetUseDrawMulAlphaColor( ModelHandle, TRUE ) ;
// 透過色を紫に設定
// ( 透過色の部分が強制的に透過されてしまうため、使用されにくい色に設定 )
SetTransColor( 255,0,255 ) ;
// 描画先を裏画面にする
SetDrawScreen( ScreenHandle ) ;
// カメラを設定
SetCameraPositionAndTarget_UpVecY( VGet( 0.0f, 750.0f, -900.0f ), VGet( 0.0f, 380.0f, 0.0f ) ) ;
SetCameraNearFar( 15.0f, 3800.0f ) ;
// メインループ
AlphaAdd = -2 ;
Alpha = 255 ;
while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 )
{
// 画面をクリア
ClearDrawScreen() ;
// アルファ値の変更
Alpha += AlphaAdd ;
if( Alpha <= 0 )
{
Alpha = 0 ;
AlphaAdd = 2 ;
}
else
if( Alpha >= 255 )
{
Alpha = 255 ;
AlphaAdd = -2 ;
}
// モデルの透明度を設定
MV1SetOpacityRate( ModelHandle, Alpha / 255.0f ) ;
// モデルの描画
MV1DrawModel( ModelHandle ) ;
// 描画ブレンドモードを乗算済みアルファにセット
SetDrawBlendMode( DX_BLENDMODE_PMA_ALPHA, Alpha ) ;
// 画像を描画
DrawGraph( 0, 0, GraphHandle, TRUE ) ;
// 描画先の画像をソフトイメージに取得する
GetDrawScreenSoftImage( 0, 0, 640, 480, SoftImageHandle ) ;
// 取り込んだソフトイメージを使用して透過ウインドウの状態を更新する
UpdateLayerdWindowForPremultipliedAlphaSoftImage( SoftImageHandle ) ;
// 少し待つ
Sleep( 12 ) ;
}
// DXライブラリの後始末
DxLib_End() ;
// ソフトの終了
return 0 ;
}