09/03/13 01:19:10 H+Qfngp2
>>823
訂正:ソフトグラフィックハンドル->ソフトイメージハンドル
あと「描画先」と書いたのは、「DrawGraph等で描画できる描画先」という意味です。
直接グラフィックハンドルをソフトイメージハンドルに変換できる方法があればよいのですが。
そもそもこの考え方自体がアホなんでしょうか。。。
825:名前は開発中のものです。
09/03/13 03:43:56 CMJVUsQ6
>>824
画面全体にエフェクトを掛けたりするのに有ると便利だが、ちょっと調べてみたが出来ないっぽいね。
そもそもLoadGraphやMakeGraphはVRAMに転送した時点でPC環境に依った画像フォーマットに変換されちゃうから、
そこからソフトイメージハンドルを生成するとなると、コンバーター(デコーダ相当)が必要になる。
DXライブラリの作者としては手間が掛かるから、要望が無い限り実装を見送っていると予想している。
優しい作者さんなんで、要望送ってみてはどうかな?
現状で対応するとなると、どうしても遅くなるが、
画面サイズと同じ大きさにMakeGraphした裏画面領域をSetDrawScreenして、
一連の画像を転送し、GetPixcelとDrawPixcelするのがベストな選択かねぇ。
SaveDrawScreenを使ってbmp保存して、そこからSoftImageを作るという最終手段もある。(とても遅い)
826:名前は開発中のものです。
09/03/13 03:50:25 CMJVUsQ6
>>823
ああ。書いてておもったが、SaveDrawScreenがあるから、デコーダ処理は既に内部には出来てるのか。
作者に要望だすと、すぐに実装してくれると思うよ。
827:名前は開発中のものです。
09/03/13 04:00:17 HX55tf54
解説 グラフィックデータのあるメモリ領域には『ロック』をしなくては アクセスする事が出来ません。
細かい事は抜きにしてとにかくWindows 環境ではメモリの管理が厳重なので malloc関数 などで確保したメモリ 領域のように簡単にはアクセスは出来ないようになっています。だから 『ロック』という作業を行い直接アクセスできるようにします。
グフィック領域に直接アクセスする利点はDrawPixel や GetPixel 関数を使用するよりも処理が速い、等があります。
ロックの説明をはじめる前に注意なのですが、ロックを行った場合は 直接アクセスが終り次第直ちにロックを解除してください。
ロックを している最中にデバッグモードなどのブレークポイントを使ってプロ グラムを止めるとハングアップするので注意してください。
ロックを すると 『GraphUnLock』関数を使用してロックを解除しない限り DrawLineをはじめすべての描画関数が使用不可能になるので注意してください。
では話を元に戻します。
ロックをするにはまずロックをしたいグラフィックハンドル、または DX_SCREEN_FRONT , DX_SCREEN_BACK 識別子を使って画面をロックする 事も出来ます。
ロックが完了すると関数は PitchBuf に指定したポインタにロック したグラフィック領域の1ライン辺りのバイト数と、DataPointBuf で 指定したポインタにロックしたグラフィックへのアドレスが代入されます。
こうしてロックしたグラフィック領域にはめでたく直接アクセスが 出来るようになります。まず希望の座標(点)にアクセスするには 以下の式を用います
(グラフィック領域の先頭アドレス) +
(X座標値 × (グラフィックのカラービット数 ÷ 8)) +
(Y座標値 × 1ライン辺りのバイト数)
= 希望の座標のポインタ
828:名前は開発中のものです。
09/03/13 04:02:17 HX55tf54
この中の『グラフィック領域の先頭アドレス』と言うのは DataPointBuf から取得できる値、『1ライン辺りのバイト数』は PitchBuf から取得できる値
『グラフィックのカラービット数は』SetGraphMode関数 の 引数 ColorBitNum の値(デフォルトでは16です)となります。
次に1ドット辺りのビット数はカラービット数と比例します、以下に カラービット数と一般のデータ型との比例関係を示します。
8bitカラー char 型と同サイズ
16bitカラー short 型と同サイズ
32bitカラー int 型と同サイズ
もし16ビットカラーのグラフィックに1ドット分データのアクセスを するつもりで int 型変数で値を代入した場合は2ドット分描画してしまう ので注意してください。(アドレスの算出のときも同じです)
注 … グラフィックをロックする場合は SetUse3DFlag 関数で3D機能を使わない設定にしてからLoadGraph,MakeGraph等で作られたグラフィックでないとロックは失敗します。
例 128×128のグラフィックデータを作成し、座標( 24 , 11 )
の点に色コード0を代入します。(16ビットカラー)
char *GraphData ;
short *DrawPoint ;
int Pitch , GHandle ;
// グラフィックの作成
GHandle = MakeGraph( 128 , 128 ) ;
// グラフィックのロック
GraphLock( GHandle , &Pitch , &GraphData ) ;
// 座標( 24 , 11 )のデータのアドレスを算出
DrawPoint = ( short * )( GraphData +
24 * ( 16 / 8 ) +
11 * Pitch ) ;
// 色コード0を代入します
*DrawPoint = 0 ;
// ロックを解除します
GraphUnLock( GHandle ) ;
829:名前は開発中のものです。
09/03/13 04:05:06 HX55tf54
サンプル 表画面をロックして直接アクセスで画面にグラデーションを描きます
#include "DxLib.h"
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ){
int i , j , k ;
int Pitch ;
short *DrawPoint , Cr ;
char *GraphData ;
if( DxLib_Init() == -1 ){return -1;}
// 表画面をロックします
GraphLock( DX_SCREEN_FRONT , &Pitch , ( void ** )&GraphData ) ;
// 画面にグラデーションを描きます
for( i = 0 ; i < 480 ; i ++ )
{
for( j = 0 ; j < 640 ; j ++ )
{
// 色の値を取得
k = 255 * i / 480 ;
Cr = ( short )GetColor( k , k , k ) ;
// 描画する座標のポインタを計算
DrawPoint = ( short * )( GraphData + j * ( 16 / 8 ) + i * Pitch ) ;
// グラフィックデータへの直接アクセスで点を描画
*DrawPoint = Cr ;
}
}
// 表画面のロックを解除(『GraphUnLock』使用)
GraphUnLock( DX_SCREEN_FRONT ) ;
// キーの入力待ち
WaitKey() ;
DxLib_End() ; // DXライブラリ使用の終了処理
return 0 ; // ソフトの終了
}
830:名前は開発中のものです。
09/03/13 04:17:46 CMJVUsQ6
>>827
ありがとう。
GraphLock/Unlockなかなか便利だねぇ
ちょっと使ってみます
作者から非公開関数になった理由が知りたいとこだね
831:名前は開発中のものです。
09/03/13 10:15:03 H+Qfngp2
>>825-829
なるほど、そのためのGraphLock/UnLockだったのか。
あと非公開関数になっただけで使う事はできるんですね。
てっきり使用すらできなくなったものだとばかり思ってました。。。
とりあえずはこれで出来そうなので、デコード処理の要望の方は見送ろうかと思います。
お二方とも、ありがとうございました。