SDL2の使い方

SDL2は日本語の情報があんまりなくて、SDL2そのままの使い勝手でRubyから使えますというライブラリを作っても、使える人は限られるのではないかと言うことで、基本的なことを書いておくことにした。とりあえずはおおまかな概念だけ。
関数の一覧および使い方はSDL2.0日本語リファレンスマニュアルを参照するとよい。あとはSDL2のソースとか。

SDL2の基本オブジェクト

SDL2の関数を呼び出して生成するSDLオブジェクトには、だいたい
SDL_Window
SDL_Surface
SDL_Renderer
SDL_Texture
といったものがある。これらはSDL2の生成関数を呼び出したら返ってくるし、関数に引数として渡して使ったりもする。OSやGPUのリソースを管理するものである。他、SDL_Mixerを使えばMix_ChunkやMix_Music、SDL_ttfではTTF_Fontなどを扱うことになる。SDL_imageはSDL_Surfaceが返ってくるので独自オブジェクトは無い。

SDL_Window

SDL2の関数であるSDL_CreateWindowを呼び出すと返ってくる、アプリのウィンドウを表現するオブジェクトである。パラメータにもよるが、基本的には呼び出すと画面にウィンドウが出る。こいつをSDL_DestroyWindowするとウィンドウが消える。サイズを変えたりその他もろもろいろんな操作ができる。通常、SDLを使うアプリはウィンドウを使うので、SDL_Windowがもっとも基本のオブジェクトとなる。
なお、SDL_CreateWindowを何度も呼ぶとウィンドウをたくさん作ることができる。これはSDL2の新機能である。

SDL_Surface

SDLの画像データを扱うオブジェクト。SDL1.2の頃はウィンドウの描画領域もSurfaceで表現していた。Surfaceへの画像の書き込み、読み出しはソフトウェア(一部GPUサポート)でやることになるので大変遅かったが、SDL2ではRendererを使って描画するので大変速くなった。面倒だけど。一応、SDL2でもSurfaceベースの描画で画面を作る機能は残っているが、遅いのでオススメしない。
SDL_imgaeで画像ファイルを読み込むとSurfaceが作られるので、SDL2ではこれをTextureに変換してRendererで描画するという手順になる。

SDL_Renderer

SDL2の描画が速いのはDXRubyと同様に3Dハードウェアで2D描画をするためであり、3Dハードウェアを抽象化したのがSDL_Rendererである。Rendererはウィンドウ1つに対して1つ生成することができ、複数生成しようとするとエラーになる。このRendererに後で説明するSDL_Textureを渡すことで、3Dハードウェアがウィンドウに描画してくれる。

SDL_Texture

3Dハードウェアで描画するためにはVRAMに画像データを置いておく必要がある。VRAM上の画像データを表すのがSDL_Textureとなる。Surfaceは基本的にはメインメモリ上に置かれるのでCPUからデータにアクセスできるが、TextureはCPUから読み書きできない。その代わりGPUから高速アクセスができるので高速描画ができる、という寸法である。
Textureの画像データへはSDL_LockTextureで一方通行の書き込み専用メモリ領域を作ることができる。また、SDL_RenderReadPixelsを使うと読み出すこともできるが大変遅い。
従って、データを書き換えながら描画するような場合はSurfaceとTextureを用意しておいて、Surfaceを書き換える→SDL_LockTextureで書き換えた部分だけ転送という手順が最も高速になるが、面倒なら毎回SDL_CreateTextureFromSurfaceを使ってSurfaceからTextureを作ってしまえばよいだろう。前のはSDL_DestroyTextureできちんと消さないとVRAMが足りなくなる。
なんにせよ、SDL2は速いぶんめんどくさいのである。まあ、固定の画像ならさほど面倒ではないし、Surfaceでは厳しかったスケーリングや回転も高速にやってくれるので受け入れたほうが良い。

入力

ユーザの入力は基本的にはイベント処理で受け取る。直接調べるような関数も用意されてはいるが、内部ではイベントで処理するように実装されているのでどっちも同じである。
イベントは通常SDL_PollEventで受け取り、返ってきたSDL_Event構造体の中身をチェックして処理する。ゲームなんかでは1フレームに1回、イベントが無くなるまでSDL_PollEventを繰り返してまとめて処理することになる。イベント処理内でキーボードの状態やらマウスの状態やらを保存しておいて、ゲームの本処理でそれを参照する、というのがよくある実装である。

その他

SDL2はAndroidiPhoneにまで対応しているので、それら用のイベントが用意されていたりする。また、幅広いマルチプラットフォームに対応するのでたとえば画像のピクセルフォーマットは多種多様なものが使えるし、エンディアン違いにも対応するし、他、SDL2.0日本語リファレンスマニュアルにも書かれていないような微妙なマクロがたくさんある。フルに機能を使うのは無茶もいいところなので、とりあえず動けばいいんじゃなーいぐらいに考えておくのがよさげである。