GDI+SDLがおしゃれなんですよ(違

STATUS: 故障中

 いま作っているゲームは、グラフィックはGDI+DIBでやってます。
 DIBSectionなので、メモリを直接操作出来るし、GDIの描画APIも使えるしで楽ちん。
 でも、ぜんぶソフト処理になっちゃうので速度的にはちょっと不利。
 といっても一番処理に時間がかかっているのは、DIBのイメージを画面(V-RAM)に転送するところのようです。
 ここはもっとビデオカードアクセラレーション効いてもバチは当たらないんじゃないかなあ。
 
 まあ速度的にはここ数年のマシンだったら全く問題ないのでいいのです。きっと。
 でも、全画面表示をしようとか言い出すとちょっと困ってしまいます。
 そこで、SDLで全画面表示モードにしてから、SDLのサーフェイスにDIBのメモリイメージを転送してやったらいいんじゃないかと思って試してみました。
 …結果、簡単に全画面に対応できました。うーんSDLは単純でイイ
 

SDLで全画面なソース

m_game.Create();

SDL_Init(SDL_INIT_VIDEO);

SDL_Surface *pScreen = reinterpret_cast(SDL_SetVideoMode(640, 480, 24, SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_FULLSCREEN));
SDL_Rect rectScreen;
rectScreen.x = 0;
rectScreen.y = 0;
rectScreen.w = pScreen->w;
rectScreen.h = pScreen->h;

SDL_Surface *pGame = SDL_CreateRGBSurface( SDL_HWSURFACE , 640,480,24 , 0x00ff0000 , 0x00ff0000 , 0x000000ff , 0x00000000);

while(true) {
        m_game.Action();
        m_game.Draw( NULL , 0,0 );

        SDL_LockSurface( pGame );
        memcpy( pGame->pixels , m_game.GetSceneImage().GetBits() , m_game.GetSceneImage().GetWidthBytes() * m_game.GetSceneImage().GetHeight() );
        SDL_UnlockSurface( pGame );

        SDL_BlitSurface(pGame,&rectScreen,pScreen,&rectScreen );
        SDL_Flip(pScreen);
}

SDL_FreeSurface(pGame);
SDL_FreeSurface(pScreen);
SDL_Quit();

 m_gameがゲームクラスです。
 m_game.Draw( NULL , 0,0 );で、クラス内にDIBSectionのサーフェイスが出来ます。
 m_game.GetSceneImage().GetBits();で、サーフェイスのメモリアドレスを取得しています。
 あとは、SDLのサーフェイスにmemcpyでコピーしてるだけ。

 で、動いたのはいいのですが、なんか遅い〜。
 全画面モードで 40fpsしか出ない。
 SDL_Flip(pScreen);だけで計っても 60fpsしか出ない。CPUの使用率は100%になってるし。
 なんでだろ。ちなみに SDL_HWSURFACEをSDL_SWSURFACEにしても同じ結果でした。うーむ。
 さらにウィンドウモードでも同じ結果でした。

 ちなみに、DIBをWindowsBitBlt APIで画面に描画すると 115fps出ます。
 最後の画面描画だけでもSDL使ったら速くなるかな〜と期待していたのですが…。

【マシンスペック】
CPU:Pentium4 1.7GHz
RAM:512MByte
VIDEO:GeForce440MX (3200x1200x16bit mode)

 やっぱり画面の色数とサーフェイスの色数が違っちゃまずいよなと、画面、DIB、SDLサーフェイスそれぞれを32bit色モードにしてみたところ 60fpsでました。フルスクリーンだと、65fpsです。やった〜
 でもSDL使わないバージョン(bitblt版)では、この状態でも 115fpsでてるんだよなあ。
 SDL版ではmemcpyとSDL_BlitSurfaceの分が響いているぽい。これ外したら95fps出るようになったけど、これでは画面には何にも表示されないわけで…。
 GDI+SDL作戦はいまいちな結果に終わってしまいました。まあ、全画面表示用には使えるか。 

コメント