Nanashi-soft○プログラマ専用○PS3 Linux SDL○
現状は RSXの仕様が隠蔽されていて、実質フレームバッファしか使用できません(2007/02現在)
「それだと何もできない」と思っている人が多いので、どのくらいダメなの? 本当にダメなの? という所を検証してみました
まずはベンチマークを取る為の雛形を作成しました
1秒間に何回描画できるのか? を測ります。それが一番分かり易いでしょう
ちなみに、この雛形状態だと 231298fpsでしたw
#include "SDL.h"
int main(int args,char *argp[]){
//初期化
if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) < 0){
return -1;
}
SDL_Surface *screen=SDL_SetVideoMode(1920,1080,32,SDL_SWSURFACE);
if(screen == NULL){
SDL_Quit();
return -1;
}
int done = 0;
SDL_Event event;
int fps=0;
Uint32 t1=SDL_GetTicks();
while(!done){
while(SDL_PollEvent(&event)){
switch(event.type){
case SDL_QUIT:
done = 1;
break;
case SDL_KEYDOWN:
if(event.key.keysym.sym == SDLK_ESCAPE){
done = 1;
}
break;
}
}
//ここに処理を追加して変化を見る
if(SDL_GetTicks() < t1 + 1000){
fps++;
}
else{
printf("fps=%d\n", fps);
fps=0;
t1=SDL_GetTicks();
}
}
SDL_Quit();
}
RGB(24bit)で羅列したデータを、直接描画して測ってみます
グローバル変数にこの裏画面を生成して、SDL_CreateRGBSurfaceFromでサーフェスにします
~
unsigned char gUra[1920*1080*3];//裏画面
~
int main(int args,char *argp[]){
~
while(!done){
~
//ここに処理を追加して変化を見る
SDL_Surface *bitmap = SDL_CreateRGBSurfaceFrom((void *)gUra,1920,1080,24,1920*3,0xff0000,0xff00,0xff,0);
SDL_BlitSurface(bitmap,NULL,screen,NULL);
SDL_UpdateRect(screen,0,0,0,0);
~
これを計測すると 5fpsでしたよ(*'-')
うはw 5fpsじゃ何も作れないよorz
……と思ったら、そこで終わりです
このような際物機器では、自動で最適化される事がありません
自力で最適化して、速度を上げていくのが常識なのです
データをそのまま渡してしまった事が間違いだと思うので、今度はフレームバッファのフォーマットに自力で合わせてから送ってみます
unsigned char gUra[1920*1080*3];//裏画面
Uint32 pix[1920*1080];//ワーク用画面
~
int main(int args,char *argp[]){
~
//ここに処理を追加して変化を見る
int x, y;
Uint32 *pixp = pix;
unsigned char *gUrap=gUra;
for(y=0; y < 1080; y++){
for(x=0; x < 1920; x++){
unsigned int r = *gUrap++;
unsigned int g = *gUrap++;
unsigned int b = *gUrap++;
*pixp++ = (r << 16) + (g << 8) + b;
}
}
SDL_Surface *bitmap = SDL_CreateRGBSurfaceFrom((void *)pix,1920,1080,32,1920*3,0xff0000,0xff00,0xff,0);
SDL_BlitSurface(bitmap,NULL,screen,NULL);
SDL_UpdateRect(screen,0,0,0,0);
~
このままだとやっぱり 5fpsです
コンパイラオプションに最適化を付けると、劇的にスピードアップします
gcc -O2 -o 「拡張子無しファイル名」「ファイル名」 `sdl-config --cflags --libs`
そうすると、25fps出ました(^_^)
更に、この場合SDL_SWSURFACEを SDL_HWSURFACEにするだけで 36fpsにアップします
blitが高速化される為だと思われます
ふと思いました
裏画面を最初からフレームバッファと同じフォーマットにしておいたらどうでしょう?
PS3はハード的に固定なので、専用であればそれで良いはずです
Uint32 gUra[1920*1080*4];//裏画面
~
int main(int args,char *argp[]){
~
//ここに処理を追加して変化を見る
SDL_Surface *bitmap = SDL_CreateRGBSurfaceFrom((void *)gUra,1920,1080,32,1920*3,0xff0000,0xff00,0xff,0);
SDL_BlitSurface(bitmap,NULL,screen,NULL);
SDL_UpdateRect(screen,0,0,0,0);
裏画面と実画面の構造が同じなので、変換する必要が無い
こうすると 105fpsでました!
更に、グローバルでは無くヒープの方に置いて実験してみたところ……
int main(int args,char *argp[]){
Uint32 *gUra=(Uint32*)malloc(1920*1080*4);//ワーク用画面
~
while(!done){
~
//ここに処理を追加して変化を見る
SDL_Surface *bitmap = SDL_CreateRGBSurfaceFrom((void *)gUra,1920,1080,32,1920*3,0xff0000,0xff00,0xff,0);
SDL_BlitSurface(bitmap,NULL,screen,NULL);
SDL_UpdateRect(screen,0,0,0,0);
そうすると 229fpsでました(*'-')
以上の検証より、SDLでは、実画面に合わせたフォーマットのデータを扱う事によりスピードアップすると言うことが分かりました
逆に言えば、独自フォーマットを使用すると劇的に速度低下を起こすと言う事ですので、注意が必要ですね
全グラフィックをハードウェアサーフェス上に置いて、それを表示したらもっと速いでしょう
フルHD(1920×1080画面で毎秒60コマ表示)も夢では無いかも知れませんよ
ぜひ、みなさんもチャレンジしてみて下さい