レンダーターゲットの設定

2021年9月3日

SDLでレンダーターゲットを設定するには、「SDL_SetRenderTarget関数」を使用します。

SDL_SetRenderTarget関数

レンダーターゲットを設定します。

宣言

int SDL_SetRenderTarget( SDL_Renderer* renderer, SDL_Texture* texture );

引数

rendererレンダラのアドレスです。
textureレンダーターゲットにするテクスチャのアドレスです。このテクスチャはアクセス方式にSDL_TEXTUREACCESS_TARGETを設定している必要があります。
また、この引数にNULLを指定すると、デフォルトのレンダーターゲット( レンダラに関連付けたウィンドウ )を設定します。

戻り値

設定に成功すると「0」を返し、失敗すると「エラーコード( 負の数 )」を返します。

サンプルプログラム

#include <SDL.h>

const auto WINDOW_WIDTH     = 1280;
const auto WINDOW_HEIGHT    = 720;

SDL_Window*     g_window    = nullptr;
SDL_Renderer*   g_renderer  = nullptr;
SDL_Texture*    g_texture   = nullptr;

bool Initialize();
bool Update();
void Draw();
void Finalize();
SDL_Texture* CreateCheckeredPatternTexture();
void DrawCheckeredPattern();

int main( int argc, char* argv[] )
{
    if ( !Initialize() ) 
    {
        Finalize();
        return -1;
    }

    while ( true )
    {
        if ( !Update() ) break;
        Draw();
    }

    Finalize();

    return 0;
}

bool Initialize() 
{
    if ( SDL_Init( SDL_INIT_VIDEO ) != 0 )
    {
        SDL_Log( u8"SDLの初期化処理に失敗しました。エラーメッセージ: %s", SDL_GetError() );
        return false;
    }

    g_window = SDL_CreateWindow(
        u8"サンプル",
        SDL_WINDOWPOS_CENTERED,
        SDL_WINDOWPOS_CENTERED,
        WINDOW_WIDTH,
        WINDOW_HEIGHT,
        0
    );

    if ( g_window == nullptr )
    {
        SDL_Log( u8"ウィンドウの作成に失敗しました。エラーメッセージ: %s", SDL_GetError() );
        return false;
    }

    g_renderer = SDL_CreateRenderer(
        g_window,
        -1,
        SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC
    );

    if ( g_renderer == nullptr )
    {
        SDL_Log( u8"レンダラの作成に失敗しました。エラーメッセージ: %s", SDL_GetError() );
        return false;
    }

    g_texture = CreateCheckeredPatternTexture();
    
    if ( g_texture == nullptr ) 
    {
        SDL_Log( u8"テクスチャの作成に失敗しました。エラーメッセージ: %s", SDL_GetError() );
        return false;
    }

    return true;
}

bool Update() 
{
    auto event_info = SDL_Event();

    while ( SDL_PollEvent( &event_info ) == 1 )
    {
        if ( event_info.type == SDL_QUIT ) return false;
    }

    return true;
}

void Draw() 
{
    SDL_SetRenderDrawColor( g_renderer, 0, 0, 255, 255 );
    SDL_RenderClear( g_renderer );

    SDL_RenderCopy( g_renderer, g_texture, nullptr, nullptr );

    SDL_RenderPresent( g_renderer );
}

void Finalize() 
{
    if ( g_texture  != nullptr )    SDL_DestroyTexture( g_texture );
    if ( g_renderer != nullptr )    SDL_DestroyRenderer( g_renderer );
    if ( g_window   != nullptr )    SDL_DestroyWindow( g_window );
    SDL_Quit();
}

SDL_Texture* CreateCheckeredPatternTexture() 
{
    auto texture = SDL_CreateTexture(
        g_renderer,
        SDL_PIXELFORMAT_RGBA32,
        SDL_TEXTUREACCESS_TARGET,
        WINDOW_WIDTH,
        WINDOW_HEIGHT
    );

    if ( texture == nullptr ) return nullptr;

    SDL_SetRenderTarget( g_renderer, texture );
    DrawCheckeredPattern();
    SDL_SetRenderTarget( g_renderer, nullptr );

    return texture;
}

void DrawCheckeredPattern() 
{
    auto rectangle          = SDL_Rect();
    rectangle.w             = 80;
    rectangle.h             = 80;

    auto horizontal_count   = WINDOW_WIDTH / rectangle.w / 2;
    auto vertical_count     = WINDOW_HEIGHT / rectangle.h;

    SDL_SetRenderDrawColor( g_renderer, 255, 255, 255, 255 );
    SDL_RenderClear( g_renderer );

    SDL_SetRenderDrawColor( g_renderer, 0, 100, 200, 255 );

    for ( auto i = 0; i < vertical_count; i++ )
    {
        rectangle.y     = rectangle.h * i;
        auto is_even    = i % 2 == 0;
        auto offset_x   = is_even ? 0 : rectangle.w;

        for ( auto j = 0; j < horizontal_count; j++ )
        {
            rectangle.x = rectangle.w * j * 2 + offset_x;
            SDL_RenderFillRect( g_renderer, &rectangle );
        }
    }
}

参考ページ