SDL_RenderGeometry - jagged edges?

I’m on macOS Monterery (don’t know if that’s relevant) and just downloaded 2.0.18. I thought I’d try out the new ability to render triangles with SDL_RenderGeometry, so I called it in the following way:

SDL_Vertex vs[4] = {
    {{40+40*cosf(M_PI/6),          40+40*sinf(M_PI/6)         }, {0, 0, 255, 255}},
    {{40+40*cosf(M_PI/6+M_PI/2),   40+40*sinf(M_PI/6+M_PI/2)  }, {0, 0, 255, 255}},
    {{40+40*cosf(M_PI/6+M_PI),     40+40*sinf(M_PI/6+M_PI)    }, {0, 0, 255, 255}},
    {{40+40*cosf(M_PI/6+3*M_PI/2), 40+40*sinf(M_PI/6+3*M_PI/2)}, {0, 0, 255, 255}},
};
int indices[6] = {0, 1, 2, 2, 3, 0};
SDL_RenderGeometry(renderer, NULL, vs, 4, indices, 6);

This results in the following image:

image

The edges of the square are jagged. Is that expected? It is very noticeable with small triangles. Is it possible to get smooth edges or am I using the API wrong?

Do you have high-dpi support enabled for your window?

I had forgotten to set that flag.

I get an image like this now:

image

Full source in case I’m missing something:

#include <SDL2/SDL.h>
#include <math.h>

int
main(){
    SDL_Window* window;
    SDL_Renderer* renderer;
    if (SDL_Init(SDL_INIT_VIDEO) < 0)
            return 1;

    window = SDL_CreateWindow("Test",
                    SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
                    100, 100,
                    SDL_WINDOW_ALLOW_HIGHDPI);

    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC);

    float spin = 0;
    int paused = 1;
    for(;;){
        SDL_Event event;
        while (SDL_PollEvent(&event)) {
            if(event.type == SDL_QUIT)
                return 0;
            if(event.type == SDL_KEYDOWN){
                switch(event.key.keysym.sym){
                    case 'q': return 0;
                    case 'p': paused = !paused; break;
                }
            }
        }
        SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
        SDL_RenderClear(renderer);

        SDL_Vertex vs[4] = {
            {{40+40*cosf(M_PI*(spin+1./6)),        40+40*sinf(M_PI*(spin+1./6))       }, {0, 0, 255, 255}},
            {{40+40*cosf(M_PI*(spin+1./6+1./2)),   40+40*sinf(M_PI*(spin+1./6+1./2))  }, {0, 0, 255, 255}},
            {{40+40*cosf(M_PI*(spin+1./6+1.)),     40+40*sinf(M_PI*(spin+1./6+1.))    }, {0, 0, 255, 255}},
            {{40+40*cosf(M_PI*(spin+1./6+3*1./2)), 40+40*sinf(M_PI*(spin+1./6+3*1./2))}, {0, 0, 255, 255}},
        };
        int indices[6] = {0, 1, 2, 2, 3, 0};
        SDL_RenderGeometry(renderer, 0, vs, 4, indices, 6);

        SDL_RenderPresent(renderer);
        if(!paused)
            spin += 0.003;
    }
    return 0;
}

I don’t think SDL_Render supports MSAA or other forms of antialiasing, so for pure geometry you’ll get aliased edges like that because the GPU will treat a pixel as fully covered or fully uncovered by geometry depending on if the geometry intersects the pixel’s center, there’s no in between.

One handy trick is to have a texture that’s fully transparent around its edges, and opaque elsewhere. It’s effectively free antialiasing if the texture is rendered at its native scale using bilinear filtering, even when it’s rotated.

Add this:

SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2");

I may be totally wrong, but I was under the impression that SDL_HINT_RENDER_SCALE_QUALITY only affects texture sampling (Nearest Neighbor vs Bilinear).

I think maybe the jagged edges are because the geometry is being drawn without subpixel precision? Each pixel of the target is either fully covered by the triangle or completely outside of it.

Yes, there’s no anti-aliasing

SDL_RenderGeometry() is giving me anti-aliasing, no problem.

geometry

This was rendered on Windows 10, direct3d, NVIDIA GeForce video card with the following settings:

SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2");

Lines were drawn with the following option:

SDL_SetHint(SDL_HINT_RENDER_LINE_METHOD, "3");

I guess it must be hardware/driver dependent then. Like the OP, my RenderGeometry and Line drawing is jagged, with no antialiasing, regardless of settings.