DXライブラリの二重初期化について(修正)

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
結城
記事: 52
登録日時: 13年前
連絡を取る:

DXライブラリの二重初期化について(修正)

#1

投稿記事 by 結城 » 13年前

えー、なんだかよく理解できないタイトルをつけてしまいましたが
具体的に
一度初期化したDXライブラリを同一アプリケーション内でもう一度初期化したいのですが
これがなかなかうまくいかないのです

さらに詳しく言うと

DXライブラリ初期化1回目
↓ウィンドウの大きさ、描画範囲などを設定
↓メインループ1……形のないウィンドウを作るため描画の反映方法はソフトウェアイメージの転送
DXライブラリ終了
DXライブラリ初期化2回目
↓ウィンドウの大きさ、描画範囲などを設定
↓メインループ2……こちらは640×480で固定の枠ありウィンドウ
   ↑ここで止まる、ProcessMessageがエラーを返したり、FPSが極端に遅くなる

原因のコードです

コード:

#define GLOBAL_INSTANCE 
#include "GV.h"
#include "Display.h"

//ループで必ず行う3大処理
int ProcessLoop(){
	if(ProcessMessage()!=0)return -1;//プロセス処理がエラーなら-1を返す
	if(ClearDrawScreen()!=0)return -1;//画面クリア処理がエラーなら-1を返す
	//GetHitKeyStateAll_2();//現在のキー入力処理を行う
	//GetHitPadStateAll();  //現在のパッド入力処理を行う
	return 0;
}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
	SetWindowTextA("AIS-#Alice");
	int h,w;
	DisplayMode m_display;
	w=m_display.GetWidth();
	h=m_display.GetHeight();
	int screensofthandle, screensofthandle2, sfhandle ;

	SetWindowStyleMode(2);
	SetGraphMode(w,h,32);
	SetWindowSize(w,h);
	SetWindowInitPosition(0,0);
	// ウインドウモードで起動
	ChangeWindowMode( TRUE );

	// ウインドウの透過色モードON
	SetUseBackBufferTransColorFlag( TRUE ) ;

	// DXライブラリの初期化
	if( DxLib_Init() < 0 ) return -1;

	SetDrawMode(DX_DRAWMODE_BILINEAR);

	// 画像の読み込み
	sfhandle = LoadSoftImage( "AIS-StarupLogoDesign.png");
	int iw,ih;
	GetSoftImageSize(sfhandle,&iw,&ih);

	// 透過色を設定
	SetTransColor( 255, 0, 255 ) ;

	// 画面出力用のソフトウエア画像の作成
	screensofthandle = MakeARGB8ColorSoftImage( w, h ) ; 

	screensofthandle2 = MakeARGB8ColorSoftImage( w , h );

	// 描画先を裏画面に
	SetDrawScreen( DX_SCREEN_BACK ) ;

	int wav01;
	wav01=LoadSoundMem("AIS-StartUpSound.wav");
	int opacity = 0;
	int c001 = 0;

	while( ProcessMessage() == 0 )
	{

		if(c001<=64)
		{
			if(opacity<=255)opacity+=4;
			if(opacity>=255)opacity=255;
		}
		else
		{
			if(c001>=160)
			{
				if(opacity>=0)opacity-=8;
				if(opacity<=0)opacity=0;
			}
		}
		if(c001==0)
			PlaySoundMem(wav01,DX_PLAYTYPE_BACK);
		if(c001<192)
			c001++;
		else
			goto NEXT001;


		// 画面をクリア
		ClearDrawScreen() ;

		// 画面出力用のソフトウエア画像をクリア
		FillSoftImage( screensofthandle, 0, 0, 0, 0 ) ;

		FillSoftImage( screensofthandle2, 0, 0, 0, 0 ) ;

		// 画面出力用のソフトウエア画像の左上端に読み込んだ画像を転送
		BltSoftImage( 0, 0, iw, ih, sfhandle, (w-iw)/2, (h-ih)/2, screensofthandle ) ;

		BltSoftImageWithAlphaBlend( 0, 0, w, h, screensofthandle, 0, 0, screensofthandle2,opacity);

		// 画面出力用のソフトウエア画像を使ってウインドウの表示を更新
		UpdateLayerdWindowForSoftImage( screensofthandle2 ) ; 


	}
