立て続けになりますが、失礼します。
MakeScreenで作成した画像に描きこんだ内容が正しく表示されなくなってしまいました。
原因はあまりはっきりしてませんが、DxLib_Init関数後に、SetGraphModeで解像度かビットレートを変更した事が原因のようです。
応急措置として、
・下記プログラムのDXScreen::Eraseのようにすることで解決しました。
・あるいはメインループのScreenFlip後にMakeScreenの画像の内容を消去することでも解決できました。
しかし、これらの方法はあまり用いたくないです。
どのようにすれば良いでしょうか?
立て続けで申し訳ありませんが、よろしくお願いします。
以下プログラムです。
//DXライブラリ用のスクリーン(アルファチャンネル付き)を保持したり出力したりするクラス
//<!ポイント!>
//☆アルファチャンネル付きなので透過色が不要!
//☆アルファチャンネルが付いているので、アルファブレンドしてBoxなどを描きこんだ際、後ろに描いた画像が透けて見えます!(背景色が透けて見えない!)
//☆もちろんスクリーン自体にブレンドかけることもできます!
class DXScreen
{
int screen = 0;
void Setup()
{
if (GetGraphSize(screen, 0, 0) == -1)
{
//失敗時はscreenに有効なハンドルが入っていないので取得
static RECT rc;
GetWindowCRect(&rc);
screen = MakeScreen(rc.right - rc.left, rc.bottom - rc.top, true);
while (GetASyncLoadNum() > 0 && !ProcessMessage());
}
}
public:
bool trans = false; //Sendの際に透過を行うフラグ
int blend_mode = DX_BLENDMODE_NOBLEND; //ブレンドモードを指定する
unsigned char pal = 255; //ブレンドモードのパラメータを指定する
//コンストラクタ
DXScreen() { Setup(); }
//ムーブコンストラクタ
DXScreen(DXScreen&& a)
{
*this = std::move(a);
a.screen = 0;
a.trans = 0;
a.blend_mode = 0;
a.pal = 0;
}
//デストラクタ
~DXScreen() { DeleteGraph(screen); }
operator int() const { return screen; }
void operator=(const DXScreen& a)
{
screen = a.screen;
trans = a.trans;
blend_mode = a.blend_mode;
pal = a.pal;
}
//描画先をこのスクリーンに設定します。
//0:成功 -1:失敗
int Targeting()
{
Setup();//スクリーンの存在を確認し、無ければ作成
return SetDrawScreen(screen);
}
//スクリーンに描かれた内容を裏画面に出力します
//do_erase:描き込み後、スクリーンを消去します。
//target_screen:出力先のスクリーンのハンドル。デフォルト = DX_SCREEN_BACK
void Send(bool do_erase = true)
{
int buf = 0,
b_bl = 0, b_pal = 0;
buf = GetDrawScreen();
GetDrawBlendMode(&b_bl, &b_pal);
SetDrawScreen(DX_SCREEN_BACK);
if (blend_mode != b_bl || pal != b_pal) SetDrawBlendMode(blend_mode, pal);
DrawGraph(0, 0, screen, trans);
//☆解像度を変えてもMakeScreenの画像を削除しなければ表示される
if (do_erase) Erase();
if (blend_mode != b_bl || pal != b_pal) SetDrawBlendMode(b_bl, b_pal);
SetDrawScreen(buf);
}
//スクリーンの内容を消去
void Erase()
{
//DeleteGraph(screen);
//Setup();
//☆解像度を変更した場合、↑の2つのみを使うと正常な出力になります
int buf = GetDrawScreen();
SetDrawScreen(screen);
ClearDrawScreen();
SetDrawScreen(buf);
}
};
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
SetGraphMode(900, 800, 32);
SetOutApplicationLogValidFlag(false);
ChangeWindowMode(true);
SetDoubleStartValidFlag(true);
SetWaitVSyncFlag(false);
SetMainWindowText("EXPERIENCE_APP_KAI");
SetBackgroundColor(90, 90, 90);
if (DxLib_Init() == -1)
{
MessageBox(0, "初期化に失敗しました。", "致命的なエラー", MB_OK | MB_ICONHAND);
exit(-1);
}
//☆解像度を変更した場合、DXScreen::Eraseの実装を変更すると直ります
SetGraphMode(1000, 600, 32);
SetDrawScreen(DX_SCREEN_BACK);
SetAlwaysRunFlag(true);
SetSysCommandOffFlag(true);
SetWindowSizeExtendRate(1);
SetCreateDrawValidGraphMultiSample(0, 0);
SetChangeScreenModeGraphicsSystemResetFlag(false);
SetFontCacheUsePremulAlphaFlag(true);
DXScreen scr;
scr.trans = true;
while (true)
{
// 別関数内 #############
SetDrawScreen(DX_SCREEN_BACK);
scr.Send();
ScreenFlip();
ClearDrawScreen();
if (ProcessMessage()) break;
// 別関数内 #############
scr.Targeting();
DrawBox(100, 100, 200, 200, GetColor(255,0,100),true);
DrawString(0,0,"見える!",GetColor(255,255,0));
}
DxLib_End();
return 0;
}