見出し画像

ローグライク(仮)SDL2のMetal化とヴィジュアルアート

今日は、というかこの頃体の調子が悪くてほとんど作業できていないのだが、まずは SDL の macOS の描画を Metal にする方法について。

技術的な解説

昨日説明した以下のコードは勘違いをしており、SDL_GetRenderDriverInfo は SDL がその環境で使用できる複数の描画ドライバを取得できる方法だった。このコードの場合は 0 番目の描画ドライバの情報を取得していた。

SDL_RendererInfo info;
SDL_GetRenderDriverInfo(0, &info);
std::cout << info.name << std::endl;

なので、この方法では現在使用されている描画ドライバが取得できるわけではなかった。なので今日はひたすら SDL2 のソースコードを読み漁り、Metal の API がどのように呼び出されているかを理解する時間にした。
その甲斐があり、Metal を使った描画に変更することができるようになった。

int render_driver_index = -1;
SDL_RendererInfo info;
for (int i = 0; i < SDL_GetNumRenderDrivers(); i++) {
  SDL_GetRenderDriverInfo(i, &info);
  if (std::string(info.name) == "metal") {
    render_driver_index = i;
  }
}

auto renderer = SDL_CreateRenderer(window, render_driver_index,
                   SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);

このようなコードで、レンダラーを作成すると Metal が使用できる。SDL_CreateRenderer の第2引数は SDL_GetRenderDriverInfo で取得するインデックスと同じものを使う。また、-1 を使用するとデフォルトの挙動となる。なので、描画ドライバの名前が "metal" になるインデックスを調べてからレンダラーを作るようにすればよかった。

本当に Metal で描画されているかを確認することもできる。SDL_RenderGetMetalLayer という API で 0 ではない値が入っていれば無事に Metal で描画されている。

Metal でやりたいこと

昨日は macOS の OpenGL 廃止の方針に従って Metal が使用されるようにできるかを試したいという動機で作業しているように書いたが、実際はビジュアルクオリティを向上させるためのポストエフェクトなど、単なる画像を貼り付けるだけではない描画テクニックを使いたい理由があって Metal や Vulkan や Direct3D 12 などのローレベル描画 API を SDL で使えるかの確認をするためだった。

今日は Metal で描画されていることを確認しただけではなく、Metal を使って SDL の描画に介入する方法も探った。Metal は macOS と iOS など、Apple 製品のみで使えるものなので Windows, Linux, Android などの OS では使用できないが、まずは普段使用している Metal を勉強することにした。

今日わかったことは、SDL の Metal モードは全部で 1500 行程度で作られており非常にコンパクトであること、そして Metal の Command Encoder や Core Animation Layer へのアクセスができるため、Metal API を使用するために必要なものは SDL に手を加えなくても提供されているということ。
ただ、Metal を使って描画を色々試してみたのだが、ぼくの Metal 自体の理解不足のためだと思うがうまく描画できなかった。単に直線を描くだけの実装をしたかっただけなのだが。今日のところはこれで終わって、引き続き検証を行う。

目標としては SDL で描画したものにシェーダを使ってポストエフェクトを掛けられるようにしたい。ポストエフェクトは GIMP でこんな感じにしたいな〜と思っている画像を作ってみた。

被写界深度(ピントが合ってない部分がボヤけるやつ)、ブルーム(明るい部分が強調され漏れ出てるように見えるやつ)を入れてみた。これは SDL 単体ではできない効果なので、時間は掛かるかも知れないが頑張って達成したい。

応援してくださると嬉しいです。よろしくお願いいたします!