> 一つは2600px×1951、二つ目は2600px×2601pxです。
> 1カラーを変更するだけの場合は大体0.1〜0.2秒くらい(この場合は画面全体は影響していないように見える)
面積が2600x1951pxですと、0.1〜0.2秒くらい時間が掛かるのは妥当かもしれません…
多少処理を高速化できるかもしれない方法としては、カラー変更の際に
DeleteGraph でグラフィックハンドルの削除
↓
CreateDivGraphFromSoftImage でグラフィックハンドルの作成
とされていると思いますが、こちらを
ReCreateDivGraphFromSoftImage で既存のグラフィックハンドルの画像を変更
とすることです( ReCreateDivGraphFromSoftImage は ReloadDivGraph の SoftImage版です )
// ソフトウエアで扱うイメージから既存の分割グラフィックハンドルにデータを転送する
int ReCreateDivGraphFromSoftImage( int SIHandle, int AllNum, int XNum, int YNum, int SizeX, int SizeY, const int *HandleArray ) ;
…と、申し上げようとしたら、ReCreateDivGraphFromSoftImage がありませんでした…
なので、ReCreateDivGraphFromSoftImage を追加したバージョンをアップしましたので、
よろしければこちらのバージョンで ReCreateDivGraphFromSoftImage を試してみてください m(_ _;m
https://dxlib.xsrv.jp/temp/DxLibVCTest.zip // Windows版 VisualC++ 用
https://dxlib.xsrv.jp/temp/DxLibBCCTest.zip // Windows版 BorlandC++ 用
https://dxlib.xsrv.jp/temp/DxLibBCC2Test.zip // Windows版 C++ Builder 10.2 用
https://dxlib.xsrv.jp/temp/DxLibGCC_MinGWTest.zip // Windows版 MinGW 用
https://dxlib.xsrv.jp/temp/DxLibDotNet.zip // Windows版 .NET用
https://dxlib.xsrv.jp/temp/DxLibAndroidTest_ARM.zip // Android版 ARM用
https://dxlib.xsrv.jp/temp/DxLibAndroidTest_ARM64.zip // Android版 ARM64用
https://dxlib.xsrv.jp/temp/DxLibAndroidTest_x86.zip // Android版 x86用
https://dxlib.xsrv.jp/temp/DxLibAndroidTest_x64.zip // Android版 x64用
https://dxlib.xsrv.jp/temp/DxLibiOSTest.zip // iOS版
https://dxlib.xsrv.jp/temp/DxLibMakeTest.zip // ソース
(中身を既存のライブラリのファイルに上書きして『リビルド』をして下さい)
> 連続でカラー変更を行っても処理落ちをしないようにしたいと思っています。
DxLib_Init を実行する前に SetScreenMemToVramFlag( FALSE ); を実行することで
使用することができるソフトウェアレンダリングモードではパレット画像を
パレット画像のまま保持するため、グラフィックハンドルのパレットの色を
変更するための SetGraphPalette という関数を使用することができます
// グラフィックハンドルのパレットを変更する( ソフトウエアレンダリングモードで、且つパレット画像の場合のみ使用可能 )
int SetGraphPalette( int GrHandle, int ColorIndex, unsigned int Color ) ;
グラフィックハンドルのパレットを変更する場合は、画像のピクセル情報はそのままで
パレット情報のみ変更するので処理は一瞬で終わる為、処理落ち無くパレットの色を
変更して描画することができます
この関数を使用してサンプル実行用フォルダにある test2.bmp の棒人間の色を1秒毎に変更するプログラムは以下のようになります
( 分割画像の場合は、分割されたグラフィックハンドルのどれか一つに対して色を変えると全てのグラフィックハンドルに反映されます )
#include "DxLib.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
int GrHandle[ 10 ] ;
int i ;
int Counter ;
int ColorIndex ;
// ウィンドウモードで起動
ChangeWindowMode( TRUE ) ;
// ソフトウェアレンダリングモードで起動
SetScreenMemToVramFlag( FALSE ) ;
// DXライブラリを初期化
if( DxLib_Init() < 0 )
return -1 ;
// BMP画像のメモリへの分割読み込み
LoadDivGraph( "test2.bmp" , 10 , 4 , 3 , 48 , 56 , GrHandle ) ;
// 描画先を裏画面に変更
SetDrawScreen( DX_SCREEN_BACK ) ;
// 色番号を初期化
ColorIndex = 0 ;
// カウンターを初期化
Counter = 0 ;
// メインループ
while( ProcessMessage() == 0 )
{
// 画面を初期化
ClearDrawScreen() ;
// カウンターをインクリメント
Counter ++ ;
// 60フレーム経過したら色を変える
if( Counter == 60 )
{
// カウンターを初期化
Counter = 0 ;
// 色番号を変更
ColorIndex = ( ColorIndex + 1 ) % 6 ;
// 色番号に沿ってパレット1番の色を設定
switch( ColorIndex )
{
case 0 : SetGraphPalette( GrHandle[ 0 ], 1, GetColor( 0,255,0 ) ) ; break ;
case 1 : SetGraphPalette( GrHandle[ 0 ], 1, GetColor( 0,0,255 ) ) ; break ;
case 2 : SetGraphPalette( GrHandle[ 0 ], 1, GetColor( 255,0,0 ) ) ; break ;
case 3 : SetGraphPalette( GrHandle[ 0 ], 1, GetColor( 255,255,0 ) ) ; break ;
case 4 : SetGraphPalette( GrHandle[ 0 ], 1, GetColor( 0,255,255 ) ) ; break ;
case 5 : SetGraphPalette( GrHandle[ 0 ], 1, GetColor( 255,0,255 ) ) ; break ;
}
}
// 分割画像を描画
for( i = 0 ; i < 10 ; i ++ )
{
DrawGraph( 48 * i, 0, GrHandle[ i ], TRUE ) ;
}
// 裏画面の内容を表画面に反映
ScreenFlip() ;
}
// DXライブラリの後始末
DxLib_End() ;
// ソフトウェアの終了
return 0 ;
}
ただ、ソフトウェアレンダリングモードはGPUを一切使用せずに描画処理を行うため、描画処理の
パフォーマンスが著しく低下しますので、贅沢な描画処理を行いたい場合はこの選択肢は使えません…
前述までの二つの方法以外には、SetASyncLoadFlag( TRUE ); を使用したバックグラウンド処理を使用する方法があります
SetASyncLoadFlag( TRUE ) ; を実行した状態で CreateDivGraphFromSoftImage や
ReCreateDivGraphFromSoftImage を実行すると、グラフィックハンドルの作成や再読み込みが
バックグラウンドで行われるので、処理落ちしないようにできるかもしれません
ただ、バックグラウンドで読み込み処理を開始すると、CheckHandleASyncLoad の戻り値が FALSE に
なるまでグラフィックハンドルは使用できないので、グラフィックハンドルのセットは2つ用意する必要があります
〜〜〜〜〜 準備処理
int UseIndex = 0 ;
int GrHandle[ 2 ][ 12 ];
int IsChangeColor = 0 ;
int TargetColor = 0 ; // ←変更先の色番号
// 準備(最初の読み込み)
CreateDivGraphFromSoftImage( SoftImage, 12, 4, 3, 650, 650, GrHandle[ 0 ] ) ;
CreateDivGraphFromSoftImage( SoftImage, 12, 4, 3, 650, 650, GrHandle[ 1 ] ) ;
〜〜〜〜〜
〜〜〜〜〜 メインループ中
GrHandle[ UseIndex ][ 0〜11 ] を使用して描画
〜〜〜〜〜
〜〜〜〜〜 カラー変更処理開始
〜〜〜〜〜〜〜〜〜〜〜
TargetColor に従った SoftImage のパレットの色変更処理
〜〜〜〜〜〜〜〜〜〜〜
// UseIndex とは逆の番号( 0 だったら 1, 1 だったら 0 )に再読み込み
ReCreateDivGraphFromSoftImage( SoftImage, 12, 4, 3, 650, 650, GrHandle[ UseIndex == 0 ? 1 : 0 ] ) ;
// 色の変更処理中かどうかを示すフラグを立てる
IsChangeColor = 1 ;
〜〜〜〜〜
〜〜〜〜〜 カラー変更処理中のメインループに追加する処理
// 色の変更処理の終了待ち中だった場合のみ処理
if( IsChangeColor == 1 )
{
// 全ての非同期読み込み処理が終わったら UseIndex を逆にする
// ( ハンドル単位では CheckHandleASyncLoad ですが、他に非同期読み込みをしていなければ
// GetASyncLoadNum で手抜きをすることもできます )
if( GetASyncLoadNum() == 0 )
{
UseIndex = UseIndex == 0 ? 1 : 0 ;
// 色の変更処理中かどうかを示すフラグを倒す
IsChangeColor = 0 ;
}
}
〜〜〜〜〜
描画は常に UseIndex が示す側のグラフィックハンドルセットを使用するようにして、切り替える
際は UseIndex が示していない方にバックグラウンドで読み込み、読み込みが終わったら UseIndex が
示す番号を変える、という感じです
ただ、読み込み処理に 0.1〜0.2秒くらい掛かることから、処理落ちが発生しなくはなるかもしれませんが、
カラーを変更する操作をしてから 0.1〜0.2秒経過しないとカラーが切り替わらない、という状態になります
加えて、バックグラウンドでの処理が終わる前に次のカラー変更を行ってしまった( 次のバックグラウンド
処理を始めようとしてしまった )場合は既に実行中のバックグラウンド処理が終わるまで待たされる( 通常の
SetASyncLoad( TRUE ) ; を使用していない読み込みのように処理がブロックされる )ので、
それが発生しないようにするためには『GetASyncLoadNum が 0 になる前に次の色変更が発生した場合は、
GetASyncLoadNum が 0 になるまで次の ReCreateDivGraphFromSoftImage を待つ』という処理を行う必要があります
〜〜〜〜〜 準備処理
int UseIndex = 0;
int GrHandle[ 2 ][ 12 ];
int IsChangeColor = 0 ;
int TargetColor = 0 ; // ←変更先の色番号
int ColorChangeRequest = 0 ;
// 準備(最初の読み込み)
CreateDivGraphFromSoftImage( SoftImage, 12, 4, 3, 650, 650, GrHandle[ 0 ] ) ;
CreateDivGraphFromSoftImage( SoftImage, 12, 4, 3, 650, 650, GrHandle[ 1 ] ) ;
〜〜〜〜〜
〜〜〜〜〜 メインループ中
GrHandle[ UseIndex ][ 0〜11 ] を使用して描画
〜〜〜〜〜
〜〜〜〜〜 カラー変更処理開始
// まだバックグラウンドで処理中だったら予約だけしておく
if( GetASyncLoadNum() > 0 )
{
ColorChangeRequest = 1 ;
}
else
{
〜〜〜〜〜〜〜〜〜〜〜
TargetColor に従った SoftImage のパレットの色変更処理
〜〜〜〜〜〜〜〜〜〜〜
// UseIndex とは逆の番号( 0 だったら 1, 1 だったら 0 )に再読み込み
ReCreateDivGraphFromSoftImage( SoftImage, 12, 4, 3, 650, 650, GrHandle[ UseIndex == 0 ? 1 : 0 ] ) ;
// 色の変更処理中かどうかを示すフラグを立てる
IsChangeColor = 1 ;
}
〜〜〜〜〜
〜〜〜〜〜 カラー変更処理中のメインループに追加する処理
// 色の変更処理の終了待ち中だった場合のみ処理
if( IsChangeColor == 1 )
{
// 全ての非同期読み込み処理が終わったら UseIndex を逆にする
if( GetASyncLoadNum() == 0 )
{
UseIndex = UseIndex == 0 ? 1 : 0 ;
// 色の変更処理中かどうかを示すフラグを倒す
IsChangeColor = 0 ;
// 次の色変更の予約があった場合は、次の色に変更する処理を開始する
if( ColorChangeRequest == 1 )
{
// 色の変更の予約を解除
ColorChangeRequest = 0 ;
〜〜〜〜〜〜〜〜〜〜〜
TargetColor に従った SoftImage のパレットの色変更処理
〜〜〜〜〜〜〜〜〜〜〜
// UseIndex とは逆の番号( 0 だったら 1, 1 だったら 0 )に再読み込み
ReCreateDivGraphFromSoftImage( SoftImage, 12, 4, 3, 650, 650, GrHandle[ UseIndex == 0 ? 1 : 0 ] ) ;
// 色の変更処理中かどうかを示すフラグを立てる
IsChangeColor = 1 ;
}
}
}
〜〜〜〜〜
と、これ以外の二つの方法に比べてかなり処理が複雑です…
> しかし、想定している数が100カラー分であり、上記の分割画像2種類×100の画像を作成したので
> 3.5GBほどメモリを食ってしまい、これはちょっと…と思いました。
確かに…3.5GBは厳しいですね…