Skip to content

OpenGL MSAA Not Working with SDL_Renderer #13072

Open
@ShaharNacht

Description

@ShaharNacht

I haven't seen a way to enable MSAA through the SDL_Renderer API, so I thought I could tell the renderer to use OpenGL and do it through the SDL_GL API, but it doesn't seem to be working.

I created a sample program to test it:

#include <stddef.h>

#define SDL_MAIN_USE_CALLBACKS
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
#include <SDL3/SDL_opengl.h>

static SDL_Window *window = NULL;
static SDL_Renderer *renderer = NULL;
static SDL_GLContext gl_context = NULL;

static SDL_AppResult panic(const char *func_name) {
    SDL_LogError(SDL_LOG_CATEGORY_ERROR, "%s failed: %s", func_name, SDL_GetError());

    return SDL_APP_FAILURE;
}

SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) {
    if (!SDL_Init(SDL_INIT_VIDEO)) {
        return panic("SDL_Init");
    }

    if (!SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3)) {
        return panic("SDL_GL_SetAttribute");
    }
    if (!SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3)) {
        return panic("SDL_GL_SetAttribute");
    }
    if (!SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1)) {
        return panic("SDL_GL_SetAttribute");
    }
    if (!SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4)) {
        return panic("SDL_GL_SetAttribute");
    }

    if (!SDL_CreateWindowAndRenderer("MSAA Test", 200, 200, SDL_WINDOW_OPENGL, &window, &renderer)) {
        return panic("SDL_CreateWindowAndRenderer");
    }

    gl_context = SDL_GL_CreateContext(window);
    if (gl_context == NULL) {
        return panic("SDL_GL_CreateContext");
    }

    if (!SDL_GL_MakeCurrent(window, gl_context)) {
        return panic("SDL_GL_MakeCurrent");
    }

    int opengl_major, opengl_minor, buffers, samples;
    if (!SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &opengl_major)) {
        return panic("SDL_GL_GetAttribute");
    }
    if (!SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &opengl_minor)) {
        return panic("SDL_GL_GetAttribute");
    }
    if (!SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &buffers)) {
        return panic("SDL_GL_GetAttribute");
    }
    if (!SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &samples)) {
        return panic("SDL_GL_GetAttribute");
    }

    SDL_Log("OpenGL %d.%d", opengl_major, opengl_minor);
    SDL_Log("Buffers: %d, samples: %d", buffers, samples);

    bool multisample_supported = SDL_GL_ExtensionSupported("GL_ARB_multisample");
    SDL_Log("GL_ARB_multisample supported: %d", multisample_supported);
    
    void (APIENTRY *glEnable_ptr)(GLenum) = (void (APIENTRY *)(GLenum)) SDL_GL_GetProcAddress("glEnable");
    if (glEnable_ptr == NULL) {
        return panic("SDL_GL_GetProcAddress");
    }

    // GL_MULTISAMPLE, GL_MULTISAMPLE_ARB and GL_MULTISAMPLE_EXT are all 0x809D,
    // so it shouldn't matter which I use
    glEnable_ptr(GL_MULTISAMPLE_ARB);

    return SDL_APP_CONTINUE;
}

SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) {
    if (event->type == SDL_EVENT_QUIT) {
        return SDL_APP_SUCCESS;
    }

    return SDL_APP_CONTINUE;
}

SDL_AppResult SDL_AppIterate(void *appstate) {
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    SDL_RenderClear(renderer);

    const SDL_FColor color = { 1.0f, 0.0f, 0.0f, 1.0f };

    const SDL_Vertex vertices[] = {
        {
            .position = { 100.0f, 50.0f },
            .color = color,
            .tex_coord = { 0.0f, 0.0f }
        },
        {
            .position = { 150.0f, 100.0f },
            .color = color,
            .tex_coord = { 0.0f, 0.0f }
        },
        {
            .position = { 100.0f, 150.0f },
            .color = color,
            .tex_coord = { 0.0f, 0.0f }
        },
        {
            .position = { 50.0f, 100.0f },
            .color = color,
            .tex_coord = { 0.0f, 0.0f }
        }
    };

    const int indices[] = {
        0, 1, 3,
        1, 2, 3
    };

    SDL_RenderGeometry(
        renderer,
        NULL,
        vertices,
        sizeof(vertices) / sizeof(vertices[0]),
        indices,
        sizeof(indices) / sizeof(indices[0])
    );

    SDL_RenderPresent(renderer);
    
    return SDL_APP_CONTINUE;
}

void SDL_AppQuit(void *appstate, SDL_AppResult result) {
    if (!SDL_GL_DestroyContext(gl_context)) {
        panic("SDL_GL_DestroyContext");
    }
    gl_context = NULL;

    SDL_DestroyRenderer(renderer);
    renderer = NULL;

    SDL_DestroyWindow(window);
    window = NULL;

    SDL_Quit();
}

(Tested on Windows 11, GCC mingw-ucrt64, SDL 3.2.14)

This is what the sample program prints on my machine:

OpenGL 3.3
Buffers: 1, samples: 4
GL_ARB_multisample supported: 1

But the image that gets rendered to the window is this: (Notice no anti-aliasing)
Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions