まず、下記のソースコード(約150行)を実行してください。
そして、実行結果が次を満たしているかを確認してください。
1) 上の二つは完全に一致している。
2) 上の二つと一致するものは下の三つにはない。
これらが成り立っている前提で、次の要望は受け付けてもらえますでしょうか。
『GraphBlend 系 ではなく SetDrawBlendMode を使って中央上を実現させたい』
あるいは、ほかに簡単に実現する方法はありますでしょうか。
要望の理由:
α付き画像複数から新しいα付き画像一枚を作りたい。
GraphBlend 系 には DrawTurn/Rota/ModiGraph に相当するものがなくて不便。
DX_BLENDMODE_ALPHA (左下) や DX_BLENDMODE_HALF_ADD(中央下) が役に立たない。
よろしくお願いいたします。
#include "DxLib.h"
const int numOfSrcs = 4;
int sources[ numOfSrcs ];
int backGround;
int tempScreen;
//
// 貼り付けたい大元のαチャンネル付き画像を作ります。
//
void makeSources()
{
for ( int c = 0; c < numOfSrcs; ++c )
{
sources[ c ] = MakeScreen( 100, 100, TRUE );
FillGraph( sources[ c ], 0, 0, 0, 0 );
SetDrawScreen( sources[ c ] );
for ( int i = 0; i < 50; ++i )
{
int v = ( 25 - i ) * 255 / 25;
if ( v < 0 ) { v = -v; }
int vs = v / 4;
int cc = 0;
switch ( c )
{
case 0: cc = GetColor( v, vs, v ); break;
case 1: cc = GetColor( vs, v, vs ); break;
case 2: cc = GetColor( v, vs, vs ); break;
case 3: cc = GetColor( v, v, vs ); break;
}
DrawCircle( 50, 50, 50 - i, cc, TRUE );
}
}
}
//
// 背景用の画像を作ります。
//
void makeBackground()
{
backGround = MakeScreen( 200, 480, TRUE );
SetDrawScreen( backGround );
for ( int i = 0 ; i < 12 ; ++i )
{
for ( int j = 0 ; j < 4 ; ++j )
{
const int c = GetColor( 192, i % 2 == j % 2 ? 192 : 255, 192 );
DrawBox( j*50, i*40, j*50+50, i*40+40, c, TRUE );
}
}
}
//
// αチャンネル付き画像を別のαチャンネル付き画像に貼り付けます。
// 描画先は SetDrawScreen() で指定したものを自動的に取得します。
// 貼り付ける寸法は srcHandle の大きさそのものになります。
//
void copyByGraphBlendRect( int dstX, int dstY, int srcHandle, int ratio, int dummy )
{
int width, height;
GetGraphSize( srcHandle, &width, &height );
GraphBlendRectBlt( tempScreen, srcHandle, tempScreen,
dstX, dstY, dstX + width, dstY + height,
0, 0,
dstX, dstY,
ratio, DX_GRAPH_BLEND_NORMAL_ALPHACH );
}
//
// copyByGraphBlendRect と同じ結果を求めようとしています。
// が、現在ある合成方法では成功するものがありません。
//
void copyByBlendMode( int dstX, int dstY, int srcHandle, int ratio, int blendMode )
{
SetDrawBlendMode( blendMode, ratio );
DrawGraph( dstX, dstY, srcHandle, TRUE );
}
typedef void (funcType)( int, int, int, int, int );
void drawGraphs( int startAlpha, funcType* ptr, int param )
{
int alpha = startAlpha;
const int e = numOfSrcs - 1;
for ( int c = 0; c < numOfSrcs; ++c, alpha = ( alpha + 64 ) % 256 )
{
(*ptr)( ( e - c ) * 30, ( e - c ) * 40, sources[ c ], alpha, param );
}
}
void drawGraphsWithTempScreen( int x, int y, int startAlpha, funcType* ptr, int param )
{
SetDrawScreen( tempScreen );
FillGraph( tempScreen, 0, 0, 0, 0 );
drawGraphs( startAlpha, ptr, param );
SetDrawScreen( DX_SCREEN_BACK );
SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 255 );
DrawGraph( x, y, tempScreen, TRUE );
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
ChangeWindowMode( TRUE );
SetGraphMode( 640, 480, 32, 60 );
DxLib_Init();
makeSources();
makeBackground();
tempScreen = MakeScreen( 320, 240, TRUE );
int offset = 0;
while ( -1 != ProcessMessage() && 0 == CheckHitKeyAll() )
{
SetDrawScreen( DX_SCREEN_BACK );
SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 255 );
DrawGraph( 0, 0, backGround, FALSE );
DrawGraph( 200, 0, backGround, FALSE );
DrawGraph( 400, 0, backGround, FALSE );
const int startAlpha = 255 - GetNowCount() / 25 % 255;
// 左上 ( 目標画像 )
SetDrawScreen( DX_SCREEN_BACK );
drawGraphs( startAlpha, ©ByBlendMode, DX_BLENDMODE_ALPHA );
// 左中 ( 合成に成功 )
drawGraphsWithTempScreen( 200, 0, startAlpha, ©ByGraphBlendRect, 0 );
// 左下・中下・右下 ( すべて合成に失敗 )
const int bm[ 3 ] = {
DX_BLENDMODE_ALPHA, DX_BLENDMODE_HALF_ADD, DX_BLENDMODE_SRCCOLOR
};
for ( int t = 0; t < 3; ++t )
{
drawGraphsWithTempScreen( t * 200, 240, startAlpha, ©ByBlendMode, bm[ t ] );
}
ScreenFlip();
}
DxLib_End();
}