ユーニックス総合研究所

  • home
  • archives
  • sdl2-show-image

SDL2で画像をウィンドウに表示する【C++】

  • 作成日: 2023-03-12
  • 更新日: 2023-12-24
  • カテゴリ: SDL2

SDL2で画像をウィンドウに表示する

SDL2でPNG画像を読み込んでそれをウィンドウに表示する方法。
ソースコードは以下。

#define SDL_MAIN_HANDLED  
#include <SDL2/SDL.h>  
#include <SDL2/SDL_image.h>  
#include <cstdio>  

int main(void) {  
    bool quit = false;  
    SDL_Event event;  

    SDL_Init(SDL_INIT_VIDEO);  
    SDL_Window *window = SDL_CreateWindow(  
        "my window",  
        SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,  
        640, 480, 0  
    );  

    SDL_Rect rect = {0};  
    SDL_Surface *image = IMG_Load("d:\\res\\img\\kao.png");  
    if (!image) {  
        printf("%s\n", IMG_GetError());  
    }  
    rect.x = 0;  
    rect.y = 0;  
    rect.w = image->w;  
    rect.h = image->h;  

    SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);  
    SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, image);  
    SDL_RenderCopy(renderer, texture, NULL, &rect);  
    SDL_RenderPresent(renderer);  

    while (!quit) {  
        SDL_WaitEvent(&event);  
        switch (event.type) {  
        case SDL_QUIT:  
            quit = true;  
            break;  
        }  
    }  

    SDL_DestroyTexture(texture);  
    SDL_FreeSurface(image);  
    SDL_DestroyRenderer(renderer);  
    SDL_DestroyWindow(window);  
    SDL_Quit();  

    return 0;  
}  

コンパイルに使ったMakefileは↓の通り。

CC := g++  
CC_FLAGS := -Wall -O0 -g -L .  
PROG := cgame.exe  

all: $(PROG)  

.PHONY: clean  
clean:  
    rm $(PROG)  

$(PROG): main.cpp  
    $(CC) $(CC_FLAGS) -o $@ $< -lSDL2 -lSDL2_image  

rectに画像の座標とサイズを設定して

    SDL_RenderCopy(renderer, texture, NULL, &rect);  

に渡している。
このrectはコピー先の矩形領域になる。
このような指定をすると画像が原寸大で表示される。

  1. Window作成
  2. image作成(IMG_Load)
  3. WindowからRenderer作成
  4. RendererとimageからTexture作成
  5. Rendererにtextureをコピー
  6. SDL_RenderPresent() で描画結果を画面に反映

という感じで進む。

IMG_Load()は読み込みに失敗するとNULLを返すのでこれをチェックしてIMG_GetError()でエラー内容を取得する。

Windowは640x480のサイズのウィンドウを作成している。
SDL_WINDOWPOS_UNDEFINEDで座標を指定すると座標が未定義になる。