NEXT001:
	SetWindowTextA("AIS-#Alice");
	SetWindowStyleMode(0);
	SetGraphMode(640,480,32);
	SetWindowSize(640,480);
	SetDrawArea(0,0,640,480);
	SetWindowPosition((w-640)/2,(h-480)/2);
	SetUseBackBufferTransColorFlag(FALSE);
	while(ProcessLoop()==0)
	{
		music_ini();
		switch(func_state){
			case 0://システム制御を始める前に行う初期化0
				ini();
				dictionary_loader(0);
				break;
			case 1:
				InterFace_main();
				win_draw_main();
				break;
			case 2:
				break;
			case 99://
				break;
			case 100://通常処理

				break;
			default:
				printfDx("不明なfunc_state\n");
				break;
		}
		music_play();
		ScreenFlip();//裏画面反映
		count++;

	}

	// DXライブラリの後始末
	DxLib_End();

	// ソフトの終了
	return 0;
}
1:34頃内容を補足に基づき修正

これはどうにかならないでしょうか?

あまり公にしたくない部分なども含んでいるので
コード一式が必要の場合はすみませんがレスを下さい
メールをお送りいたします
最後に編集したユーザー 結城 on 2010年12月06日(月) 01:36 [ 編集 1 回目 ]
ANGE;ART

アバター
結城
記事: 52
登録日時: 13年前
連絡を取る:

Re: DXライブラリの二重初期化について

#2

投稿記事 by 結城 » 13年前

さらに原因を探ったところ
次のようなことが分かりました(DXライブラリを初期化せずに2回目のProcessLoopを実行しています)
2回目のループに移る際
設定は反映されているが極度に速度が遅い
↑このことはウィンドウを試しに最小化→元に戻すを実行すると枠が表示されているのでわかりました
コードをいじくると描画範囲はちゃんと反映されていました。すみません

結局何が問題かというと
二つ目のループに入るとそんなに重い処理をしていないのにFPSがUpdateLayerdWindowForSoftImageを使っていた時ぐらいの速度だということです
ANGE;ART

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: DXライブラリの二重初期化について(修正)

#3

投稿記事 by softya(ソフト屋) » 13年前

ソース全体は頂かなくて良いので、最低限の状況を再現できるプロジェクトを作っていただけないでしょうか?
それを作っている過程で原因が判明する可能性がありますし、他の人が追試しやすくなります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
結城
記事: 52
登録日時: 13年前
連絡を取る:

Re: DXライブラリの二重初期化について(修正)

#4

投稿記事 by 結城 » 13年前

すみませんなぜか以下のコードを入れることによりほぼ自己解決してしまいました
あとは最小化最大化を自動的に行うコードを入れてやれば解決するはずです

挿入したコード(解決の因子と思われるもの)
SetUseSoftwareRenderModeFlag( FALSE );←FPSがガタ落ちしたところに入れてやった

HWND hnd =GetMainWindowHandle();←直前でDXライブラリがウィンドウハンドルを放棄していたのでメッセージプロセスに追加
AddMessageTakeOverWindow(hnd);
これを二つ目のループの前に入れてやると治りました

↓テスト用コードです(かなりの関数と変数を抜いて軽くなっているので違いがみられるかわかりませんが・・・)

コード:

#define GLOBAL_INSTANCE 
#include "DxLib.h"

//ループで必ず行う3大処理
int ProcessLoop(){
	if(ProcessMessage()!=0)return -1;//プロセス処理がエラーなら-1を返す
	if(ClearDrawScreen()!=0)return -1;//画面クリア処理がエラーなら-1を返す
	return 0;
}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
	int screensofthandle;

	SetWindowStyleMode(2);
	SetGraphMode(800,600,32);
	SetWindowSize(800,600);
	SetWindowInitPosition(0,0);
	// ウインドウモードで起動
	ChangeWindowMode( TRUE );

	// ウインドウの透過色モードON
	SetUseBackBufferTransColorFlag( TRUE ) ;

	// DXライブラリの初期化
	if( DxLib_Init() < 0 ) return -1;

	SetDrawMode(DX_DRAWMODE_BILINEAR);

	// 画面出力用のソフトウエア画像の作成
	screensofthandle = MakeARGB8ColorSoftImage( w, h ) ; 

	// 描画先を裏画面に
	SetDrawScreen( DX_SCREEN_BACK ) ;

	int c001 = 0;

	while( ProcessMessage() == 0 )
	{

		if(c001<192)
			c001++;
		else
			goto NEXT001;


		// 画面をクリア
		ClearDrawScreen() ;

		// 画面出力用のソフトウエア画像をクリア
		FillSoftImage( screensofthandle, 0, 0, 0, 255) ;

		// 画面出力用のソフトウエア画像を使ってウインドウの表示を更新
		UpdateLayerdWindowForSoftImage( screensofthandle ) ; 


	}
