Android視野に入れるならSDL1.2よりSDL2のほうが良いらしい。みたいなことを何処かで見たので。
どうせやるなら新しい方で。
つっても1.2より情報少ないから、さらに苦労しそうだ。たぶん途中で投げ出すよ宣言。
取り敢えず画像表示までやる。
準備
用意するものは、前回同様
DMDを本家から。DMDは2.064.2だとVisual Dのスケルトンでエラーが出るので、一個古い2.063.2を使用。エラー出ても動くけどね。
SDL2.dllをSDL本家のDevelopment Librariesから。
画像表示のためにSDL_Image2.dllを本家?のDevelopment Librariesから。
バインダとしてDerelict3を使います。
こちらを参考ににてDerelict3をビルドします。
今回もVisual Dを使います。前回参照。
環境設定
1.前回同様、VisualStudioの新規プロジェクトで[Windows Application]で新規ソリューションを作成
2.プロジェクトのプロパティで[構成プロパティ]→[Compiler]のAdditional Importsに、Derelict3のimportフォルダのパスを設定
3.プロジェクトのプロパティの[Linker]のLibrary Search PathにDerelict3の中のlib\dmdフォルダのパスを設定。
4.[Linker]のLibrary Filesに、使用するlibを追加する。今回はDerelictSDL2.libとDerelictUtil.lib。
5.ソースのフォルダにSDL2.dll、SDL_Image2.dll、libpng16-16.dll、zlib1.dllを置く。
SDL_Image2.dll、libpng16-16.dll、zlib1.dllはSDL2_imageのlibフォルダに入ってる。
exe単体で実行する場合はexeと同じ場所に置く。
コードを書く
Derelict3に入ってるsample.dや、ググって出てくる色々を参考になんとか画像表示できた。
module winmain; import core.runtime; import core.sys.windows.windows; import derelict.sdl2.sdl; import derelict.sdl2.image; extern (Windows) int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { int result; void exceptionHandler(Throwable e) { throw e; } try { Runtime.initialize(&exceptionHandler); result = myWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow); Runtime.terminate(&exceptionHandler); } catch (Throwable o) // catch any uncaught exceptions { MessageBoxA(null, cast(char *)o.toString(), "Error", MB_OK | MB_ICONEXCLAMATION); result = 0; // failed } return result; } int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { /+ Derelict3でSDL2を初期化する。 +/ DerelictSDL2.load(); DerelictSDL2Image.load(); // SDL初期化 スコープアウト時に終了処理 SDL_Init(SDL_INIT_VIDEO); scope(exit) SDL_Quit(); // デスクトップ中央にウィンドウを作成 auto window = SDL_CreateWindow("Test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN); //スコープアウト時に破棄 scope(exit) SDL_DestroyWindow(window); // レンダラー取得 // レンダリングドライバ自動判別(-1) // ハードウェアアクセラレーション(SDL_RENDERER_ACCELERATED) auto renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); scope(exit) SDL_DestroyRenderer(renderer); //スコープアウト時に破棄 //適当な画像読み込み auto image = IMG_Load("img.png"); scope (exit) SDL_FreeSurface(image);//スコープアウト時に破棄 //画像からテクスチャ作成 auto sdlTexture = SDL_CreateTextureFromSurface(renderer, image); //60fpsは16.66..ミリ秒 immutable MILLS_PER_FRAME = 1000/60; // イベントが来るのを待つだけの単純なループ bool running = true; while (running) { // フレーム開始時刻 immutable startTicks = SDL_GetTicks(); //イベント処理 SDL_Event e; while (SDL_PollEvent(&e)) { if(processEvent(e)) { running = false; } } //画面クリア SDL_SetRenderDrawColor(renderer, Uint8.max, Uint8.max, Uint8.max, Uint8.max); SDL_RenderClear(renderer); //テクスチャをレンダラにコピー SDL_RenderCopy(renderer, sdlTexture, null, null); //画面に反映 SDL_RenderPresent(renderer); //次のフレームまで待つ immutable elapse = SDL_GetTicks() - startTicks; SDL_Delay(elapse < MILLS_PER_FRAME ? MILLS_PER_FRAME - elapse : 0); } return 0; } /** イベント処理 **/ bool processEvent(const ref SDL_Event e) { switch (e.type) { //終了 case SDL_QUIT: return true; //キーダウン case SDL_KEYDOWN: return true; //マウスクリック case SDL_MOUSEBUTTONDOWN: return true; //その他 default: return false; } }
画面いっぱいに拡大されて画像が表示される。
多分普通はSDL_RenderCopyじゃなくて別の方法使うんだろうなぁ。
DLLが多くてちょっとヤな感じだけど、SDL2からzlibライセンスになったので、DLLをlibに変換してDLL減らしたりできる・・・のかしらん。
さて、次はポリゴン板一枚ぺらっと表示したりしながらOpenGL覚えるかなぁ。