I use SDL_SetHint(SDL_HINT_MAIN_CALLBACK_RATE, "60") as Daniel1985 has written in the third post. I think it should be used for Desktop and Android build because the browsers use requestAnimationFrame (that makes a very smooth animations). So, it should be in the #ifndef __EMSCRIPTEN__ condition when I use one code base for three platforms:
#ifndef __EMSCRIPTEN__
if (!SDL_SetHint(SDL_HINT_MAIN_CALLBACK_RATE, "60"))
{
SDL_Log("Failed to set a frame rate: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
#endif
Full code: callback-rate-sdl3-opengl-c.zip (2.6 KB)
main.c
#define SDL_MAIN_USE_CALLBACKS 1
#include <glad/glad.h>
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
typedef struct {
SDL_Window *window;
SDL_GLContext glContext;
Uint64 frameCount;
Uint64 lastLogTime;
} App;
SDL_AppResult SDL_AppInit(void **appState, int argc, char *argv[]) {
App *app = (App *)SDL_malloc(sizeof(App));
*appState = app;
SDL_SetHint(SDL_HINT_MAIN_CALLBACK_RATE, "60");
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl");
SDL_Init(SDL_INIT_VIDEO);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
SDL_GL_CONTEXT_PROFILE_CORE);
app->window = SDL_CreateWindow("Callback Rate 60, SDL3, OpenGL",
380, 380, SDL_WINDOW_OPENGL);
app->glContext = SDL_GL_CreateContext(app->window);
gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress);
glClearColor(0.2f, 0.2f, 0.2f, 1.f);
const GLubyte *vendor = glGetString(GL_VENDOR);
const GLubyte *glRenderer = glGetString(GL_RENDERER);
const GLubyte *version = glGetString(GL_VERSION);
SDL_Log("Vendor: %s", vendor);
SDL_Log("Renderer: %s", glRenderer);
SDL_Log("OpenGL Version: %s", version);
return SDL_APP_CONTINUE;
}
SDL_AppResult SDL_AppEvent(void *appState, SDL_Event *event) {
App *app = (App *)appState;
switch (event->type) {
case SDL_EVENT_QUIT:
return SDL_APP_SUCCESS;
default:
break;
}
return SDL_APP_CONTINUE;
}
SDL_AppResult SDL_AppIterate(void *appState) {
App *app = (App *)appState;
app->frameCount++;
Uint64 now = SDL_GetTicks();
if (now - app->lastLogTime >= 1000) {
SDL_Log("Frames per second: %llu", app->frameCount);
app->frameCount = 0;
app->lastLogTime = now;
}
glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapWindow(app->window);
return SDL_APP_CONTINUE;
}
void SDL_AppQuit(void *appState, SDL_AppResult result) {
App *app = (App *)appState;
SDL_GL_DestroyContext(app->glContext);
SDL_DestroyWindow(app->window);
SDL_Quit();
}
CMakeLists.txt
set(CMAKE_BUILD_TYPE "Debug")
cmake_minimum_required(VERSION 3.21)
project(callback-rate-sdl3-opengl-c)
set(CMAKE_C_STANDARD 17)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(SDL3_DIR "C:/libs/SDL3-devel-3.4.12-mingw/lib/cmake/SDL3")
find_package(SDL3 REQUIRED)
add_executable(app)
target_include_directories(app PRIVATE C:/libs/glad-0.1.36/opengl-3.3/include)
target_sources(app
PRIVATE
C:/libs/glad-0.1.36/opengl-3.3/src/glad.c
src/main.c
)
target_link_libraries(app PRIVATE SDL3::SDL3)
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
target_link_options(app PRIVATE -mconsole)
else()
target_link_options(app PRIVATE -mwindows)
endif()
