Windows で SDL2 を使って最低限の Window をレンダリングしてみるまで

SDL という単語自体初めて知ったのですが、小さいサンプルを作ってみたかったのでやってみました。

環境

VS でコンソールプロジェクトを作成

とりあえずサクッと実行できるプロジェクトを作成します。

デバッグ実行でちゃんと動くことが確認できればOK。

Nuget で SDL2 をインストール

Simple DirectMedia Layer - Homepage

上記の公式からダウンロードしてもいいのですが、パッケージマネージャー経由で入るならそれが楽なのでそちらで探してみました。

まず見つかったのは以下の sdl2 という名前のパッケージ。ダウンロード数もかなり多く、迷わずこれかと思ったのだが公式のバージョンよりだいぶ古い。

NuGet Gallery | sdl2 2.0.5

そこで、もう一つ見つけたのが以下の sdl2.nuget というパッケージです。

NuGet Gallery | sdl2.nuget 2.28.4

こちらは更新頻度も高く追随してくれていそうですので、こちらを使うことにしました。

以下のような package.config が作成されます。

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="sdl2.nuget" version="2.0.18" targetFramework="native" />
  <package id="sdl2.nuget.redist" version="2.0.18" targetFramework="native" />
</packages>

packages ディレクトリの内部は以下のようになっていました。ファイルはかなり抜粋しています。

packages/
  + sdl2.nuget.2.0.18/
    + build/
      + native/
        + include/
          + *.h # ヘッダファイル群
        + lib/
          + Win32/
            + dynamic/
             + SDL2.lib
             + SDL2main.lib

ビルドのための設定

SDL2/Installation - SDL Wiki

Unzip the archive, point your project at its "include" directory for headers, and link against SDL2.lib (and optionally, SDLmain.lib if you want SDL to provide a WinMain() that calls your standard Unix-like main() function). Distribute the SDL2.dll with your app's .exe file, and you're good to go!

上記をみると、include のヘッダファイルをプロジェクトから指すようにし、SDL2.lib (及び SDLmain.lib) をリンクしろとのことです。

ヘッダファイルのインクルード

プロジェクトプロパティの 「C/C++ -> 全般」の「追加のインクルードディレクトリ」に $(SolutionDir)packages\sdl2.nuget.2.0.18\build\native\include を指定します。

ソリューションエクスプローラーの外部依存関係に SDL 関連のファイルが追加されているのがわかります。

lib のリンク

プロジェクトプロパティの 「リンカー -> 全般」の「追加のライブラリディレクトリ」に $(SolutionDir)packages\sdl2.nuget.2.0.18\build\native\lib\Win32\dynamic を指定します。

一年後の 2023/10 頃になって、改めてこの手順を実行したときには、この設定では失敗しました。 $(SolutionDir)packages\sdl2.nuget.2.0.18\build\native\lib\x64 にすることで成功しました。

続いて、「リンカー -> 入力」の「追加の依存ファイル」に SDL2.libSDL2main.lib を追加します。

とりあえずビルドする

問題なくビルドできました。

最低限の Window をレンダリングするコードを書く

main の引数は以下のように定義しておく必要があるようです。

#include "SDL.h"

int main(int argc, char** argv)
{
    SDL_Init(SDL_INIT_VIDEO);
    
    SDL_Window* window = SDL_CreateWindow(
        "SDL2 TEST",
        100, // window のX座標
        100, // window のY座標
        1024, // window の幅
        768, // window の高さ
        0
    );
    
    if (!window) {
        SDL_Log("Failed to create window: %s", SDL_GetError());
        return 1;
    }

    // とりあえず表示の確認
    SDL_Delay(5000);
    
    SDL_DestroyWindow(window);

    SDL_Quit();
    return 0;
}

実行してみる

以下の Window が指定の時間表示されて消えました。成功です 🎊

SDL2.dll は?

bin/Debug には配置されていました。
SDL2.dllsdl2.nuget の依存でインストールされる sdl2.nuget.redist に入っており、ここから配置用の dll がコピーされているのだと思います。

まとめ

とりあえず最低限のサンプルが動作させることができました。ここからゲームループを作るような部分も理解を広げていければと思います。

参考にさせていただいた記事