Re: MakeScreenで作った画面の初期化 ( No.6 ) |
- 名前:takatwu 日時:2013/07/07 22:15
さらに横槍失礼します。
単純に以下の通りではダメでしょうか?
SetDrawScreen( Handle );
ClearDrawScreen();
|
Re: MakeScreenで作った画面の初期化 ( No.7 ) |
- 名前:管理人 日時:2013/07/08 09:43
こちらのようなテストプログラムを組んでみましたが、FillGraph で指定している
R,G,B の 128 の値が画面に表示されることはありませんでした
#include "DxLib.h"
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
int handle, screen;
ChangeWindowMode( TRUE );
if( DxLib_Init() < 0 ) return -1;
// アルファチャンネルつきの画面を作成
screen = MakeScreen( 640, 480, TRUE ) ;
// 画像の読み込み
handle = LoadGraph( "Test1.bmp" );
// 仮画面のクリア
SetDrawScreen( screen ) ;
FillGraph( screen, 128, 128, 128, 0 ) ;
// 仮画面に画像を描画
DrawGraph( 128, 0, handle, TRUE );
// 仮画面を裏画面に描画
SetDrawScreen( DX_SCREEN_BACK ) ;
DrawGraph( 0, 0, screen, TRUE ) ;
// 裏画面の内容を表画面に反映
ScreenFlip();
WaitKey() ;
DxLib_End();
return 0;
}
よろしければ spaaaark・∀・さんの環境でも正常に動作するか
お試しになってみて頂けないでしょうか?
|
Re: MakeScreenで作った画面の初期化 ( No.8 ) |
- 名前:spaaaark・∀・ 日時:2013/07/08 17:01
>Sura様
>takatwu様
>管理人様
皆様ご回答ありがとうございます。
大変申し訳ないのですが、この画面にも透明度を含む画像を描画しておりまして、
その際に背景の黒い画面を透過してしまい、結果が黒っぽく出力されてしまいます。
そこで、完全に色のない元の状態に戻したかったのですが、
SCRカラーを使った描画、ClearDrawScreen関数を使った初期化方法は、
すべてこの黒っぽくなる現象が発生してしまいました。
また、管理人様の実験した方法でも、鈴見咲君高様のFillGraph関数を使った
方法とほぼ同じ内容ですので、実装化するには難しいと思われます…。
|
Re: MakeScreenで作った画面の初期化 ( No.9 ) |
- 名前:鈴見咲君高 日時:2013/07/09 04:56
spaaaark・∀・さんに再現ソースコードを出してもらうのが
早いのかもしれませんが、もうちょっとエスパーしてみました。
MakeScreen で作ったビットマップにはαチャンネル付けたんだから
セル画の透明紙(?)のように動いてほしいのですが、実際にはそう
なってない、という話ではありませんか?
spaaaark・∀・さんがやりたいのはウィキペディア日本語版の
記事「アルファブレンド」に書いてある計算のうち dstA ≠ 0 の
場合であり、ところが実際の挙動は dstA = 1 固定である、と。
こうなると、実は最初の DeleteGraph と MakeScreen を繰り返し
呼び出していたバージョンの方が、実はバグとバグが重なって
たまたま想定通りに動いていた可能性があります。
解法としては次の二つ。
A) どうせ毎回書き直すのなら初めから最終描画先にα付き画像を
重ね塗りしていく
B) DXライブラリに相当のブレンドモードを追加してもらう
私もあったらいいなと思う機能なので別トピで改めて B) を求めて
みましょうかね…
|
Re: MakeScreenで作った画面の初期化 ( No.10 ) |
- 名前:鈴見咲君高 日時:2013/07/09 12:31
失敬…上記のエスパーによる仮定話ですけども、
SetDrawBlendMode( DX_BLENDMODE_HALF_ADD, 255 );
で実現できるようですね。
あと dstA ≠ 0 は dstA ≠ 1 の誤りでした。
失礼いたしました。
なので再び spaaaark・∀・さんの反応待ち。
|
Re: MakeScreenで作った画面の初期化 ( No.11 ) |
- 名前:spaaaark・∀・ 日時:2013/07/09 20:29
>鈴見咲君高様
ご回答ありがとうございます。
どうやら調べてみたところ、この描画方法には元画像を消す効果はないようです。
この方法でも、描画時に黒っぽく透過されてしまいました。
それで、今頃になって大変申し訳ないのですが、
サンプルソースの方を載せたいと思います。
#include "DxLib.h"
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
ChangeWindowMode(TRUE);
if(DxLib_Init()==-1) return -1;
int graph=LoadGraph("ts.png");
int back=LoadGraph("back.png");
int test=MakeScreen(320,240,TRUE);
SetDrawScreen(DX_SCREEN_BACK);
DrawGraph(0,0,back,FALSE);
//// 画像を描画(出力したい画像、左側)
SetDrawScreen(DX_SCREEN_BACK);
SetDrawBlendMode(DX_BLENDMODE_ALPHA,144);
DrawGraph(100,300,graph,TRUE);
ScreenFlip();
/*(描画元画面をリセットする処理を挿入)、下の処理ではうまくいきません*/
SetDrawBlendMode(DX_BLENDMODE_HALF_ADD,255);
FillGraph(test,0,0,0,0);
SetDrawScreen(test);
SetDrawBlendMode(DX_BLENDMODE_ALPHA,144);
DrawGraph(0,0,graph,TRUE);
//// 画像を描画(結果、右側)目的は左側=右側となる事
SetDrawScreen(DX_SCREEN_BACK);
SetDrawBlendMode(DX_BLENDMODE_ALPHA,255);
DrawGraph(150,300,test,TRUE);
ScreenFlip();
WaitKey();
DxLib_End();
return 0;
}
この結果の左側が、実際に得たい描画結果で、右側に描画されたものが、
鈴見咲君高様のおっしゃられた方法で初期化した場合です。
そして、このソースを書いているときに気が付いたのですが、
どうやらαチャンネルのある画面を作った初期状態でも、
この描画結果と同じ黒っぽい出力結果(右側)が表示されるようです。
この初期画面を含め色のない状態に初期化することってできないのでしょうか…。
|
Re: MakeScreenで作った画面の初期化 ( No.12 ) |
- 名前:鈴見咲君高 日時:2013/07/09 22:22
いやいやいや、DX_BLENDMODE_HALF_ADD の使い方はそうではなくて。
FillGraph の動作は SetDrawBlendMode の設定と関係ないですから。
今回は私の説明がまずいものでした、すみません。
お詫びと言っちゃなんですが、改造したソースコードを張り付けておきます。
『最初は透明度情報だけがあって、描画したとき描画した部分だけ色情報が付く』
という仕組みは存在しません。
MakeScreen( 幅, 高さ, TRUE ) で初期化されたグラフィックメモリは
全ピクセル完全透明の情報とともにもれなく黒の色情報がついてきます。
ですが、『描画元と描画先の透明度を考慮して適切な新しい色と透明度で
上書きする描画方法』はあって、それが
SetDrawBlendMode( DX_BLENDMODE_HALF_ADD, xxx )
なんです。あとはじっくり考えてみてくださいませ。では。
#include "DxLib.h"
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
ChangeWindowMode( TRUE );
if( DxLib_Init() == -1 ) return -1;
int graph = LoadGraph( _T( "ts.png" ) );
int back = LoadGraph( _T( "back.png" ) );
int test = MakeScreen( 320, 240, TRUE );
while ( -1 != ProcessMessage() && 0 == CheckHitKeyAll() )
{
// ここの alpha はお遊びなので深い意味はない
int alpha = 255 - GetNowCount() / 20 % 255;
if ( alpha < 64 ) { alpha = 255 - alpha*3; }
// 背景は毎回書き直す。
// (ScreenFlip 実行後の裏画面の内容は保証されていない)
SetDrawScreen( DX_SCREEN_BACK );
DrawGraph( 0, 0, back, FALSE );
// test が描画先になる時は
// test にαチャンネルがあるので
// DX_BLENDMODE_HALF_ADD を使う。
// DX_SCREEN_BACK が描画先になる時は
// DX_SCREEN_BACK にαチャンネルがないので
// DX_BLENDMODE_ALPHA を使う。
// 左側はα付き画像を直接描く
SetDrawScreen( DX_SCREEN_BACK );
SetDrawBlendMode( DX_BLENDMODE_ALPHA, alpha );
DrawGraph( 0, 100, graph, TRUE ); // graph → DX_SCREEN_BACK
// 右側は test を経由して描く
FillGraph( test, 0, 0, 0, 0 );
SetDrawScreen( test );
SetDrawBlendMode( DX_BLENDMODE_HALF_ADD, alpha );
DrawGraph( 0, 0, graph, TRUE ); // graph → test
SetDrawScreen( DX_SCREEN_BACK );
SetDrawBlendMode( DX_BLENDMODE_ALPHA, 255 );
DrawGraph( 320, 100, test, TRUE ); // test → DX_SCREEN_BACK
ScreenFlip();
}
DxLib_End();
return 0;
}
|
Re: MakeScreenで作った画面の初期化 ( No.13 ) |
- 名前:てらす 日時:2013/07/10 08:37
私もテストしてみました。テストに使用したソースコードは下に貼っておきます。
MakeScreenで作ったグラフィックは最初白いんですね。今まで黒だと思ってました。
そして、ClearDrawScreenはスクリーンのARGBの値を0にするんですね。
それを前提として、テストの結果から見るにDX_BLENDMODE_ALPHAは描画先に対して
描画元のα値を元に色をブレンドし、更に描画元のα値を上書きする。と言った感じの処理なんでしょうか。
裏画面はαチャンネルが存在しないため後半は無視されているようですが。
最初に描画元のα値を元にブレンドしているため、描画先に影響されて結果の色が変わっているんだと思います。
spaaaark・∀・さんはMakeScreenで作った直後のグラフィックなら大丈夫と言った感じの事を書いていますが、
それでも白っぽく濁っているはずです。
解決案としては、MakeScreenで作った直後でも一旦ClearDrawScreenして、鈴見咲君高さんが書いたように
DX_BLENDMODE_HALF_ADDでブレンドすることでしょうか。
黒い描画先に対しての加算ブレンドなら描画元の色はそのまま反映されますし、
このブレンド方法はα値も書き込んでくれるようなので。
(テストのC1の挙動についてはよくわかりません。α値も加算しているのでしょうか?)
最新のDxLibでは定義が消えてるので、もしかしたらバグか何かで使用できないようにしているのかもしれません。
しかしこの方法だと同じ描画先に2度以上の描画をすると狙った色が出ませんね。
この辺りは私も是非に解決方法が知りたいです。
だらだら考察しましたが、DX_BLENDMODE_ALPHAの挙動は、直感的ではないと私も思います。
更に上にも書きましたが、DX_BLENDMODE_HALF_ADDを使っても同じ描画先に2度以上の描画ができない点は、
半透明部分を持つ画像を複数重ねたい時など、致命的な場面が出てきそうな気がします。
MakeScreenで作ったグラフィックの色の初期値が白いのも気になります。
こちらはClearDrawScreenかFillGraphすればいい話なんですが。
以下はテストに用いたソースコードです。
#include "DxLib.h"
void TestRender( int drawScreenHandle, int color, int blendMode, int blendPalam, bool clearFrag ){
SetDrawScreen( drawScreenHandle );
if( clearFrag ) ClearDrawScreen();
SetDrawBlendMode( blendMode, blendPalam );
DrawBox( 0, 0, 100, 100, color, TRUE );
SetDrawBlendMode( DX_BLENDMODE_NOBLEND, NULL );
SetDrawScreen( DX_SCREEN_BACK );
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
ChangeWindowMode( TRUE );
if( DxLib_Init() == -1 ) return -1;
SetDrawScreen( DX_SCREEN_BACK );
int screenB = MakeScreen( 100, 100, TRUE );
int screenC = MakeScreen( 100, 100, TRUE );
int screenD1 = MakeScreen( 100, 100, TRUE );
int screenD2 = MakeScreen( 100, 100, FALSE );
int red = GetColor( 255, 0, 0 );
int strColor = GetColor( 0, 0, 0 );
int alpha = 144;
//色がわかりやすいように適当に模様を描画
for( int i=0; i<10; ++i ){
for( int j=0; j<13; ++j ){
if( i%2==j%2 ){
DrawBox( j*50, i*50, j*50+50, i*50+50, GetColor( 192, 192, 192 ), TRUE );
}else{
DrawBox( j*50, i*50, j*50+50, i*50+50, GetColor( 192, 255, 192 ), TRUE );
}
}
}
//裏画面に直接DX_BLENDMODE_ALPHAで描画・・・A1
SetDrawBlendMode( DX_BLENDMODE_ALPHA, alpha );
DrawBox( 0, 0, 100, 100, red, TRUE );
SetDrawBlendMode( DX_BLENDMODE_NOBLEND, NULL );
DrawString( 0, 0, "A1", strColor );
//裏画面に直接DX_BLENDMODE_HALF_ADDで描画・・・A2
//最新のテストバージョンではDX_BLENDMODE_HALF_ADDが定義されていなかったため
//定数を直接指定した
SetDrawBlendMode( 15, alpha );
DrawBox( 100, 0, 200, 100, red, TRUE );
SetDrawBlendMode( DX_BLENDMODE_NOBLEND, NULL );
DrawString( 100, 0, "A2", strColor );
//screenBはDX_BLENDMODE_ALPHAを使う
//最初のscreenBを経由した描画・・・B1
TestRender( screenB, red, DX_BLENDMODE_ALPHA, alpha, FALSE );
DrawGraph( 0, 100, screenB, TRUE );
DrawString( 0, 100, "B1", strColor );
//screenBをクリアし2回目のscreenBを経由した描画・・・B2
TestRender( screenB, red, DX_BLENDMODE_ALPHA, alpha, TRUE );
DrawGraph( 100, 100, screenB, TRUE );
DrawString( 100, 100, "B2", strColor );
//screenCはDX_BLENDMODE_HALF_ADDを使う
//最初のscreenCを経由した描画・・・C1
TestRender( screenC, red, 15, alpha, FALSE );
DrawGraph( 0, 200, screenC, TRUE );
DrawString( 0, 200, "C1", strColor );
//screenCをクリアし2回目のscreenCを経由した描画・・・C2
TestRender( screenC, red, 15, alpha, TRUE );
DrawGraph( 100, 200, screenC, TRUE );
DrawString( 100, 200, "C2", strColor );
//何も描画していないアルファチャンネル付きグラフィック・・・D1
DrawGraph( 0, 300, screenD1, TRUE );
DrawString( 0, 300, "D1", strColor );
//何も描画していないアルファチャンネル無しグラフィック・・・D2
DrawGraph( 100, 300, screenD2, TRUE );
DrawString( 100, 300, "D2", strColor );
//A1≠B1≠B2になり B1は白く曇り B2は黒ずんだ色になる
//C1は透過せず C2はA1と同じ色
//何も描画していないアルファチャンネル付き画像は白い
//何も描画していないアルファチャンネル無し画像も白い
ScreenFlip();
WaitKey();
DxLib_End();
return 0;
}
|
Re: MakeScreenで作った画面の初期化 ( No.14 ) |
- 名前:てらす 日時:2013/07/10 10:29
訂正
Dxlibが最新じゃありませんでした。
最新のDxlibにはDX_BLENDMODE_HALF_ADDが定義されていました。
申し訳ありません。
|
Re: MakeScreenで作った画面の初期化 ( No.15 ) |
- 名前:鈴見咲君高 日時:2013/07/12 19:01
てらすさんのテストコードを試してみました。
私の所ではてらすさんの場合とかなり異なり、
A1 = C1 = C2, B1 = B2, A1 ≠ B1,
B1 = B2 は A1 より黒っぽく、
D1 は背景のまま、D2 は真っ黒になっていました。
ただ、ご提供のテストコードにバグと思しき部分が複数見つかったので
書き直してみました。こちらをてらすさんの方でも試してもらえますか?
もちろんほかの方によるテスト報告も歓迎です。
・SetBackgroundColor( 0, 0, 255 ) のときに E1 = G1 になるか
・SetBackgroundColor( 0, 0, 0 ) のときに
E1 = G1 = G2, F1 = F2 (ただしもちろん E1 ≠ F1)になるか
特に上の二つをお知らせ頂きたいです。
他にはコード内のコメント通りに動いているかどうかなど。
今回の私の出すサンプルコード、ほとんどの挙動は自分では
納得できるのですが、F2 と G2 がいまいち理解できてません。
ですが、F2・G2 とも ClearDrawScreen で初期化しているので
そこがダメなんじゃないかな、と。
いまさらですがこちらの環境なども。
Windows 8 Pro with Media Center 64-bit (6.2, Build 9200) (9200.win8_gdr.130410-1505)
AMD A8-3820 APU with Radeon(tm) HD Graphics (4 CPUs), ~2.5GHz
Visual C++ 2010 Express Edition
(Microsoft Visual Studio 2010 Version 10.0.40219.1 SP1Rel)
DXライブラリは最終的に 3.10e で再確認しましたが、
3.10d や現在の試験版でも結果は同じだったと思います。
#include "DxLib.h"
void TestRender( int drawScreenHandle, int color, int blendMode, int blendPalam, bool useClearDrawScreen )
{
SetDrawScreen( drawScreenHandle );
// ClearDrawScreen は SetBackgroundColor の指定に従うことに注意。
// αチャンネルがつく場合は全てのαを 0 にするので
// 気にする必要がないはずだが、実際には高速化の関係で
// そうもいかないらしい。( WinMain 内の説明参照 )
if ( useClearDrawScreen ) { ClearDrawScreen(); }
else { FillGraph( drawScreenHandle, 0, 0, 0, 0 ); }
SetDrawBlendMode( blendMode, blendPalam );
DrawBox( 0, 0, 100, 100, color, TRUE );
SetDrawScreen( DX_SCREEN_BACK );
SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 255 );
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
ChangeWindowMode( TRUE );
// ClearDrawScreen の挙動を確認するためわざと派手な青にしておく
// 青ではなく黒 ( 0, 0, 0 ) を指定しておくと
// E1 = G1 だけでなく E1 = G1 = G2, F1 = F2 になる。
SetBackgroundColor( 0, 0, 255 );
if ( DxLib_Init() == -1 ) return -1;
SetDrawScreen( DX_SCREEN_BACK );
int screenB = MakeScreen( 100, 100, TRUE );
int screenD1 = MakeScreen( 100, 100, TRUE );
int screenD2 = MakeScreen( 100, 100, FALSE );
int red = GetColor( 255, 0, 0 );
int strColor = GetColor( 0, 0, 0 );
while ( -1 != ProcessMessage() && 0 == CheckHitKeyAll() )
{
// ここの alpha はお遊びなので深い意味はないが、
// いくらか比較しやすい変化にしてみたつもり。
int alpha = 255 - GetNowCount() / 40 % 255;
if ( alpha < 16 ) { alpha = 255 - alpha*15; }
// 色がわかりやすいように適当に模様を描画
SetDrawScreen( DX_SCREEN_BACK );
SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 255 );
for ( int i = 0 ; i < 10 ; ++i )
{
for ( int j = 0 ; j < 13 ; ++j )
{
const int c = GetColor( 192, i % 2 == j % 2 ? 192 : 255, 192 );
DrawBox( j*50, i*50, j*50+50, i*50+50, c, TRUE );
}
}
// 裏画面に直接DX_BLENDMODE_ALPHAで描画・・・E1
SetDrawScreen( DX_SCREEN_BACK );
SetDrawBlendMode( DX_BLENDMODE_ALPHA, alpha );
DrawBox( 0, 0, 100, 100, red, TRUE );
// 裏画面に直接DX_BLENDMODE_HALF_ADDで描画・・・E2
// しかし DX_BLENDMODE_HALF_ADD は
// 描画先にαチャンネルがあることが前提なので
// 論理的には『無意味な操作』である。
// 描画先のαチャンネルを考慮して合成したときに
// 適切な色となるよう RGB が書き込まれるので、
// αチャンネルのない E2 は E1 より白めの赤っぽくなる。
SetDrawScreen( DX_SCREEN_BACK );
SetDrawBlendMode( DX_BLENDMODE_HALF_ADD, alpha );
DrawBox( 100, 0, 200, 100, red, TRUE );
// screenB を FillGraph で初期化して
// その screenB を経由して DX_BLENDMODE_ALPHA で描画・・・F1
//
// 新しいαと新しい各色成分は次の式で値が決まる。
// ( ただしαは 0 から 255 を 0.0 から 1.0 に正規化する )
// 新α = α * α + 描画先旧α * ( 1.0 - α )
// 新描画先 = ( 描画元 * α * α + 旧描画先 * 描画先旧α * ( 1.0 - α ) ) / 新α
//
// FillGraph で 0, 0, 0, 0 を指定しているので
// A1 よりも透明寄りにαの効果がかかり、また黒っぽくなる。
TestRender( screenB, red, DX_BLENDMODE_ALPHA, alpha, false );
DrawGraph( 0, 100, screenB, TRUE );
// screenB を ClearDrawScreen で初期化して
// その screenB を経由して DX_BLENDMODE_ALPHA で描画・・・F2
//
// ClearDrawScreen は α=0 の SetBackgroundColor 指定色で
// 塗りつぶすらしい。
//
// RGBが何であろうと α=0 なのだから常に F1 = F2 になるはず
// だが、ウィキペディア日本語版の「アルファチャンネル」に
// 記された『...現にほとんどのビデオカード・グラフィックスライ
// ブラリは正確に保持していない。』にかかる高速化の関係で
// 青(青紫)っぽくなるらしい?( WinMain の最初の方で背景色に青を指定 )。
TestRender( screenB, red, DX_BLENDMODE_ALPHA, alpha, true );
DrawGraph( 100, 100, screenB, TRUE );
// screenB を FillGraph で初期化して
// その screenB を経由して DX_BLENDMODE_HALF_ADD で描画・・・G1
// すべての手続きが正しいので E1 と同じ結果になる。
TestRender( screenB, red, DX_BLENDMODE_HALF_ADD, alpha, false );
DrawGraph( 0, 200, screenB, TRUE );
// screenB を ClearDrawScreen で初期化して
// その screenB を経由して DX_BLENDMODE_HALF_ADD で描画・・・G2
//
// 新しいαと新しい各色成分は次の式で値が決まる。
// ( ただしαは 0 から 255 を 0.0 から 1.0 に正規化する )
// 新α = α + 描画先旧α * ( 1.0 - α )
// 新描画先 = ( 描画元 * α + 旧描画先 * 描画先旧α * ( 1.0 - α ) ) / 新α
//
// F1 に対する F2 と同じ理由で常に G1 = G2 になるはずだが、
// ここでは赤+青で紫(赤紫)っぽくなる。
TestRender( screenB, red, DX_BLENDMODE_HALF_ADD, alpha, true );
DrawGraph( 100, 200, screenB, TRUE );
// 何も描画していないアルファチャンネル付きグラフィック・・・H1
// すべて透明なのでなにも上書きされないはずだが白くなる環境がある?
SetDrawScreen( DX_SCREEN_BACK );
SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 255 );
DrawGraph( 0, 300, screenD1, TRUE );
// 何も描画していないアルファチャンネル無しグラフィック・・・H2
// screenD2 はαチャンネルなしの初期化なので真っ黒になるはずだが
// 真っ白になる環境がある?
SetDrawScreen( DX_SCREEN_BACK );
SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 255 );
DrawGraph( 100, 300, screenD2, TRUE );
// 字をまとめて書く
SetDrawScreen( DX_SCREEN_BACK );
SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 255 );
DrawString( 0, 0, _T( "E1" ), strColor );
DrawString( 100, 0, _T( "E2" ), strColor );
DrawString( 0, 100, _T( "F1" ), strColor );
DrawString( 100, 100, _T( "F2" ), strColor );
DrawString( 0, 200, _T( "G1" ), strColor );
DrawString( 100, 200, _T( "G2" ), strColor );
DrawString( 0, 300, _T( "H1" ), strColor );
DrawString( 100, 300, _T( "H2" ), strColor );
ScreenFlip();
}
DxLib_End();
return 0;
}
--------------------------------------------------------------------------------------
(後日追記、No.19 から No.21 の記事投稿の流れも参照)
…とソースコードになにやらいろいろ書いていますが、
実は DX_BLENDMODE_SRCCOLOR ならば確実に実行できるようです。
「字をまとめて書く」の直前あたりにでも次の4行を入れてみてください。
E1, E2 の右隣で E1=G1 と同じ色が再現されます。
TestRender( screenB, red, DX_BLENDMODE_SRCCOLOR, alpha, false );
DrawGraph( 200, 0, screenB, TRUE );
TestRender( screenB, red, DX_BLENDMODE_SRCCOLOR, alpha, true );
DrawGraph( 300, 0, screenB, TRUE );
--------------------------------------------------------------------------------------
(再追記)
追加したコード自体は期待通りに動作いたしますが、α付き画像を複数枚重ねようとすると
正しく動作しないことがわかりました。No.22 の発言も参照ください。
|
Re: MakeScreenで作った画面の初期化 ( No.16 ) |
- 名前:鈴見咲君高 日時:2013/07/10 21:29
先の私が出した二つ目のテストコードでもいろいろ書きましたけど、
いちおうてらすさんの本文にもお返事。一部のみですが。
>MakeScreenで作ったグラフィックは最初白いんですね。今まで黒だと思ってました。
いいえ。私の環境では過去も現在も黒です。
ですが、別トピックで情報を求めている方がいらっしゃるので
↓そちらで連絡を取ってみてはいかがでしょうか。
h ttp://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=view&no=3076
>そして、ClearDrawScreenはスクリーンのARGBの値を0にするんですね。
いいえ。SetBackgroundColor の説明をご覧ください。
αチャンネルがある場合はどうなるのか、について書かれていないのですが、
調べた感じαチャンネルはすべて 0 にされてしまうようです。
論理的にはαチャンネルが 0 ならば RGB は何であっても
完全に無視されるはずですが、どうもそうはなっていないようで、
今回の案件に関する限り ClearDrawScreen は封印した方がよさそうです。
>spaaaark・∀・さんはMakeScreenで作った直後のグラフィックなら大丈夫と言った感じの事を書いていますが、
>それでも白っぽく濁っているはずです。
白っぽくなるかどうかは別として、すでにテストコードを出して
頂いたときにspaaaark・∀・さんがそのようなコメントをされていますね。
>だらだら考察しましたが、DX_BLENDMODE_ALPHAの挙動は、直感的ではないと私も思います。
このあたりは同意できます。描画先にαチャンネルがないことが前提、ということが
伝わってこないですよね。あと HALF_ADD 、半加算なる表現も何を言いたいのか
さっぱりわからない…ですがこれは表現上の問題ということで。
|
Re: MakeScreenで作った画面の初期化 ( No.17 ) |
- 名前:spaaaark・∀・(解決です) 日時:2013/07/10 22:59
>鈴見咲君高様
>てらす様
>Sura様
>takatwu様
>管理人様
半加算ブレンドを使用することにより、現在私が求めていた機能は実装できましたので、
ご報告させていただきます。非常にたくさんの意見を誠にありがとうございました。
僕の環境では、どうやらMakeScreenで取得した状態の画面の色は黒になっているようで、
それが通常のαブレンドで透過されてしまう、そしてそれを裏画面に描画したとき、
その結果が黒く表示されてしまう、というものでした。
よく考えてみると、最初のDeleteGraph関数で、なぜうまくいったかは謎ですね…。
ペイントソフトなどを使っている時に、よくpng形式でαブレンド(a≠255)を残したまま
画像を保存する、というような考えがこちらでも通用すると考えていましたので、
このようなバグを招く結果となりました。
僕個人としては、やはり完全な色のない画面を作れるような関数は欲しいと思いましたが、
求めていた描画結果が得られたため、これで制作を続行しようと思います。
皆様ありがとうございました。
|
Re: MakeScreenで作った画面の初期化 ( No.18 ) |
- 名前:てらす(解決済み) 日時:2013/07/11 06:51
>鈴見咲君高さん
提供していただいたサンプルコードでテストしてみました。
>・SetBackgroundColor( 0, 0, 255 ) のときに E1 = G1 になるか
E1 = G1になっています。
>・SetBackgroundColor( 0, 0, 0 ) のときに
> E1 = G1 = G2, F1 = F2 (ただしもちろん E1 ≠ F1)になるか
これも仰るとおりです。
描画先全体のARGB値がすべて0なら
DX_BLENDMODE_HALF_ADDで大丈夫なようですね。
前回も書きましたが問題はARGB値が0でないピクセルがある場合は
どうするかってところですかね。
私は制作するゲームのレギュレーションに合わせた画像を作るときにMakeScreenと
SaveDrawScreenToPNGを使って画像を変換したりしているので問題が起きそうです。
まあ問題が起きそうなら、その時は新しいトピックでも立てます。
また、コード中のコメントにもありますが、私の環境ではH1,H2は真っ白になります。
提示していただいたトピックの方にも情報を書き込んでこようと思います。
一応、以下が私の環境です。
Windows 7 Home Premium 64-bit (6.1, Build 7601) Service Pack 1 (7601.win7sp1_gdr.130318-1533)
Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz (8 CPUs), ~3.4GHz
NVIDIA GeForce GTX 660 (Driver Version: 9.18.13.1422)
Visual Studio 2010 Professional (Version: 10.0.40219.1 SP1Rel)
DXライブラリのバージョンは3.10fで試しました。
>spaaaark・∀・さん
MakeScreenで作った直後のグラフィックの色に関して、書き込みがあったんですね。
書き込みをよく読まずに適当なことを言ってすいませんでした。
P.S.
すでに解決済みとなっているため、HNに(解決済み)をつけておきます。
|
Re: MakeScreenで作った画面の初期化 ( No.19 ) |
- 名前:いっち(解決?) 日時:2013/07/11 18:51
すでに解決なさったとの事で喜ばしいのですが、私はちょっとモヤモヤしています。
spaaaark・∀・さんのご要望を私がうまく理解できていないだけなのかもしれませんが、
DX_BLENDMODE_SRCCOLOR の使用もご検討なさってみてはいかがでしょうか?
非常に今更なのですが、(No.11)のソースは以下のような感じでうまくいくのではないかと思います。
//-- 以下、テストコード -//
#include "DxLib.h"
int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{
ChangeWindowMode(TRUE);
if(DxLib_Init()==-1) return -1;
int graph=LoadGraph("ts.png");
int back=LoadGraph("back.png");
int test=MakeScreen(320,240,TRUE);
SetDrawScreen(DX_SCREEN_BACK);
ClearDrawScreen();
DrawGraph(0,0,back,FALSE);
//// 画像を描画(出力したい画像、左側)
SetDrawScreen(DX_SCREEN_BACK);
SetDrawBlendMode(DX_BLENDMODE_ALPHA,144);
DrawGraph(100,300,graph,TRUE);
/*(描画元画面をリセットする処理?を挿入)、DX_BLENDMODE_SRCCOLOR使用*/
SetDrawScreen(test);
ClearDrawScreen();
SetDrawBlendMode(DX_BLENDMODE_SRCCOLOR,144); //<- ※ここを255で
DrawGraph(0,0,graph,TRUE);
//// 画像を描画(結果、右側)目的は左側=右側となる事
SetDrawScreen(DX_SCREEN_BACK);
SetDrawBlendMode(DX_BLENDMODE_ALPHA,255); //<- ※こっちを144でもいけるはず
DrawGraph(150,300,test,TRUE);
ScreenFlip();
WaitKey();
DxLib_End();
return 0;
}
|
Re: MakeScreenで作った画面の初期化 ( No.20 ) |
- 名前:鈴見咲 君高 日時:2013/07/12 18:59
(再訂正)
実はこちらの発言、妄想かどうかはともかくとして
DX_BLENDMODE_SRCCOLOR が使えないことに関しては正しいことがわかりました。
(No.22 を参照ください)
====================================================================
当初下のように書き込んでいましたが、このお返事は的外れなものです。
(直後の No.21 参照)
--------------------------------------------------------------------
> いっちさん
いえ、おそらくそういう話ではないと思います。
いっちさんの考えているやり方だと、graph → test → DX_SCREEN_BACK
ではなく graph → DX_SCREEN_BACK で処理したらいいよね? で
話が終わってしまいます。
つまり、わざわざ test を経由しなくてはならない理由があると思うんです。
例えば、複数のα付き画像 graph, graph2, graph3, ... を何枚も合成して
新しい一枚の半透明画像 test を作り、それを 1 フレームに 1 回ではなく
多数回、DX_SCREEN_BACK にぺったんぺったん貼り付けたい、とか。
しかも test 上に作る画像はリアルタイムで変化すると。
もちろん貼り付けたい先に繰り返し graph, graph2, graph3, ... を
重ねる方法もありますが、いくらかでも速度を稼ぎたいと思うのは無理からぬ
ことだと思います。
…という話が私一人の妄想だったら非常に恥ずかしいわけですが、
ここまでの流れを見る限り大きく外してはいないと思います。おそらく。
-------------------------------------------------------------------
(的外れコメント終わり)
====================================================================
(再訂正終わり)
|
Re: MakeScreenで作った画面の初期化 ( No.21 ) |
- 名前:鈴見咲 君高 日時:2013/07/12 18:55
(訂正) 当初下のように書いていましたが、No.20 の記述の方が
正しいことがわかりました。
(DX_BLENDMODE_SRCCOLORだと複数枚を重ねることはできない)
なお、No.19のいっちさんのコード自体は正しく動作します。
No.22 以降の内容も参照ください。
-----------------------------------------------------
いっちさん、他の皆さんも、失礼しました、ごめんなさい!
DX_BLENDMODE_SRCCOLOR でもきちんと動作します!
それどころか、こちらだと test の初期化方法で
迷う必要がなく ClearDrawScreen でクリアしても完全に
動作するようです。
No.19 にある //<- ※ここを... のコメントをみて
No.20 を書いてしまったのですが、※ 以降を無視して
No.19 のコードのまま実行する形なら No.20 の仮定でも
問題なく、というかより良い確実な形で使えるものと思われます。
重ねて大変失礼いたしました。
|
Re: MakeScreenで作った画面の初期化 ( No.22 ) |
- 名前:鈴見咲 君高(重要な訂正あり) 日時:2013/07/12 18:44
えーと、一人で空回りしていて本当にすみません。
後からよくよく調べてみたところ No.20 の発言の方が正しいことがわかりました。
さらに、DX_BLENDMODE_HALF_ADD についてはてらすさんの懸念のとおり
複数枚重ねて使うとやっぱりうまく動作しないこともわかりました。
一方で、今度こそ完全解か? と思われる方法も見つかりまして、
SetDrawBlendMode への依存を止めて、
GraphBlend 系統に DX_GRAPH_BLEND_NORMAL_ALPHACH を渡して使う、という手を
発見しました。
ただしこの場合、DrawTurn/Rota/ModiGraph に相当するものがなく場合によっては
手間がかかってしまうので後ほど別件の要望として挙げたいと思います。
GraphBlend / DX_GRAPH_BLEND_NORMAL_ALPHACH の使い方もそちらでご紹介します。
|
Re: MakeScreenで作った画面の初期化 ( No.23 ) |
- 名前:鈴見咲 君高(重要訂正の続き) 日時:2013/07/12 20:36
No.22 の予告のとおり、別スレッドを作成しました。
h ttp://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=view&no=3079
DX_BLENDMODE_SRCCOLOR がうまくいかない理由もそちらのテストコードでご確認ください(下段右端)。
|
Re: MakeScreenで作った画面の初期化 ( No.24 ) |
- 名前:管理人 日時:2013/07/27 23:27
> spaaaark・∀・さん
少し調べたところ「乗算済みアルファ」という機能を使うと「完全な色のない画面」に
描画していくような処理が実現できるということが分かりましたので、今回実装してみました
よろしければこちらのバージョンをダウンロードしてください 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)」をして下さい)
DXライブラリで「乗算済みアルファ」を使用するための機能については解説ページを
用意しましたので、よろしければご覧になってみてください m(_ _)m
http://homepage2.nifty.com/natupaji/DxLib/lecture/PremulAlpha/PremulAlpha.html
|
Re: MakeScreenで作った画面の初期化 ( No.25 ) |
- 名前:spaaaark・∀・(解決済み) 日時:2013/08/08 18:08
返答がかなり遅れてしまい申し訳ないです><
管理人様、わざわざありがとうございます。
役立ちそうな機能なので、DLして使ってみようと思います。
ご対応ありがとうございました。
|
|