NEXT001:
	DeleteSoftImage( screensofthandle );
	DxLib_End();
	// DXライブラリの初期化
	if( DxLib_Init() < 0 ) return -1;
	ChangeWindowMode(TRUE);
	SetUseSoftwareRenderModeFlag( FALSE );//ここをコメントアウトすると極度にFPSが下がります
	SetWindowStyleMode(0);
	SetGraphMode(640,480,32);
	SetWindowSize(640,480);
	SetWindowPosition(0,0);//ほんとは中央に表示するのですが別のファイル群を用いているので代理です
	SetUseBackBufferTransColorFlag(FALSE);
	HWND hnd =GetMainWindowHandle();//ここをコメントアウトすると2回目のループでエラーが返ります
	AddMessageTakeOverWindow(hnd);//上記同様
	int x=0;
	int y=0;
	int f1=0;
	int f2=0;
	while(ProcessLoop()==0)
	{
		if(x<640)
		{
			if(f1==0)
				x++;
			else
				x--;
		}
		if(x>=640)f1=1;
		if(x<=0)f1=0;
		if(y<480)
		{
			if(f2==0)
				y++;
			else
				y--;
		}
		if(y>=480)f2=1;
		if(y<=0)f2=0;		
		DrawBox(x-16,y-16,x+16,y+16,GetColor(255,0,0),1);
		ScreenFlip();//裏画面反映
		count++;
	}

	// DXライブラリの後始末
	DxLib_End();

	// ソフトの終了
	return 0;
}
ANGE;ART

アバター
結城
記事: 52
登録日時: 13年前
連絡を取る:

Re: DXライブラリの二重初期化について(修正)

#5

投稿記事 by 結城 » 13年前

以下のコードを書きかえることで解決いたしました
お騒がせいたしました

コード:

	SetWindowVisibleFlag(FALSE);
	SetWindowStyleMode(0);
	DxLib_End();
	// DXライブラリの初期化
	if( DxLib_Init() < 0 ) return -1;
	SetWindowStyleMode(0);
	SetWindowVisibleFlag(TRUE);
	ChangeWindowMode(TRUE);
	SetUseSoftwareRenderModeFlag( FALSE );
	SetGraphMode(640,480,32);
	SetWindowSize(640,480);
	SetWindowPosition((w-640)/2,(h-480)/2);
	SetUseBackBufferTransColorFlag(FALSE);
	HWND hnd =GetMainWindowHandle();
	AddMessageTakeOverWindow(hnd);
さらにウィンドウをアクティブにするために以下のコードをメインループに付加しました

コード:

				ScreenFlip();
				SetActiveWindow(NULL);
				SetActiveWindow(GetMainWindowHandle());
				func_state++;
最後に編集したユーザー 結城 on 2010年12月07日(火) 00:15 [ 編集 1 回目 ]
ANGE;ART

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: DXライブラリの二重初期化について(修正)

#6

投稿記事 by softya(ソフト屋) » 13年前

こちらでは、SetUseBackBufferTransColorFlag()などの関数がエラーでコンパイルが通りません。
どの様なDXLIBをお使いでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
結城
記事: 52
登録日時: 13年前
連絡を取る:

Re: DXライブラリの二重初期化について(修正)

#7

投稿記事 by 結城 » 13年前

すいません
3.04cという管理人さんに修正を施してもらったバージョンでした

>http://homepage2.nifty.com/natupaji/DxL ... VCTest.exe // VisualC++ 用
>http://homepage2.nifty.com/natupaji/DxL ... CCTest.exe // BorlandC++ 用
DXライブラリ掲示板より

あと一部の環境で
#include "DxLib.h"を
#include <DxLib.h>にすると通ると思います
ANGE;ART

閉鎖

“C言語何でも質問掲示板” へ戻る