自分のためのプログラミング雑記

C/C++とかゲームプログラミングに関して、自分用のメモとして書く場所

DXライブラリの描画の話

さっそく1つ検証してみた。
昔、どこかのサイトでDXライブラリは2のn乗のサイズの画像の方が処理が高速になるようなことが書かれていたのを見た気がしたので、それを検証しました。

私の開発環境を知りたい方は最初の雑記 - 自分のためのプログラミング雑記の方をどうぞ

以下ソースコード

読み込みの計測

#include <iostream>	//標準出力のため
#include <chrono>	//時間計測のため

#include "DxLib.h"

int APIENTRY _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR nCmdLine, int nCmdShow )
{
	//コンソール画面の呼び出し
	AllocConsole();
	FILE* fp;
	freopen_s(&fp, "CONOUT$", "w", stdout);
	freopen_s(&fp, "CONIN$", "r", stdin);

	int graphHandle[10] = {0};//グラフィックハンドル

	//ウィンドウで起動
	ChangeWindowMode( TRUE );
	if( DxLib_Init() == -1 )
	{
		return -1;
	}

	//計測開始
	auto start = std::chrono::system_clock::now();

	for( auto& i : graphHandle )
	{
		i = LoadGraph( _T( "test.png" ) );//画像の読み込み
	}

	//計測終了
	auto end = std::chrono::system_clock::now();

	//計測結果の出力
	std::cout << "time = "
		<< std::chrono::duration_cast<std::chrono::milliseconds>( end - start ).count()
		<< "msec."
		<< std::endl;

	WaitKey();//キー入力があるまで待機

	DxLib_End();//終了処理

	FreeConsole();//コンソールの解放

	return 0;
}


描画の計測

#include <iostream>	//標準出力のため
#include <chrono>	//時間計測のため

#include "DxLib.h"

int APIENTRY _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR nCmdLine, int nCmdShow )
{
	//コンソール画面の呼び出し
	AllocConsole();
	FILE* fp;
	freopen_s(&fp, "CONOUT$", "w", stdout);
	freopen_s(&fp, "CONIN$", "r", stdin);

	//ウィンドウで起動
	ChangeWindowMode( TRUE );
	if( DxLib_Init() == -1 )
	{
		return -1;
	}

	int graphHandle = LoadGraph( _T( "test.png" ) );//画像の読み込み

	//計測開始
	auto start = std::chrono::system_clock::now();

	for( int i = 0; i < 1000; i++)
	{
		DrawGraph( i, i, graphHandle, TRUE);
	}

	//計測終了
	auto end = std::chrono::system_clock::now();

	//計測結果の出力
	std::cout << "time = "
		<< std::chrono::duration_cast<std::chrono::milliseconds>( end - start ).count()
		<< "msec."
		<< std::endl;

	WaitKey();//キー入力があるまで待機

	DxLib_End();//終了処理

	FreeConsole();//コンソールの解放

	return 0;
}


それぞれ、縦横ともに2047、2048、2049のサイズのbmpとpngを用意して行った。
(実際1pixelだけ変えるのが正解なのかは知りません)

読み込みは、同じ画像を10個読み込むのにかかった時間。
描画は、同じ画像を1000個描画するのにかかった時間。

上記のプログラムをReleaseモードで10回行った平均が下の表。

読み込み処理[msec]

画像種類 2047^2 2048^2 2049^2
bmp 1222 1247 1561
png 5065 5130 5255


描画処理[msec]

画像種類 2047^2 2048^2 2049^2
bmp 12 10 52
png 10 12 50


まず、読み込みに関しては2のn乗を超えたサイズになると少しだけ時間がかかることが分かりました。ただ、大きい画像を10枚読み込んでようやく100~300msec程度の差なのであまり気にする必要はないように感じます。

次に、描画に関しては同じように2のn乗を超えたサイズになると時間がかかるようです。差に関しては、こちらはもっと少なく40msec程度なのでこれも気にしなくてよさそうです。

1つ気になったのが、記事には載せてませんが読み込みと描画ともに、実行の初回のみ時間がかかることが分かりました。
調べてみると、どうやらDXライブラリは同じグラフィックを連続で処理すると高速化するみたいです。そのため、初回のみ高速化されてない状態なので時間がかかるということみたいです。

以上のことから、2Dゲームを作るぐらいなら特に画像のサイズを気にする必要はあまりないようです。ただ、今回の検証が拡張子が2種類だけだったり、もっと大きいテクスチャでは検証していないので実際にどうかは分かりません。


最後に今回の検証とは関係ないのですが、ソースコード内のコンソールを使用する処理を使うとコンソール画面で出力が出来るため、デバッグ作業が非常に楽になります。
時間計測に使用したchronoライブラリはC++11で登場した新機能で、かなりスマートに時間の計測が出来るためオススメです。


以上