トップページ > 記事閲覧
高速描画について
名前:TS 日時: 2019/07/27 17:51

こちらの記事で、画像の高速描画についての記載がありました。 ttps://qiita.com/YYSS_101/items/160772c9a57ab44cf559 1つの画像ファイルを分割して読み込ませると描画が早くなったり、 ブレンドモードの切り替えを減らすと描画が高速化できるといったもので、 DirectXの仕様的になるほどと思ったのですが、 SetDrawBlendMode( DX_BLENDMODE_ALPHA, 255 ); for( int i=0 ; i<Loops ; i++ ) { DrawGraph( 100, 100, img1, trans ); DrawGraph( 100, 200, img1, trans ); DrawGraph( 100, 300, img1, trans ); DrawGraph( 100, 400, img1, trans ); } と for( int i=0 ; i<Loops ; i++ ) { SetDrawBlendMode( DX_BLENDMODE_ALPHA, 255 ); DrawGraph( 100, 100, img1, trans ); SetDrawBlendMode( DX_BLENDMODE_ALPHA, 255 ); DrawGraph( 100, 200, img1, trans ); SetDrawBlendMode( DX_BLENDMODE_ALPHA, 255 ); DrawGraph( 100, 300, img1, trans ); SetDrawBlendMode( DX_BLENDMODE_ALPHA, 255 ); DrawGraph( 100, 400, img1, trans ); } では、ほぼ同じにも関わらず、描画速度に大きな差が出てます。 ブレンドモードを毎回指定した方が描画が早くなるのでしょうか? それとも、環境による誤差なのでしょうか?
メンテ

Page: 1 |

Re: 高速描画について ( No.1 )
名前:管理人 日時:2019/07/29 22:34

> ブレンドモードを毎回指定した方が描画が早くなるのでしょうか? いえ、毎回指定しない方が高速です 試しに以下のようなテストプログラムを組んで計測してみました ( 実行するときは計測しない方のプログラムをコメントアウト ) #include "DxLib.h" #define Loops 60000 #define trans TRUE int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int img1 ; int FPS ; int FrameCounter ; LONGLONG Time ; LONGLONG StartTime ; // ウィンドウモードで起動 ChangeWindowMode( TRUE ) ; // VSync待ちをしない SetWaitVSyncFlag( FALSE ) ; if( DxLib_Init() == -1 ) // DXライブラリ初期化処理 { return -1 ; // エラーが起きたら直ちに終了 } // 画像を読み込み img1 = LoadGraph( "16x16.bmp" ) ; // 描画先を売ら画面に変更 SetDrawScreen( DX_SCREEN_BACK ) ; // 変数の初期化 FPS = 0 ; FrameCounter = 0 ; StartTime = GetNowHiPerformanceCount() ; // メインループ while( ProcessMessage() == 0 ) { // 画面の初期化 ClearDrawScreen() ; SetDrawBlendMode( DX_BLENDMODE_ALPHA, 255 ); for( int i=0 ; i<Loops ; i++ ) { DrawGraph( 100, 100, img1, trans ); DrawGraph( 100, 200, img1, trans ); DrawGraph( 100, 300, img1, trans ); DrawGraph( 100, 400, img1, trans ); } /* for( int i=0 ; i<Loops ; i++ ) { SetDrawBlendMode( DX_BLENDMODE_ALPHA, 255 ); DrawGraph( 100, 100, img1, trans ); SetDrawBlendMode( DX_BLENDMODE_ALPHA, 255 ); DrawGraph( 100, 200, img1, trans ); SetDrawBlendMode( DX_BLENDMODE_ALPHA, 255 ); DrawGraph( 100, 300, img1, trans ); SetDrawBlendMode( DX_BLENDMODE_ALPHA, 255 ); DrawGraph( 100, 400, img1, trans ); }*/ // FPSの表示 DrawFormatString( 0, 0, GetColor( 255,255,255 ), "FPS:%d", FPS ) ; // 裏画面の内容を表画面に反映 ScreenFlip() ; // FPS処理 FrameCounter++; Time = GetNowHiPerformanceCount() ; if( Time - StartTime >= 1000000 ) { StartTime = Time ; FPS = FrameCounter ; FrameCounter = 0 ; } } DxLib_End() ; // DXライブラリ使用の終了処理 return 0 ; // ソフトの終了 } 縦横16ピクセルの画像を使用して載せていただいたプログラムを片方づつ試してみたのですが、手元の環境では 196FPS : SetDrawBlendMode( DX_BLENDMODE_ALPHA, 255 ); を最初に一回だけ 175FPS : DrawGraph の前に毎回 SetDrawBlendMode( DX_BLENDMODE_ALPHA, 255 ); を実行 と、SetDrawBlendMode( DX_BLENDMODE_ALPHA, 255 ); を最初に一回だけ実行した場合の方が高速でした よろしければ TSさんの環境でも SetDrawBlendMode( DX_BLENDMODE_ALPHA, 255 ); を最初に一回だけ実行した 場合の方が高速に実行されるか試してみてください m(_ _)m // 16x16.bmp はこちらです https://dxlib.xsrv.jp/temp/16x16.bmp
メンテ
Re: 高速描画について ( No.2 )
名前:.m1v 日時:2019/07/30 06:24

