DXライブラリの初期化の意味

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ゆうき2

DXライブラリの初期化の意味

#1

投稿記事 by ゆうき2 » 6年前

DXライブラリを使用する上では必ずメイン関数の冒頭部分でDXライブラリの初期化を行っています。
何故初期化という処理が必要なのでしょうか?

DXライブラリ入門編の1.2章で簡単に触れられていますが
よりその具体的な構造を理解したく質問させて頂きました。

ちなみにですが、個人的な予想では
メイン関数がライブラリ関数を呼び出すときに、その関数一つ一つに対しメモリ上のアドレス空間が渡されるので
初期化という処置をして、アドレスをリセットして、メモリ上のデータを全て削除しているのかな?と思いました。

仮にそうだとしてもわざわざデータを削除する意味も理解していないのですが・・・。

ご教授のほど、よろしくお願いします。

超絶右留斗羅天才プログラマー
記事: 44
登録日時: 6年前

Re: DXライブラリの初期化の意味

#2

投稿記事 by 超絶右留斗羅天才プログラマー » 6年前

DXライブラリというのは、Windows+DirectXをプログラムの初心者でもそれなりにとっつきやすく、簡単に扱えるようにしたものです。ですので、Windows+DirectXの話を織り交ぜて、そのDxLib_Initでは何が行われているかを簡単に説明したいと思います。

①ウィンドウプロシージャを作成します。
Windowsプログラミングの要であるウィンドウプロシージャ関数が、ウィンドウを作成する際に必要なので用意します。
ウィンドウを閉じるなどの操作を、ウィンドウプロシージャ関数で処理します。

②ウィンドウを作成します。
ウィンドウクラスを生成し、それをRegisterClassEx関数で登録し、CreateWindow関数でウィンドウを用意します。
ウィンドウを作成する際には、ウィンドウプロシージャと関連付けなければなりません。
この段階ではウィンドウの準備段階で、まだ表示されません。

③Direct3Dで扱うデバイスを初期化します。
LPDIRECT3DDEVICE9型の変数で、絵の描画の要となるデバイスをLPDIRECT3DDEVICE9::CreateDevice関数で作成します。
LPDIRECT3DDEVICE9とは、Long Pointer Direct3D Device 9 (ロングポインタ型のDirect3Dのバージョン9のデバイス)の略です。
DXライブラリに用意されているDrawGraph関数では、このデバイスを用いて描画されているので、DirectXを扱う上で一番使われる変数となります。
ハードウェアレンダリングやソフトウェアレンダリング(速い描画か遅い描画か)を決めるのも、この段階です。

④ウィンドウを表示します。
ShowWindow関数で実際にウィンドウを表示します。

⑤初期化失敗
もしこれらの処理のいずれかに失敗した場合、戻り値としてFALSEが返されます。

