Re: DIBやDirectXについて ( No.1 ) |
- 名前:管理人 日時:2019/05/23 00:49
> DXLibでDIBを使わないようにするには、
>
> ↓を使用しない(またはTRUEにする)であってるでしょうか。
> SetScreenMemToVramFlag(FALSE);
はい、合っています
> この場合、
> SetSoftRenderModeUserScreenImage
> は使用せず、ReCreateGraphFromSoftImage や Lock する方法で転送すれば良いでしょうか。
GraphLock で裏画面をロックできるのはソフトウェアレンダリングモードの場合のみなので、
現状では ReCreateGraphFromSoftImage 一択となります
ただ、考えてみれば Android・iOS では OpenGL ES のテクスチャに SetSoftRenderModeUserScreenImage で
設定した画面イメージを転送して描画の工程を高効率化することで高速化したので、同じことを Windows の
Direct3D でも行えば、DIB を使用しない場合の画面イメージのモニタへの表示も高速化できますね…
Windows は高速なので ReCreateGraphFromSoftImage で十分とのことでしたが、折角なので
Windows でも Direct3D を使う場合も SetSoftRenderModeUserScreenImage を使用できるようにしようと思います
そして、そうなると SetSoftRenderModeUserScreenImage はソフトウェアレンダリングモードではなくても使用できる
ことになるので、関数名が変わります、すみません…( 多分、単純に SoftRenderMode が抜けて SetUserScreenImage になります )
ギウさんが不要とされている機能の追加になるのですが、よろしければもう少しお付き合いください m(・・;m
> P.S
> Android版の方は、DX_SOFTRENDER_SCREEN_FORMAT_R5G5B5X1を使って、1500usまで高速化することができました^^ 感謝。
1500us! ReCreateGraphFromSoftImage の頃は 8900usですよね?
多少の高速化は期待できると思っていましたが、テクスチャへの転送は避けられない OpenGL ES の環境なので
まさかそこまで高速化できるとは思っていませんでした(汗
 |
Re: DIBやDirectXについて ( No.2 ) |
- 名前:ギウ 日時:2019/05/23 08:28
ご回答ありがとうございます!
>ギウさんが不要とされている機能の追加になるのですが、よろしければもう少しお付き合いください m(・・;m
いえいえ、その方式の方が速そうなので、ありがたいです。
よろしくお願いいたします!
>1500us! ReCreateGraphFromSoftImage の頃は 8900usですよね?
はい、劇的に速くなりました!
(なので昨日の夜は、この7msを使って何か面白いことできないか考えて中々眠れませんでしたw まあ使わなくても対応機種増えますし、消費電力も減ってるはずなので良いんですけど)
現状、RGB5551で行ってるんですが、RGB565でLock転送した時は2100usくらいだったので(お送りしたバージョン)、
内部的な(OpenGL側の)変換処理が余分に発生していたとかかもしれないですね。
|
Re: DIBやDirectXについて ( No.3 ) |
- 名前:ギウ 日時:2019/05/23 09:28
あ、計測は、Flipを含めてないので、Flipを含めて計測してみます。
|
Re: DIBやDirectXについて ( No.4 ) |
- 名前:ギウ 日時:2019/05/23 10:14
計測しなおしました。
※今までは、ProcessMessageとFlipを除外して計測していました。
・ProcessMessageとFlip込みの速度↓(DISPはSetGraphModeで設定したbit数)
==================
<新関数>
・Android:5551,16bit,DISP=16bit = 8900us
・Android:5551,16bit,DISP=32bit = 7700us
・Android:565,16bit,DISP=16bit = 5300us
・Android:565,16bit,DISP=32bit = 5300us
・Android:5551→(自力変換)X0R8G8B8,DISP=32bit = 13300us
<旧関数>
・Android:5551→旧方式 = 9800us (VSYNC有りの為、Flipは除外してる状態。ProcessMessage込み)
==================
ということで、私のスマホだと、新版のRGB565で転送するのが一番速そうでした。
RGB565なら5ms以上は速くなってそうですね。
|
Re: DIBやDirectXについて ( No.5 ) |
- 名前:管理人 日時:2019/05/25 02:39
 |
Re: DIBやDirectXについて ( No.6 ) |
- 名前:ギウ 日時:2019/05/25 07:34
ありがとうございます!
試してみました。
・SetUserScreenImage関数(ProcessMessageとFlip込み)
・PC:565,16bit,DISP=16bit = 1350us (但し、30fpsのウエイトをかけない場合は、650usくらいになる。キャッシュの影響?)
・PC:565,16bit,DISP=32bit = 1350us
・Android:565,16bit,DISP=16bit = 5150us〜5350us (ウエイトを外しても、速度は変わらず)
・Android:565,16bit,DISP=32bit = 5150us〜5350us
Windwos+DirectXは、3400us(Flipは考慮しない)だったので、かなり高速化しました!
ウエイト無しならDIBモードと同じくらいの速度になったかなと思います。
Androidの方は、DISPの16bit/32bitで同じくらいな印象でした。
元々ゆらぎがあるので、50usくらいの違いの場合はよくわからないというのはありますが・・・
因みに、DISP=16bitの場合、消費してるビデオメモリは少なくなってると考えて大丈夫でしょうか。
であれば、PC版もAndroid版も 「RGB565, DISP=16bit」を使うのがベストですね。
|
Re: DIBやDirectXについて ( No.7 ) |
- 名前:ギウ 日時:2019/05/25 07:43
(追記)
上記は、ウインドウモードで計測した状態です。
フルスクリーンモードで計測したところ(DISP=16bit)、
ウエイト有り=1400us
ウエイト無し=3300us
という感じでウインドウモードとは逆にウエイト無し側が遅くなりました。
謎ですね;(どこかで計測ミスしてる可能性もありますが)
|
Re: DIBやDirectXについて ( No.8 ) |
- 名前:ギウ 日時:2019/05/25 08:51
>管理人様
Windows版、
↓の方法で文字入力をしているのですが、
===================
// キー入力ハンドルを作る
int InputHandle = MakeKeyInput(max, TRUE, FALSE, FALSE);
// 作成したキー入力ハンドルをアクティブにする
DxLib::SetActiveKeyInput(InputHandle);
// デフォルト文字を設定
if(moto_str)
SetKeyInputString(moto_str, InputHandle);
// キー入力終了待ちループ
int input_ret = 0;
while (!ProcessMessage())
{
// 入力が終了している場合は終了
input_ret = CheckKeyInput(InputHandle);
if (input_ret) break;
// 入力モードを描画
DrawKeyInputModeString(DISP_X, DISP_Y);
// 入力途中の文字列を描画
DrawKeyInputString(x, y, InputHandle);
// 裏画面の内容を表画面に反映させる
ScreenFlip();
}
// 入力された文字列を取得
GetKeyInputString(str, InputHandle);
// 用済みのインプットハンドルを削除する
DxLib::DeleteKeyInput(InputHandle);
===================
新関数だとこれらも無効になってしまい、文字入力できなくなってしまいました。
何か方法はあるでしょうか。
|
Re: DIBやDirectXについて ( No.9 ) |
- 名前:管理人 日時:2019/05/25 23:31
お試しいただきありがとうございます
> Androidの方は、DISPの16bit/32bitで同じくらいな印象でした。
> 元々ゆらぎがあるので、50usくらいの違いの場合はよくわからないというのはありますが・・・
残念、変化なしでしたか…
> 因みに、DISP=16bitの場合、消費してるビデオメモリは少なくなってると考えて大丈夫でしょうか。
> であれば、PC版もAndroid版も 「RGB565, DISP=16bit」を使うのがベストですね。
速度が変化していないとなると内部では 32bitのフレームバッファが使用されていたりする可能性が
あるなど結局デバイス側の実装次第ですが、少なくとも 32bit より多くなることはありませんので、
16bitカラーを使用された方が良いと思います
> という感じでウインドウモードとは逆にウエイト無し側が遅くなりました。
> 謎ですね;(どこかで計測ミスしてる可能性もありますが)
なんと、謎ですね…
> 新関数だとこれらも無効になってしまい、文字入力できなくなってしまいました。
> 何か方法はあるでしょうか。
おお、ギウさんも全て自前で行われているわけではなかったのですね
文字列描画も含めてDXライブラリの描画関数は一切使用できなくなりますので一応仕様の通りではありますが、
R5G6B5 と X8R8G8B8 だけはソフトウェアレンダリングモードが使用しているピクセルフォーマットと同じなので、
DX_USER_SCREEN_PIXEL_FORMAT_R5G6B5 と DX_USER_SCREEN_PIXEL_FORMAT_X8R8G8B8 を指定した場合のみ
DXライブラリの描画関数( ソフトウェアレンダリング相当 )も使用できるようにしてみました
よろしければその変更を加えたバージョンをダウンロードしてください 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 // ソース
(中身を既存のライブラリのファイルに上書きして『リビルド』をして下さい)
ただ、前述の通り DX_USER_SCREEN_PIXEL_FORMAT_R5G6B5 と DX_USER_SCREEN_PIXEL_FORMAT_X8R8G8B8 以外の
DX_USER_SCREEN_PIXEL_FORMAT_X8B8G8R8 や DX_USER_SCREEN_PIXEL_FORMAT_R5G5B5X1 等を指定した場合は
DXライブラリの描画関数は使用できないので注意してください
あと、別の方法として入力中の情報を取得して自前で文字列を描画するという選択肢もあります
GetKeyInputString 入力中の文字列を取得
GetKeyInputCursorPosition カーソル位置を取得
GetIMEInputData IMEで入力中の情報を取得
GetIMEInputModeStr IMEの入力モードの情報を取得
以前作成した入力中文字列の自前描画のサンプルは以下のようになっています
#include "DxLib.h"
#define CANDIDATE_SPACE (20) // 変換候補毎の間隔
#define BOTTOMLINE_Y (20) // 下線を描画する高さ
// 入力文字列を描画する関数
void DrawOriginalInputString( int x, int y, int InputHandle, int OnePageListNum )
{
char String[ 1024 ] ;
const IMEINPUTDATA *ImeData ;
int i, CursorPos, CursorDotPos, SelectClauseX, LineStartX, LineLength, StartNumber ;
// 現時点での確定入力文字列を取得する
GetKeyInputString( String , InputHandle ) ;
// 確定入力文字列を描画する
DrawString( x, y, String, GetColor( 255,255,255 ) ) ;
// カーソルの位置を取得する
CursorPos = GetKeyInputCursorPosition( InputHandle ) ;
// カーソルのドット単位の位置を取得する
CursorDotPos = GetDrawStringWidth( String, CursorPos ) ;
// IME入力情報を取得する
ImeData = GetIMEInputData() ;
// IME入力情報があるかどうか(IME入力をしているかどうか)で処理を分岐
if( ImeData )
{
// IME入力をしている場合
// IMEで入力中の文字列を描画する
DrawString( CursorDotPos + x, y, ImeData->InputString, GetColor( 255,0,0 ) );
// 文節の数だけ下線を描画する
SelectClauseX = x ;
for( i = 0; i < ImeData->ClauseNum ; i++ )
{
// 下線の開始座標を計算
LineStartX = GetDrawStringWidth( ImeData->InputString, ImeData->ClauseData[ i ].Position ) ;
// 下線の長さを計算
LineLength = GetDrawStringWidth( ImeData->InputString + ImeData->ClauseData[ i ].Position, ImeData->ClauseData[ i ].Length ) ;
// 下線の描画
DrawLine( CursorDotPos + LineStartX + 1 + x, y + BOTTOMLINE_Y,
CursorDotPos + LineStartX + LineLength - 1 + x, y + BOTTOMLINE_Y,
GetColor( 255,255,0 ) ) ;
// もし選択している文節だった場合は文節の開始座標を保存しておく
if( i == ImeData->SelectClause )
{
SelectClauseX = CursorDotPos + LineStartX + x ;
}
}
// カーソルの描画
LineStartX = GetDrawStringWidth( ImeData->InputString, ImeData->CursorPosition ) ;
DrawBox( CursorDotPos + x + LineStartX, y, CursorDotPos + x + LineStartX + 2, y + 16, GetColor( 255,255,255 ), TRUE ) ;
// 変換候補リストが存在する場合は描画処理を行う
if( ImeData->CandidateNum )
{
// 変換候補リストの開始ナンバーを計算
StartNumber = ImeData->SelectCandidate / OnePageListNum * OnePageListNum ;
// 変換候補リストの同時表示数に達するか、変換候補リストの終端に来るまでループ
for( i = 0; StartNumber + i < ImeData->CandidateNum && i < OnePageListNum; i ++ )
{
// 変換候補の描画
DrawString( SelectClauseX, i * CANDIDATE_SPACE + y + 24, ImeData->CandidateList[ StartNumber + i ], GetColor( 0,255,0 ) ) ;
}
// 選択している変換候補を囲う枠の描画
DrawBox(
SelectClauseX - 2,
( ImeData->SelectCandidate - StartNumber ) * CANDIDATE_SPACE + y + 22,
SelectClauseX + 2 + GetDrawStringWidth( ImeData->CandidateList[ ImeData->SelectCandidate ], _tcslen( ImeData->CandidateList[ ImeData->SelectCandidate ] ) ),
( ImeData->SelectCandidate - StartNumber ) * CANDIDATE_SPACE + y + 42,
GetColor( 0,255,128 ), FALSE ) ;
}
}
else
{
// IME入力をしていない場合
// カーソルを描画
DrawBox( x + CursorDotPos, y, x + CursorDotPos + 2, y + 16, GetColor( 255,255,255 ), TRUE );
}
}
// WinMain 関数
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
int InputHandle ;
TCHAR String[ 512 ] ;
// ウインドウモードで起動
ChangeWindowMode( TRUE ) ;
// DXライブラリの初期化
if( DxLib_Init() == -1 ) return -1 ;
// 描画先を裏にする
SetDrawScreen( DX_SCREEN_BACK ) ;
// キー入力ハンドルを作る(キャンセルなし全角文字有り数値入力じゃなし)
InputHandle = MakeKeyInput( 50 , FALSE , FALSE , FALSE ) ;
// 作成したキー入力ハンドルをアクティブにする
SetActiveKeyInput( InputHandle ) ;
// メインループ
while( ProcessMessage() == 0 )
{
// 入力が終了している場合は終了
if( CheckKeyInput( InputHandle ) != 0 ) break ;
// 画面の初期化
ClearDrawScreen() ;
// 入力モードを描画
DrawKeyInputModeString( 640 , 480 ) ;
// 入力中文字列の描画
DrawOriginalInputString( 100, 100, InputHandle, 5 ) ;
// 裏画面の内容を表画面に反映させる
ScreenFlip() ;
}
// 入力された文字列を取得
GetKeyInputString( String , InputHandle ) ;
// 用済みのインプットハンドルを削除する
DeleteKeyInput( InputHandle ) ;
// 画面の初期化
ClearDrawScreen() ;
// 入力された文字列を画面に表示する
DrawString( 0 , 0 , "あなたが入力した文字列は", GetColor( 255 , 255 , 255 ) ) ;
DrawString( 0 , 16 , String , GetColor( 255 , 255 , 255 ) ) ;
// 裏画面の内容を表画面に反映させる
ScreenFlip() ;
// キー入力待ち
WaitKey() ;
// DXライブラリの使用終了
DxLib_End() ;
// 終了
return 0 ;
}
そして、このサンプルの動作を確認中に GetKeyInputCursorPosition にバグがあることを発見し
修正しましたので、上記のプログラムを実行する場合も更新版のDXライブラリをお使いください m(_ _;m
 |
Re: DIBやDirectXについて ( No.10 ) |
- 名前:ギウ(解決) 日時:2019/05/26 10:41
>管理人様
ありがとうございます!
(ひとまず以前の方法で)動作確認しました。助かります!
>おお、ギウさんも全て自前で行われているわけではなかったのですね
はい、DXLibを使うまでは、お手軽なダイアログボックスでの入力を使ってました。
DXLibでやってるようなきちんとしたのを作るのが大変そうだったのと、どちらにしてもWindows固有のAPIを使わないといけないので。
(元々、WindowsのAPIやDirectX(初期はまともに動かなかった)が信用できない→可能な限りAPIを使わない。という流れできてる為)
ということで今はお手軽に実装できるDXLibの恩恵にあずかってます^^
今回もありがとうございました。
今後ともよろしくお願いいたします。
|
Re: DIBやDirectXについて ( No.11 ) |
- 名前:管理人(解決) 日時:2019/05/27 23:27
> (ひとまず以前の方法で)動作確認しました。助かります!
あれ?
すみません、以前の方法というのは ReCreateGraphFromSoftImage を使用する最初の方法でしょうか?
あと、よろしければギウさんが開発されたソフトウェアレンダリングシステムが対応しているピクセルフォーマットに
ついて教えていただけないでしょうか?
1. R5G5B5X1 と R5G6B5 にネイティブに( 最高速度動作に )対応している
2. 対応しているのは R5G5B5X1 のみで、R5G6B5 や X8R8G8B8 などに最後に変換を行って対応
ギウさんのシステムは上記の 1 と 2 のどちらでしょうか?
> 元々、WindowsのAPIやDirectX(初期はまともに動かなかった)が信用できない
Riva, Rage, Savage, Voodoo, Matrox などがひしめいていた頃は酷かったですね…
( 私も昔バイトで開発したキータイピング練習ソフトはビデオカード毎の動作テストが大変だからと
ソフトウェアレンダリングで開発する方針になりました )
|
Re: DIBやDirectXについて ( No.12 ) |
- 名前:ギウ(解決) 日時:2019/05/28 07:49
>管理人様
>すみません、以前の方法というのは ReCreateGraphFromSoftImage を使用する最初の方法でしょうか?
あ、
GetIMEInputData などを使わない、「Re: DIBやDirectXについて ( No.8 )」で書いた方法で、という意味で書きました。
ゲーム自体は、X_USER_SCREEN_PIXEL_FORMAT_R5G6B5 を使わせてもらってます。
>1. R5G5B5X1 と R5G6B5 にネイティブに( 最高速度動作に )対応している
こっちです。
今回のでR5G6B5がPCでもAndroidでも最速ということがわかりましたので(ビデオ―カードによるかもですが、多分、多数派かなと)、
現在は、R5G6B5で統一しました。
※今はフラグで R5G5B5、R5G6B5、R5G5B5X1、X8R8G8B8を切り替えできるようになってます。
>ソフトウェアレンダリングで開発する方針になりました
なるほど、出発点は私も似た感じです。
今ではほとんど「失われた技術」みたいになってますけどw
|
Re: DIBやDirectXについて ( No.13 ) |
- 名前:管理人(解決) 日時:2019/05/29 00:42
> あ、
> GetIMEInputData などを使わない、「Re: DIBやDirectXについて ( No.8 )」で書いた方法で、という意味で書きました。
> ゲーム自体は、X_USER_SCREEN_PIXEL_FORMAT_R5G6B5 を使わせてもらってます。
>
> >1. R5G5B5X1 と R5G6B5 にネイティブに( 最高速度動作に )対応している
>
> こっちです。
> 今回のでR5G6B5がPCでもAndroidでも最速ということがわかりましたので(ビデオ―カードによるかもですが、多分、多数派かなと)、
> 現在は、R5G6B5で統一しました。
> ※今はフラグで R5G5B5、R5G6B5、R5G5B5X1、X8R8G8B8を切り替えできるようになってます。
なるほど、フラグで切り替えられるようになっているのですね
このスレッドの最初のお書き込みでは R5G5B5X1 を使用されているというお話だったので、
「R5G6B5 には対応していないので ReCreateGraphFromSoftImage に戻したのだろうか?」
「でも No.6 では R5G6B5 にネイティブに対応しているようなお書き込みが…?」
と、少し疑問を持ってしまったのでご質問してしまいました、ご返答ありがとうございます m(_ _;m
|
|