トップページ > 記事閲覧
テキスト描画時の処理落ち
名前:anekitt 日時: 2014/05/25 23:03

質問させていただきます。 最近DrawStringToHandleでテキストを画面に表示すると処理落ちするようになってしまいました。 色々原因を調べてみたのですが、画面に多くの種類のテキストを描画すると処理落ちが激しくなるようなのです。 同じテキストを描画する分には処理落ちはしないので、キャッシュ的なものが働いてるのかなーとは思うのですが、対策が思いつきません。知恵をお貸しいただけたらと思います。 ちょっと説明が難しいので、サンプルを作ってみました。 #include "DxLib.h" // WinMain関数 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { char str_data1[1024], str_data2[1024]; int FontHandle; char work[3]; char text[256]; int i, x = 0, y = 0, count; // DXライブラリの初期化 SetGraphMode(640 * 2, 480 * 2, 32); ChangeWindowMode(true); if( DxLib_Init() == -1 ) return 0 ; SetDrawScreen(DX_SCREEN_BACK); FontHandle = CreateFontToHandle( NULL , 40 , 3 , DX_FONTTYPE_ANTIALIASING_EDGE) ; str_data1[0] = '\0'; for(i = 0;i < 100;i++){ strcat(str_data1, "あ"); } strcpy(str_data2, "あいうえおかきくけこ"); strcat(str_data2, "さしすせそたちつてと"); strcat(str_data2, "なにぬねのはひふへほ"); strcat(str_data2, "まみむめもらりるれろ"); strcat(str_data2, "やゆよわんぁぃぅぇぉ"); strcat(str_data2, "アイウエオカキクケコ"); strcat(str_data2, "サシスセソタチツテト"); strcat(str_data2, "ナニヌネノハヒフヘホ"); strcat(str_data2, "マミムメモラリルレロ"); strcat(str_data2, "ヤユヨワンァィゥェォ"); while(1){ ClearDrawScreen(); //「あ」を100回描画 x = 0; y = 0; count = GetNowCount(); for(i = 0;i < 100;i++){ work[0] = str_data1[i * 2]; work[1] = str_data1[i * 2 + 1]; work[2] = '\0'; DrawStringToHandle(x, y, (char *)work, GetColor(255, 255, 255), FontHandle); x += 40; if(x > 1280){ x = 0; y += 40; } if(y > 900){ y = 0; } } sprintf(text, "「あ」100回描画で : %d ms", GetNowCount() - count); DrawStringToHandle(350, 200, text, GetColor(255, 255, 255), FontHandle); //いろいろ100回描画 x = 0; y = 400; count = GetNowCount(); for(i = 0;i < 100;i++){ work[0] = str_data2[i * 2]; work[1] = str_data2[i * 2 + 1]; work[2] = '\0'; DrawStringToHandle(x, y, (char *)work, GetColor(255, 255, 255), FontHandle); x += 40; if(x > 1280){ x = 0; y += 40; } if(y > 900){ y = 0; } } sprintf(text, "いろいろ100回描画で : %d ms", GetNowCount() - count); DrawStringToHandle(350, 600, text, GetColor(255, 255, 255), FontHandle); ScreenFlip(); ProcessMessage(); if(CheckHitKeyAll() != 0)break; } // 作成したフォントデータを削除する DeleteFontToHandle( FontHandle ) ; // DXライブラリの終了 DxLib_End() ; // ソフトの終了 return 0 ; } 「あ」だけを100回描画するのと、いろいろな文字を100回描画するのを比較してます。 うちの環境ですと、「あ」の方は1ms以内で、いろいろな文字を描画する方は17〜18msほどかかっています。 お忙しいとは思いますが、何卒よろしくお願いします。
メンテ

Page: 1 |

Re: テキスト描画時の処理落ち ( No.1 )
名前:管理人 日時:2014/05/26 01:18

お察しの通り一度描画したものをキャッシュして高速描画を実現しているのですが、 キャッシュから溢れると再度キャッシュする処理が実行されるので、その場合に > いろいろな文字を描画する方は17〜18msほどかかっています。 のような高負荷状態が発生してしまいます サンプルプログラムを実行させて頂いたところ、キャッシュできる文字数は 81文字でした( フォントのサイズによって変化します ) 「いろいろな文字を描画する方」では100文字描画しているので、毎フレームキャッシュから 文字が溢れてしまい、毎フレーム再キャッシュが行われ処理負荷が高い状態になってしまっていました 解決策としてはキャッシュする文字数を非公開の関数 SetFontCacheCharNum で 増やすという方法があります // フォントキャッシュでキャッシュできる文字数を設定する int SetFontCacheCharNum( int CharNum ) ; キャッシュする文字数は CreateFontToHandle でフォントハンドルを作成する際に 決定するので、CreateFontToHandle を呼ぶ前にこの関数でキャッシュしたい文字数を 設定しておくことでキャッシュできる文字数を変更することができます サンプルプログラムでは100文字使用しているので、 FontHandle = CreateFontToHandle( NULL , 40 , 3 , DX_FONTTYPE_ANTIALIASING_EDGE) ; こちらの CreateFontToHandle を呼ぶ1行前に SetFontCacheCharNum( 100 ) ;を追加して SetFontCacheCharNum( 100 ) ; FontHandle = CreateFontToHandle( NULL , 40 , 3 , DX_FONTTYPE_ANTIALIASING_EDGE) ; としてみたところ、「いろいろな文字を描画する方」も1ms以内で処理が完了するようになりました 実際は100文字ぴったりということは無いと思いますので、画面に同時に表示される 文字数に合わせて SetFontCacheCharNum に渡す値を調節してみてください 因みに、キャッシュする文字数を増やすとそれだけシステムメモリとVRAMを多く必要と しますので、キャッシュする文字数は必要最低限に抑えるようにしてください
メンテ
Re: テキスト描画時の処理落ち ( No.2 )
名前:anekitt(解決) 日時:2014/05/26 05:32

解決しました。 まさに求めていたものでした。 しっかりヘッダも読まないとダメですね・・・。 本当にありがとうございました。
メンテ

Page: 1 |

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

   クッキー保存