SDL導入

画像処理コードの確認の際、C++で簡単にウィンドウを表示したいと思い、SDLを少し使ってみました。

SDLダウンロード

下記ページよりdllをダウンロードします。
Simple DirectMedia Layer - SDL version 2.0.7 (stable)
f:id:any-programming:20171202132413p:plain

shared_ptrに変換する関数定義(任意)

SDLはCのライブラリのため、ポインタの開放は手動でやる必要があります。(例:SDL_CreateWindow → SDL_DestroyWindow)

ポインタの管理を楽にするため、shared_ptrに変換する関数を準備します。

shared_ptr作成時に対応するデストラクタを渡すようにしています。

#define DEEFINE_TO_SHARED_PTR(type, destructor) std::shared_ptr<type> ToSharedPtr(type* p) { return std::shared_ptr<type>(p, destructor); }
DEEFINE_TO_SHARED_PTR(SDL_Window,   SDL_DestroyWindow)
DEEFINE_TO_SHARED_PTR(SDL_Renderer, SDL_DestroyRenderer)
DEEFINE_TO_SHARED_PTR(SDL_Surface,  SDL_FreeSurface)
DEEFINE_TO_SHARED_PTR(SDL_Texture,  SDL_DestroyTexture)


簡単な実装

画像を読み込んで表示するアプリケーションを実装してみます。

ついでにマウスの位置に正方形も描画してみます。

f:id:any-programming:20171202173056p:plain

#include <SDL.h>
#pragma comment(lib, "SDL2.lib")
#pragma comment(lib, "SDL2main.lib")

int main(int, char**)
{
    SDL_assert(SDL_Init(SDL_INIT_VIDEO) == 0);

    std::shared_ptr<SDL_Window> window = ToSharedPtr(SDL_CreateWindow(
        "SDL Sample", 
        SDL_WINDOWPOS_UNDEFINED, 
        SDL_WINDOWPOS_UNDEFINED, 
        640, 
        480, 
        0
    ));
    SDL_assert(window);
    
    std::shared_ptr<SDL_Renderer> renderer = ToSharedPtr(SDL_CreateRenderer(window.get(), -1, 0));
    SDL_assert(renderer);

    std::shared_ptr<SDL_Surface> surface = ToSharedPtr(SDL_LoadBMP("Parrots.bmp"));
    SDL_assert(surface);

    std::shared_ptr<SDL_Texture> texture = ToSharedPtr(SDL_CreateTextureFromSurface(renderer.get(), surface.get()));
    SDL_assert(texture);
    
    while (1)
    {
        SDL_Event event;
        if (SDL_PollEvent(&event) == 0)
            continue;

        if (event.type == SDL_QUIT)
            break;
        else if (event.type == SDL_MOUSEMOTION)
        {
            SDL_assert(SDL_RenderClear(renderer.get()) == 0);

            // 画像描画
            SDL_assert(SDL_RenderCopy(renderer.get(), texture.get(), nullptr, nullptr) == 0);
            
            // マウスの位置に正方形描画
            SDL_Rect rect = { event.motion.x, event.motion.y, 50, 50 };
            SDL_assert(SDL_SetRenderDrawColor(renderer.get(), 255, 255, 255, 255) == 0);
            SDL_assert(SDL_RenderFillRect(renderer.get(), &rect) == 0);

            SDL_RenderPresent(renderer.get());
        }
    }

    SDL_Quit();

    return 0;
}