DxLibは効率化のため、描画命令を実行してもすぐに描画されるとは限らない。(あとでまとめて描画) そのため、部分的に時間を計測してもあまり意味がない。(その時点で描画されているかもしれないし、されていないかもしれない) 通常は、ScreenFlip()でまとめて描画されることが多い。(VSync待ちをFalseにして、FPSを計測する方法がよい) 部分的に時間を測定したいがScreenFlip()までは使いたくないのであれば、RenderVertex()を使う といったところでしょうか?
メンテ
Re: 高速描画について ( No.3 )
名前:TS 日時:2019/08/02 10:45

返答遅れました。 自分の環境で試してみたところ、 ・SetDrawBlendMode( DX_BLENDMODE_ALPHA, 255 ); を最初に一回だけ  293〜306FPS  平均:3.30ms ・DrawGraph の前に毎回 SetDrawBlendMode( DX_BLENDMODE_ALPHA, 255 ); を実行  296〜306FPS  平均:3.31ms でした。 自分の環境ではほとんど違いがなかったので、 環境によって異なるって感じですかね・・・。 >> DxLibは効率化のため、描画命令を実行してもすぐに描画されるとは限らない。(あとでまとめて描画) >> そのため、部分的に時間を計測してもあまり意味がない。(その時点で描画されているかもしれないし、されていないかもしれない) >> 通常は、ScreenFlip()でまとめて描画されることが多い。(VSync待ちをFalseにして、FPSを計測する方法がよい) >> 部分的に時間を測定したいがScreenFlip()までは使いたくないのであれば、RenderVertex()を使う そういうことであれば、あの記事の検証方法は精度に欠けてるかもしれませんね。 記事を書いた人に一言伝えておこうかと思います。
メンテ
Re: 高速描画について ( No.4 )
名前:管理人 日時:2019/08/03 00:55

> .m1vさん 確かに、TSさんご紹介のゆゆさんの記事は DrawGraph だけの計測になっていますね DrawGraph 関数から処理が出てきた時点では描画は行われているとは限らないので、 正常な計測にはならないですね… > 部分的に時間を測定したいがScreenFlip()までは使いたくないのであれば、RenderVertex()を使う RenderVertex を用いればOK、と私も思ったのですが、考えてみたらそれでも 正常な描画負荷の計測はできないことに気付きました Direct3D はメインスレッドとは別のスレッドで描画処理を行っているので、 RenderVertex を呼んで Direct3D 11 の描画APIを呼んで処理が API から 返ってきても、その時点では描画処理が終わっているという保証が無いからです なので、正確な描画負荷を計測するには No.1 のサンプルプログラムのように SetWaitVSyncFlag( FALSE ); で VSYNC を OFF にした状態で FPS を計測するしかありません… > TSさん > 自分の環境ではほとんど違いがなかったので、 > 環境によって異なるって感じですかね・・・。 二つの処理で異なるのはCPUの負荷なので、CPUの負荷よりもGPUの負荷( 実際の描画処理 )の方が 高ければ高いほど二つの処理のFPSの差は小さくなっていくと思います ただ、少なくとも『毎回』が『最初に一回』より高速に処理される理屈が存在しないので、 正しく計測した場合は差が限りなく小さくなることはあっても、『毎回』が『最初に一回』より 高速になることは無い筈です
メンテ
Re: 高速描画について ( No.5 )
名前:TS(解決済み) 日時:2019/08/06 09:21

>>ただ、少なくとも『毎回』が『最初に一回』より高速に処理される理屈が存在しないので、 >>正しく計測した場合は差が限りなく小さくなることはあっても、『毎回』が『最初に一回』より >>高速になることは無い筈です 確かに、私の環境では差がありませんでしたが、 ほかの環境では差が出ることを考えると『最初に1回』を採用した方が確実ですね。 参考にしたいと思います。 とりあえず、記事の投稿者にこの掲示板の内容を伝えて、 編集リクエストをしておきました。 色々とありがとうございました。
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存