初期化があるからこそ、ウィンドウが表示され、ウィンドウの上に絵が描画でき、ウィンドウを閉じることもできるわけですね(*´▽`*)

個々の詳しい情報は、こちらのその1とそのサンプルプログラムが参考になります。
http://marupeke296.com/DirectXMain.html
ただの超絶右留斗羅天才プログラマーです。同人ゲーム制作進捗度:7%

びぎなぁ携帯

Re: DXライブラリの初期化の意味

#3

投稿記事 by びぎなぁ携帯 » 6年前

malloc freeやnew deleteなどが初期化関数の中で使われているんじゃないかな?
dxライブラリも大本はdirectxだろうし、内部でdirect3dcreate9関数やcreatedevice関数を呼び出している
プログラムの基本として、作ったものは消す、取得したものは解放してやらんといかん

アバター
みけCAT
記事: 6247
登録日時: 9年前
住所: 千葉県
連絡を取る:

Re: DXライブラリの初期化の意味

#4

投稿記事 by みけCAT » 6年前

ソースを読んでおらず想像ですが、おそらく消す役割を持っているのはDxLib_Endの方でしょう。
これから初期化をするところなのに、何を消す必要があるのですか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

びぎなぁ
記事: 6
登録日時: 6年前

Re: DXライブラリの初期化の意味

#5

投稿記事 by びぎなぁ » 6年前

>ゆうき2さん
>メモリ上のデータを全て削除しているのかな?

削除というのは正確には間違いで、DXライブラリを使うにあたって、必要なパラメーターを設定しています。
そのとき、DxLib_Init()の中のWindowsプログラムの部分ではハンドルというものが取得され、
DirectXプログラムの部分ではDirect3DCreate9()でDirectX9の実体が作られ、さらにCreateDevice()でデバイス操作用のポインタを取得します。
その他さまざまな処理を行って、DxLib_Init()は終わりです。

その後に実際のゲームのコード部分を書いていきます。


それが終わると、DxLib_Init()の処理で得た資源を削除解放してやらなければなりません。
それがおそらくDxLib_End()でしょう。
具体的にはハンドルの解放や、DirectX9関連のオブジェクトをRelease()していると思われます。

びぎなぁ
記事: 6
登録日時: 6年前

Re: DXライブラリの初期化の意味

#6

投稿記事 by びぎなぁ » 6年前

追伸です。

ここでちょろちょろ情報を出されても、わけわからんと思うので、
WIN32APIとDirectXの勉強をされると、よくわかるようになります。
その類のサイトはたくさんありますので。

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

Re: DXライブラリの初期化の意味

#7

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

DXライブラリはソースも配布されているので中を見ることができます。

ざっと、こんな事をしています。 ソースを引用。

コード:

// ライブラリ初期化関数
extern int NS_DxLib_Init( void )
{
	// 既に初期化済みの場合は何もせず終了
	if( DxSysData.DxLib_InitializeFlag == TRUE ) return 0 ;

	// 初期化中フラグを立てる
	DxSysData.DxLib_RunInitializeFlag = TRUE ;

	// DxSysData の共通初期化処理
	DxLib_SysInit() ;

	// API を読み込む
	LoadWinAPI() ;

	// フルスクリーンモードの場合は指定の画面解像度が使用可能かどうかを調べる
	if( WinData.WindowModeFlag == FALSE )
	{
		int Num, i, Width, Height ;
		DISPLAYMODEDATA Mode ;

		NS_GetDrawScreenSize( &Width, &Height ) ; 

		Num = NS_GetDisplayModeNum() ;
		for( i = 0 ; i < Num ; i ++ )
		{
			Mode = NS_GetDisplayMode( i ) ;
			if( Mode.Width == Width && Mode.Height == Height )
				break ;
		}
		if( i == Num )
		{
			if( !( Width == 320 && Height == 240 && GRA2.NotUseHardWare == FALSE ) )
			{
				NS_ChangeWindowMode( TRUE ) ;
			}
		}

		// 320x240 の解像度の場合は640x480の解像度で320x240の画面をエミュレーションする
		if( GRA2.MainScreenSizeX == 320 && GRA2.MainScreenSizeY == 240 && WinData.WindowModeFlag == FALSE )
		{
			GRH.FullScreenEmulation320x240 = TRUE ;
			SetMainScreenSize( 640, 480 ) ;
		}
	}

#ifndef DX_NON_OGGTHEORA
	// Theora 用の初期化
	TheoraDecode_GrobalInitialize() ;
#endif

	// アーカイブファイルアクセス用のデータを初期化
#ifndef DX_NON_DXA
	DXA_DIR_Initialize() ;
#endif

	// ストリームデータ読み込み制御用ポインタ構造体のデフォルト値をセット
	NS_ChangeStreamFunction( NULL ) ;

	// カレントディレクトリ保存
	FGETDIR( WinData.CurrentDirectory ) ; 

#ifndef DX_NON_LOG
	// ログ出力フォルダが指定されていない場合はカレントディレクトリにする
	if( LogData.LogOutDirectory[ 0 ] == TEXT( '\0' ) )
	{
		lstrcpy( LogData.LogOutDirectory, WinData.CurrentDirectory ) ;
	}

	// エラーログ排出の初期化
	ErrorLogInitialize() ;
#endif

	// 24ビットカラーチェック
	if( DxSysData.NotWinFlag == FALSE )
	{
		int CrBitNum ;

		// 現在の画面モードでの色の数を取得
		{
			HDC hdc ;
			hdc = GetDC( NULL ) ;
			CrBitNum = GetDeviceCaps( hdc, PLANES ) * GetDeviceCaps( hdc, BITSPIXEL ) ;
			ReleaseDC( NULL, hdc ) ;
		}

		if( ( CrBitNum == 24 && WinData.WindowModeFlag == TRUE ) ||
			( NS_GetColorBitDepth() == 24 ) )
		{
			DXST_ERRORLOG_ADD( _T( "DXライブラリは24ビットカラーモードに対応していません\n" ) ) ;
			return -1 ;
		}
	}

	// パフォーマンスカウンター情報の初期化
	{
		// パフォーマンスカウンターの周波数を取得する
		QueryPerformanceFrequency( ( LARGE_INTEGER * )&WinData.PerformanceClock ) ;

		// 使えるかどうかを保存しておく
		WinData.PerformanceTimerFlag = WinData.PerformanceClock != 0 ;
	}

	// システムログを出力
	OutSystemInfo() ;

	// デフォルトのグラフィック復元関数を登録
	NS_SetRestoreGraphCallback( NULL ) ;

	// 各処理系の初期化
	InitializeCom() ;											// COMの初期化
	if( InitializeWindow() == -1 ) goto ERROR_DX ;				// ウインドウ関係の初期化
#ifndef DX_NON_NETWORK
#if 0
	if( HTTP_Initialize() == -1 ) goto ERROR_DX ;				// HTTP 関係の処理の初期化
#endif
#endif

	if( DxSysData.NotInputFlag == FALSE )
	{
#ifndef DX_NON_INPUT
		if( InitializeDirectInput() == -1 ) goto ERROR_DX ;			// DirectInput関係の初期化
#endif // DX_NON_INPUT
	}

	if( DxSysData.NotSoundFlag == FALSE )
	{
		InitializeSoundConvert() ;									// サウンド変換処理の初期化
#ifndef DX_NON_SOUND
		InitializeDirectSound() ;									// DirectSound関係の初期化
#endif // DX_NON_SOUND
	}
	if( DxSysData.NotDrawFlag == FALSE )
	{
		InitializeBaseImageManage() ;
#ifndef DX_NON_SOFTIMAGE
		InitializeSoftImageManage() ;
#endif // DX_NON_SOFTIMAGE
#ifndef DX_NON_MOVIE
		InitializeMovieManage() ;
#endif

		if( InitializeGraphics2() < 0 ) goto ERROR_DX ;
	}
#ifndef DX_NON_INPUTSTRING
	InitializeInputCharBuf() ;									// 文字コードバッファの初期化
#endif // DX_NON_INPUTSTRING

	// DXライブラリ初期化完了フラグをたてる
	DxSysData.DxLib_InitializeFlag = TRUE ;

	// VSYNC待ちをする
//	NS_SetWaitVSyncFlag( TRUE ) ;

	// フルスクリーンモードだった場合ウインドウを最前面に持ってくる
	if( WinData.WindowModeFlag == FALSE && WinData.UserWindowFlag == FALSE )
		SetAbsoluteForegroundWindow( WinData.MainWindow ) ;
	
#if !defined( DX_NON_LOG ) && !defined( DX_NON_PRINTF_DX )
	// ログ出力処理の初期化を行う
	InitializeLog() ;
#endif

	// 描画先の変更
	NS_SetDrawScreen( DX_SCREEN_BACK ) ;
	NS_SetDrawScreen( DX_SCREEN_FRONT ) ;

	if( DxSysData.NotDrawFlag == FALSE )
	{
#ifndef DX_NON_MODEL
		// モデルバージョン1の初期化
		MV1Initialize() ;
#endif
	}

	// 初期化中フラグを倒す
	DxSysData.DxLib_RunInitializeFlag = FALSE ;

	// ウインドウのサイズが有効かどうかのフラグを倒すリクエストがされていたらフラグを倒す
	if( WinData.WindowSizeValidResetRequest == TRUE )
	{
		WinData.WindowSizeValid = FALSE ;
	}

	// 終了
	return 0 ;

ERROR_DX:
	NS_DxLib_End() ;

	// 初期化中フラグを倒す
	DxSysData.DxLib_RunInitializeFlag = FALSE ;

	return -1 ;
} 
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ゆうき2

Re: DXライブラリの初期化の意味

#8

投稿記事 by ゆうき2 » 6年前

超絶右留斗羅天才プログラマーさん
びぎなぁさん
みけCATさん
softyaさん
ご丁寧なご回答ありがとうございます。
おかげさまで初期化を理解できた気がします。

起動しているプログラム=ウィンドウが出て、画像が出て音が出て・・・それが当然だと無意識に
思い込んでいましたが、普通に考えればそういったソフトの方が稀ですもんね。
何から何まで全てがプログラムなんだという事を再認識させられました。

質問してよかったです。ありがとうございました!

閉鎖

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