Skip to content

[SDL3] [WASM] Rendering without using requestAnimationFrame even with emscripten_set_main_loop properly called #12805

Open
@martindeveloper

Description

@martindeveloper

Hello,

Feels like I'm doing some obvious mistake, but when I compile my basic app with static version of SDL 3.2.10 with Emscripten into WASM, I get the Looks like you are rendering without using requestAnimationFrame for the main loop. You should use 0 for the frame rate in emscripten_set_main_loop in order to use requestAnimationFrame, as that can greatly improve your frame rates! warning (Safari, Edge).

But in the code I use the emscripten_set_main_loop as mentioned in the warning. Here is the main.cpp.

#include "Platform/Platform.h"
#include "Platform/Std.h"
#include <SDL3/SDL.h>

#define UNUSED(x) (void)(x)

struct AppState {
    SDL_Window* window;
    SDL_Renderer* renderer;
    bool shouldQuit;

    AppState() : window(nullptr), renderer(nullptr), shouldQuit(false) {}
};

static AppState* appState = nullptr;

static void on_update() {
    SDL_Event event;
    while (SDL_PollEvent(&event)) {
        if (event.type == SDL_EVENT_QUIT) {
            appState->shouldQuit = true;
        }
        else if (event.type == SDL_EVENT_KEY_DOWN && event.key.key == SDLK_ESCAPE) {
            appState->shouldQuit = true;
        }
    }

    SDL_SetRenderDrawColor(appState->renderer, 124, 0, 0, 255);
    SDL_RenderClear(appState->renderer);

    SDL_RenderPresent(appState->renderer);
}

int main(int argc, char* argv[]) {
    UNUSED(argc);
    UNUSED(argv);

    if (!SDL_Init(SDL_INIT_VIDEO)) {
        std::cerr << "Failed to initialize SDL: " << SDL_GetError() << std::endl;
        return 1;
    }

    appState = new AppState();

    SDL_CreateWindowAndRenderer("Game", 800, 600, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE, &appState->window, &appState->renderer);

    if (!appState->window) {
        std::cerr << "Failed to create window: " << SDL_GetError() << std::endl;
        SDL_Quit();
        return 1;
    }

    if (!appState->renderer) {
        std::cerr << "Failed to create renderer: " << SDL_GetError() << std::endl;
        SDL_DestroyWindow(appState->window);
        SDL_Quit();
        return 1;
    }

    const char* rendererName = SDL_GetRendererName(appState->renderer);
    std::cout << "Renderer: " << rendererName << std::endl;

    #ifdef PLATFORM_WASM
    emscripten_set_main_loop(on_update, 0, true);
    #else
    while (!appState->shouldQuit) {
        on_update();
    }
    #endif

    SDL_DestroyRenderer(appState->renderer);
    SDL_DestroyWindow(appState->window);
    SDL_Quit();

    delete appState;
    return 0;
}

I'm on macOS with Apple Silicon using emcc in 4.0.6-git version, with some basic flags.

set(EMSCRIPTEN_FLAGS
        "-s USE_SDL=0" # Linking with manually built libSDL3.a - no code changes
        "-s ALLOW_MEMORY_GROWTH=1"
        "-s MAX_WEBGL_VERSION=2"
        "-s FETCH=1"
        "-s USE_PTHREADS=0"
        "-s ASSERTIONS=1"
        "-s WASM=1"
        "-s ASYNCIFY"
        "-s EXPORTED_RUNTIME_METHODS=['ccall','cwrap']"
        "--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/bin/wasm-wasm32/assets@assets"
        "--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/bin/wasm-wasm32/shaders@shaders"
    )

Am I missing something please?

Thank you,
Martin

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions