mirror of
https://github.com/aap/librw.git
synced 2026-01-23 19:42:56 +00:00
Add SDL3 backend
This commit is contained in:
@@ -153,6 +153,7 @@ if(LIBRW_PLATFORM_GL3)
|
||||
if (NOT TARGET glfw)
|
||||
find_package(glfw3 REQUIRED)
|
||||
endif()
|
||||
target_compile_definitions(librw PUBLIC LIBRW_GLFW)
|
||||
target_link_libraries(librw
|
||||
PUBLIC
|
||||
glfw
|
||||
@@ -169,6 +170,13 @@ if(LIBRW_PLATFORM_GL3)
|
||||
PUBLIC
|
||||
SDL2::SDL2
|
||||
)
|
||||
elseif (LIBRW_GL3_GFXLIB STREQUAL "SDL3")
|
||||
find_package(SDL3 CONFIG REQUIRED)
|
||||
target_compile_definitions(librw PUBLIC LIBRW_SDL3)
|
||||
target_link_libraries(librw
|
||||
PUBLIC
|
||||
SDL3::SDL3
|
||||
)
|
||||
endif()
|
||||
|
||||
set(OpenGL_GL_PREFERENCE GLVND)
|
||||
|
||||
@@ -1246,8 +1246,12 @@ getFramebufferRect(Raster *frameBuffer)
|
||||
if(fb->type == Raster::CAMERA){
|
||||
#ifdef LIBRW_SDL2
|
||||
SDL_GetWindowSize(glGlobals.window, &r.w, &r.h);
|
||||
#else
|
||||
#elif defined(LIBRW_SDL3)
|
||||
SDL_GetWindowSize(glGlobals.window, &r.w, &r.h);
|
||||
#elif defined(LIBRW_GLFW)
|
||||
glfwGetFramebufferSize(glGlobals.window, &r.w, &r.h);
|
||||
#else
|
||||
missing implementation
|
||||
#endif
|
||||
}else{
|
||||
r.w = fb->width;
|
||||
@@ -1412,12 +1416,20 @@ showRaster(Raster *raster, uint32 flags)
|
||||
else
|
||||
SDL_GL_SetSwapInterval(0);
|
||||
SDL_GL_SwapWindow(glGlobals.window);
|
||||
#else
|
||||
#elif defined(LIBRW_SDL3)
|
||||
if(flags & Raster::FLIPWAITVSYNCH)
|
||||
SDL_GL_SetSwapInterval(1);
|
||||
else
|
||||
SDL_GL_SetSwapInterval(0);
|
||||
SDL_GL_SwapWindow(glGlobals.window);
|
||||
#elif defined(LIBRW_GLFW)
|
||||
if(flags & Raster::FLIPWAITVSYNCH)
|
||||
glfwSwapInterval(1);
|
||||
else
|
||||
glfwSwapInterval(0);
|
||||
glfwSwapBuffers(glGlobals.window);
|
||||
#else
|
||||
not implemented
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1603,7 +1615,174 @@ stopSDL2(void)
|
||||
SDL_DestroyWindow(glGlobals.window);
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
|
||||
#elif defined(LIBRW_SDL3)
|
||||
|
||||
static void
|
||||
addVideoMode(const SDL_DisplayMode *mode)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 1; i < glGlobals.numModes; i++){
|
||||
if(glGlobals.modes[i].mode.w == mode->w &&
|
||||
glGlobals.modes[i].mode.h == mode->h &&
|
||||
glGlobals.modes[i].mode.format == mode->format){
|
||||
// had this mode already, remember highest refresh rate
|
||||
if(mode->refresh_rate > glGlobals.modes[i].mode.refresh_rate)
|
||||
glGlobals.modes[i].mode.refresh_rate = mode->refresh_rate;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// none found, add
|
||||
glGlobals.modes[glGlobals.numModes].mode = *mode;
|
||||
glGlobals.modes[glGlobals.numModes].flags = VIDEOMODEEXCLUSIVE;
|
||||
glGlobals.numModes++;
|
||||
}
|
||||
|
||||
static void
|
||||
makeVideoModeList(SDL_DisplayID displayIndex, SDL_DisplayID *displays)
|
||||
{
|
||||
int i, num, depth;
|
||||
const SDL_DisplayMode *currentMode;
|
||||
SDL_DisplayMode **modes;
|
||||
|
||||
currentMode = SDL_GetCurrentDisplayMode(displays[displayIndex]);
|
||||
modes = SDL_GetFullscreenDisplayModes(displayIndex, &num);
|
||||
|
||||
rwFree(glGlobals.modes);
|
||||
glGlobals.modes = rwNewT(DisplayMode, num+(currentMode != NULL ? 1 : 0), ID_DRIVER | MEMDUR_EVENT);
|
||||
|
||||
if (currentMode) {
|
||||
glGlobals.modes[0].mode = *currentMode;
|
||||
glGlobals.modes[0].flags = 0;
|
||||
glGlobals.numModes = 1;
|
||||
}
|
||||
|
||||
for(i = 0; i < num; i++)
|
||||
addVideoMode(modes[i]);
|
||||
|
||||
for(i = 0; i < glGlobals.numModes; i++){
|
||||
depth = SDL_BITSPERPIXEL(glGlobals.modes[i].mode.format);
|
||||
// set depth to power of two
|
||||
for(glGlobals.modes[i].depth = 1; glGlobals.modes[i].depth < depth; glGlobals.modes[i].depth <<= 1);
|
||||
}
|
||||
SDL_free(modes);
|
||||
}
|
||||
|
||||
static int
|
||||
openSDL3(EngineOpenParams *openparams)
|
||||
{
|
||||
glGlobals.winWidth = openparams->width;
|
||||
glGlobals.winHeight = openparams->height;
|
||||
glGlobals.winTitle = openparams->windowtitle;
|
||||
glGlobals.pWindow = openparams->window;
|
||||
|
||||
memset(&gl3Caps, 0, sizeof(gl3Caps));
|
||||
|
||||
/* Init SDL */
|
||||
if (!SDL_InitSubSystem(SDL_INIT_VIDEO)){
|
||||
RWERROR((ERR_GENERAL, SDL_GetError()));
|
||||
return 0;
|
||||
}
|
||||
|
||||
glGlobals.currentDisplay = 0;
|
||||
SDL_DisplayID *displays = SDL_GetDisplays(&glGlobals.numDisplays);
|
||||
|
||||
if (glGlobals.currentDisplay >= glGlobals.numDisplays) {
|
||||
RWERROR((ERR_GENERAL, SDL_GetError()));
|
||||
return 0;
|
||||
}
|
||||
|
||||
makeVideoModeList(glGlobals.currentDisplay, displays);
|
||||
SDL_free(displays);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
closeSDL3(void)
|
||||
{
|
||||
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct {
|
||||
int gl;
|
||||
int major, minor;
|
||||
} profiles[] = {
|
||||
{ SDL_GL_CONTEXT_PROFILE_CORE, 3, 3 },
|
||||
{ SDL_GL_CONTEXT_PROFILE_CORE, 2, 1 },
|
||||
{ SDL_GL_CONTEXT_PROFILE_ES, 3, 1 },
|
||||
{ SDL_GL_CONTEXT_PROFILE_ES, 2, 0 },
|
||||
{ 0, 0, 0 },
|
||||
};
|
||||
|
||||
static int
|
||||
startSDL3(void)
|
||||
{
|
||||
SDL_Window *win;
|
||||
SDL_GLContext ctx;
|
||||
DisplayMode *mode;
|
||||
|
||||
mode = &glGlobals.modes[glGlobals.currentMode];
|
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, glGlobals.numSamples);
|
||||
|
||||
int i;
|
||||
for(i = 0; profiles[i].gl; i++){
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, profiles[i].gl);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, profiles[i].major);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, profiles[i].minor);
|
||||
|
||||
if(mode->flags & VIDEOMODEEXCLUSIVE) {
|
||||
win = SDL_CreateWindow(glGlobals.winTitle, mode->mode.w, mode->mode.h, SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN);
|
||||
if (win)
|
||||
SDL_SetWindowFullscreenMode(win, &mode->mode);
|
||||
} else {
|
||||
win = SDL_CreateWindow(glGlobals.winTitle, glGlobals.winWidth, glGlobals.winHeight, SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL);
|
||||
if (win)
|
||||
SDL_SetWindowFullscreenMode(win, NULL);
|
||||
}
|
||||
if(win){
|
||||
gl3Caps.gles = profiles[i].gl == SDL_GL_CONTEXT_PROFILE_ES;
|
||||
gl3Caps.glversion = profiles[i].major*10 + profiles[i].minor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(win == nil){
|
||||
RWERROR((ERR_GENERAL, SDL_GetError()));
|
||||
return 0;
|
||||
}
|
||||
ctx = SDL_GL_CreateContext(win);
|
||||
|
||||
if (!((gl3Caps.gles ? gladLoadGLES2Loader : gladLoadGLLoader) ((GLADloadproc) SDL_GL_GetProcAddress, gl3Caps.glversion)) ) {
|
||||
RWERROR((ERR_GENERAL, "gladLoadGLLoader failed"));
|
||||
SDL_GL_DestroyContext(ctx);
|
||||
SDL_DestroyWindow(win);
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("OpenGL version: %s\n", glGetString(GL_VERSION));
|
||||
|
||||
glGlobals.window = win;
|
||||
glGlobals.glcontext = ctx;
|
||||
*glGlobals.pWindow = win;
|
||||
glGlobals.presentWidth = 0;
|
||||
glGlobals.presentHeight = 0;
|
||||
glGlobals.presentOffX = 0;
|
||||
glGlobals.presentOffY = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
stopSDL3(void)
|
||||
{
|
||||
SDL_GL_DestroyContext(glGlobals.glcontext);
|
||||
SDL_DestroyWindow(glGlobals.window);
|
||||
return 1;
|
||||
}
|
||||
#elif defined(LIBRW_GLFW)
|
||||
|
||||
static void
|
||||
addVideoMode(const GLFWvidmode *mode)
|
||||
@@ -1767,6 +1946,8 @@ stopGLFW(void)
|
||||
glfwDestroyWindow(glGlobals.window);
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
not implemented
|
||||
#endif
|
||||
|
||||
static int
|
||||
@@ -2007,7 +2188,94 @@ deviceSystemSDL2(DeviceReq req, void *arg, int32 n)
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else
|
||||
#elif defined(LIBRW_SDL3)
|
||||
|
||||
static int
|
||||
deviceSystemSDL3(DeviceReq req, void *arg, int32 n)
|
||||
{
|
||||
VideoMode *rwmode;
|
||||
|
||||
switch(req){
|
||||
case DEVICEOPEN:
|
||||
return openSDL3((EngineOpenParams*)arg);
|
||||
case DEVICECLOSE:
|
||||
return closeSDL3();
|
||||
|
||||
case DEVICEINIT:
|
||||
return startSDL3() && initOpenGL();
|
||||
case DEVICETERM:
|
||||
return termOpenGL() && stopSDL3();
|
||||
|
||||
case DEVICEFINALIZE:
|
||||
return finalizeOpenGL();
|
||||
|
||||
|
||||
case DEVICEGETNUMSUBSYSTEMS:
|
||||
return glGlobals.numDisplays;
|
||||
|
||||
case DEVICEGETCURRENTSUBSYSTEM:
|
||||
return glGlobals.currentDisplay;
|
||||
|
||||
case DEVICESETSUBSYSTEM:
|
||||
if (n >= glGlobals.numDisplays)
|
||||
return 0;
|
||||
glGlobals.currentDisplay = n;
|
||||
return 1;
|
||||
|
||||
case DEVICEGETSUBSSYSTEMINFO: {
|
||||
const char *display_name = SDL_GetDisplayName(n);
|
||||
if (display_name == nil)
|
||||
return 0;
|
||||
strncpy(((SubSystemInfo*)arg)->name, display_name, sizeof(SubSystemInfo::name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
case DEVICEGETNUMVIDEOMODES:
|
||||
return glGlobals.numModes;
|
||||
|
||||
case DEVICEGETCURRENTVIDEOMODE:
|
||||
return glGlobals.currentMode;
|
||||
|
||||
case DEVICESETVIDEOMODE:
|
||||
if(n >= glGlobals.numModes)
|
||||
return 0;
|
||||
glGlobals.currentMode = n;
|
||||
return 1;
|
||||
|
||||
case DEVICEGETVIDEOMODEINFO:
|
||||
if (n <= 0)
|
||||
return 0;
|
||||
rwmode = (VideoMode*)arg;
|
||||
rwmode->width = glGlobals.modes[n].mode.w;
|
||||
rwmode->height = glGlobals.modes[n].mode.h;
|
||||
rwmode->depth = glGlobals.modes[n].depth;
|
||||
rwmode->flags = glGlobals.modes[n].flags;
|
||||
return 1;
|
||||
|
||||
case DEVICEGETMAXMULTISAMPLINGLEVELS:
|
||||
{
|
||||
GLint maxSamples;
|
||||
glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
|
||||
if(maxSamples == 0)
|
||||
return 1;
|
||||
return maxSamples;
|
||||
}
|
||||
case DEVICEGETMULTISAMPLINGLEVELS:
|
||||
if(glGlobals.numSamples == 0)
|
||||
return 1;
|
||||
return glGlobals.numSamples;
|
||||
case DEVICESETMULTISAMPLINGLEVELS:
|
||||
glGlobals.numSamples = (uint32)n;
|
||||
return 1;
|
||||
default:
|
||||
assert(0 && "not implemented");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#elif defined(LIBRW_GLFW)
|
||||
|
||||
static int
|
||||
deviceSystemGLFW(DeviceReq req, void *arg, int32 n)
|
||||
@@ -2094,6 +2362,10 @@ deviceSystemGLFW(DeviceReq req, void *arg, int32 n)
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
not implemented
|
||||
|
||||
#endif
|
||||
|
||||
Device renderdevice = {
|
||||
@@ -2115,8 +2387,12 @@ Device renderdevice = {
|
||||
gl3::im3DEnd,
|
||||
#ifdef LIBRW_SDL2
|
||||
gl3::deviceSystemSDL2
|
||||
#else
|
||||
#elif defined(LIBRW_SDL3)
|
||||
gl3::deviceSystemSDL3
|
||||
#elif defined(LIBRW_GLFW)
|
||||
gl3::deviceSystemGLFW
|
||||
#else
|
||||
not implemented
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -2,8 +2,12 @@
|
||||
#include "glad/glad.h"
|
||||
#ifdef LIBRW_SDL2
|
||||
#include <SDL.h>
|
||||
#else
|
||||
#elif defined(LIBRW_SDL3)
|
||||
#include <SDL3/SDL.h>
|
||||
#elif defined(LIBRW_GLFW)
|
||||
#include <GLFW/glfw3.h>
|
||||
#else
|
||||
not implemented
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -15,8 +19,13 @@ struct EngineOpenParams
|
||||
#ifdef LIBRW_SDL2
|
||||
SDL_Window **window;
|
||||
bool32 fullscreen;
|
||||
#else
|
||||
#elif defined(LIBRW_SDL3)
|
||||
SDL_Window **window;
|
||||
bool32 fullscreen;
|
||||
#elif defined(LIBRW_GLFW)
|
||||
GLFWwindow **window;
|
||||
#else
|
||||
not implemented
|
||||
#endif
|
||||
int width, height;
|
||||
const char *windowtitle;
|
||||
|
||||
@@ -26,8 +26,12 @@ struct DisplayMode
|
||||
{
|
||||
#ifdef LIBRW_SDL2
|
||||
SDL_DisplayMode mode;
|
||||
#else
|
||||
#elif defined(LIBRW_SDL3)
|
||||
SDL_DisplayMode mode;
|
||||
#elif defined(LIBRW_GLFW)
|
||||
GLFWvidmode mode;
|
||||
#else
|
||||
not implemented
|
||||
#endif
|
||||
int32 depth;
|
||||
uint32 flags;
|
||||
@@ -42,13 +46,22 @@ struct GlGlobals
|
||||
|
||||
int numDisplays;
|
||||
int currentDisplay;
|
||||
#else
|
||||
#elif defined(LIBRW_SDL3)
|
||||
SDL_Window **pWindow;
|
||||
SDL_Window *window;
|
||||
SDL_GLContext glcontext;
|
||||
|
||||
int numDisplays;
|
||||
int currentDisplay;
|
||||
#elif defined(LIBRW_GLFW)
|
||||
GLFWwindow **pWindow;
|
||||
GLFWwindow *window;
|
||||
|
||||
GLFWmonitor *monitor;
|
||||
int numMonitors;
|
||||
int currentMonitor;
|
||||
#else
|
||||
not implemented
|
||||
#endif
|
||||
|
||||
DisplayMode *modes;
|
||||
|
||||
Reference in New Issue
Block a user