Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fastest way to draw filled quad/triangle with the SDL2 renderer?

Tags:

c++

sdl

sdl-2

I have a game written using SDL2, and the SDL2 renderer (hardware accelerated) for drawing. Is there a trick to draw filled quads or triangles?

At the moment I'm filling them by just drawing lots of lines (SDL_Drawlines), but the performance stinks.

I don't want to go into OpenGL.

like image 473
Tom Davies Avatar asked Oct 05 '21 09:10

Tom Davies


1 Answers

SDL_RenderGeometry()/SDL_RenderGeometryRaw() were added in SDL 2.0.18:

  • Added SDL_RenderGeometry() and SDL_RenderGeometryRaw() to allow rendering of arbitrary shapes using the SDL 2D render API

Example:

screenshot

// g++ main.cpp `pkg-config --cflags --libs sdl2`
#include <SDL.h>
#include <vector>

int main( int argc, char** argv )
{
    SDL_Init( SDL_INIT_EVERYTHING );
    SDL_Window* window = SDL_CreateWindow("SDL", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_SHOWN );
    SDL_Renderer* renderer = SDL_CreateRenderer( window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC );

    const std::vector< SDL_Vertex > verts =
    {
        { SDL_FPoint{ 400, 150 }, SDL_Color{ 255, 0, 0, 255 }, SDL_FPoint{ 0 }, },
        { SDL_FPoint{ 200, 450 }, SDL_Color{ 0, 0, 255, 255 }, SDL_FPoint{ 0 }, },
        { SDL_FPoint{ 600, 450 }, SDL_Color{ 0, 255, 0, 255 }, SDL_FPoint{ 0 }, },
    };

    bool running = true;
    while( running )
    {
        SDL_Event ev;
        while( SDL_PollEvent( &ev ) )
        {
            if( ( SDL_QUIT == ev.type ) ||
                ( SDL_KEYDOWN == ev.type && SDL_SCANCODE_ESCAPE == ev.key.keysym.scancode ) )
            {
                running = false;
                break;
            }
        }

        SDL_SetRenderDrawColor( renderer, 0, 0, 0, SDL_ALPHA_OPAQUE );
        SDL_RenderClear( renderer );
        SDL_RenderGeometry( renderer, nullptr, verts.data(), verts.size(), nullptr, 0 );
        SDL_RenderPresent( renderer );
    }

    SDL_DestroyRenderer( renderer );
    SDL_DestroyWindow( window );
    SDL_Quit();

    return 0;
}

Note that due to the API lacking a data channel for Z coordinates only affine texturing is achievable.

like image 61
genpfault Avatar answered Sep 19 '22 13:09

genpfault