14

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.

genpfault
  • 51,148
  • 11
  • 85
  • 139
Tom Davies
  • 2,386
  • 3
  • 27
  • 44
  • Not sure whether you will find a reasonable alternative to OpenGL (excluding the proprietary / OS specific siblings Direct3d and Metal). I once painted an HUD in Qt / QPainter (annotations to my rendered 3d contents) hoping on the fact that Qt seems to use OpenGL for this under the hood as well. After having received complaints about poor performance, I ported the code to "hand-written" OpenGL, and mission succeeded. Of course, there might be other APIs which do a better job... – Scheff's Cat Oct 05 '21 at 10:24

3 Answers3

16

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.

genpfault
  • 51,148
  • 11
  • 85
  • 139
  • 1
    Should make SDL_Renderer-based backends for immediate-mode GUIs like [nuklear](https://github.com/Immediate-Mode-UI/Nuklear) viable too. – genpfault Oct 05 '21 at 17:07
  • 1
    Thanks for making me aware of nuklear. I'm using dear-imgui (with a intermediate lib to render imgui with the SDL2 renderer - a bit slow) in my game, but that looks very nice as well. – Tom Davies Oct 05 '21 at 17:13
  • [RE: SDL_Renderer backend...](https://github.com/Immediate-Mode-UI/Nuklear/pull/280) – genpfault Oct 06 '21 at 03:28
  • 1
    Just as a follow up, I just built the latest SDL source, and have drawn a filled triangle for the first time. Heady days indeed, thanks. I'd not have noticed this as I only check the official releases. – Tom Davies Oct 06 '21 at 09:48
0

Not possible. SDL2 does not include a full-fledged rendering engine.

Some options:

  • You could adopt Skia (the graphics library used in Chrome, among ohters) and then either stick with a software renderer, or instantiate an OpenGL context and use the hardware backend.

  • You could use another 2D drawing library such as Raylib

  • Or just bite the bullet and draw your triangles using OpenGL.

Botje
  • 26,269
  • 3
  • 31
  • 41
0

Here is my basic example:

#include <stdio.h>
#include <stdlib.h>
#include <SDL.h>

int width=1280,height=720;
SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
SDL_Event e;

SDL_Vertex triangleVertex[3]=
{
 {
  { 0,0}, /* first point location */ 
  { 255, 0, 0, 0xFF }, /* first color */ 
  { 0.f, 0.f }
 },
 {
  { 0, 720 }, /* second point location */ 
  { 0,255,0, 0xFF }, /* second color */
  { 0.f, 0.f }
 },
 {
  { 640, 360 }, /* third point location */ 
  { 0,0,255, 0xFF }, /* third color */
  { 0.f, 0.f }
 }
};


int main(int argc, char** argv)
{
 if(SDL_Init(SDL_INIT_VIDEO)){printf( "SDL could not initialize! SDL_Error: %s\n",SDL_GetError());return -1;}

 window = SDL_CreateWindow( "SDL Chaste Triangle",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,width,height,0);
 if(window==NULL){printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );return -1;}

 renderer = SDL_CreateRenderer(window,-1,0);
 if(renderer==NULL){printf( "Renderer could not be created! SDL_Error: %s\n", SDL_GetError() );return -1;}
    
 SDL_SetRenderDrawColor(renderer,0,0,0,255);
 SDL_RenderClear(renderer);
 if( SDL_RenderGeometry(renderer, NULL, triangleVertex, 3, NULL, 0) < 0 ) {SDL_Log("%s\n", SDL_GetError());}

 SDL_RenderPresent(renderer);
    
 while(e.type != SDL_KEYUP && e.type != SDL_QUIT) /*wait until any key is pressed and then released*/
 {
  SDL_PollEvent( &e );
 }
    
 SDL_DestroyRenderer(renderer);
 SDL_DestroyWindow(window);
 SDL_Quit();
 return 0;
}

/*
 This file is the Chastity's modification of an example from here:

 https://daywithstars.github.io/sdl2/geometry/2021/12/03/SDL2-new-geometry-rendering-SDL_RenderGeometry.html

 Unlike the original, this one is compatible with the C89 standard which Chastity always uses.

 Compile and run on Linux with this command:
 gcc -Wall -ansi -pedantic main.c -o main `sdl2-config --cflags --libs` -lm && ./main
*/

I have this one and some more examples at my github project.

https://github.com/chastitywhiterose/SDL_Chaste_Triangle

It is possible to draw any shape with enough triangles and so I made the project to help me in future games I make.

  • 1
    Awesome, I figured out how to share the code in the answer. I had to select the text and use CTRL+K. I'm new to stack overflow and I joined just because of the SDL Triangle question. I don't blame the OP for not wanting to mess with OpenGL! – Chandler Isaac Klebs Mar 07 '23 at 16:21