mirror of
https://github.com/aap/librw.git
synced 2024-11-28 06:35:41 +00:00
Merge pull request #43 from ccawley2011/sdl2
Get the SDL2 backend working again
This commit is contained in:
commit
f68bdb3649
@ -25,32 +25,35 @@
|
|||||||
|
|
||||||
namespace rw {
|
namespace rw {
|
||||||
namespace gl3 {
|
namespace gl3 {
|
||||||
#ifndef LIBRW_SDL2
|
|
||||||
struct DisplayMode
|
struct DisplayMode
|
||||||
{
|
{
|
||||||
|
#ifdef LIBRW_SDL2
|
||||||
|
SDL_DisplayMode mode;
|
||||||
|
#else
|
||||||
GLFWvidmode mode;
|
GLFWvidmode mode;
|
||||||
|
#endif
|
||||||
int32 depth;
|
int32 depth;
|
||||||
uint32 flags;
|
uint32 flags;
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
struct GlGlobals
|
struct GlGlobals
|
||||||
{
|
{
|
||||||
#ifdef LIBRW_SDL2
|
#ifdef LIBRW_SDL2
|
||||||
|
SDL_Window **pWindow;
|
||||||
SDL_Window *window;
|
SDL_Window *window;
|
||||||
SDL_GLContext glcontext;
|
SDL_GLContext glcontext;
|
||||||
#else
|
#else
|
||||||
|
GLFWwindow **pWindow;
|
||||||
GLFWwindow *window;
|
GLFWwindow *window;
|
||||||
|
|
||||||
GLFWmonitor *monitor;
|
GLFWmonitor *monitor;
|
||||||
int numMonitors;
|
int numMonitors;
|
||||||
int currentMonitor;
|
int currentMonitor;
|
||||||
|
#endif
|
||||||
|
|
||||||
DisplayMode *modes;
|
DisplayMode *modes;
|
||||||
int numModes;
|
int numModes;
|
||||||
int currentMode;
|
int currentMode;
|
||||||
GLFWwindow **pWindow;
|
|
||||||
#endif
|
|
||||||
int presentWidth, presentHeight;
|
int presentWidth, presentHeight;
|
||||||
int presentOffX, presentOffY;
|
int presentOffX, presentOffY;
|
||||||
|
|
||||||
@ -1434,6 +1437,10 @@ showRaster(Raster *raster, uint32 flags)
|
|||||||
{
|
{
|
||||||
// TODO: do this properly!
|
// TODO: do this properly!
|
||||||
#ifdef LIBRW_SDL2
|
#ifdef LIBRW_SDL2
|
||||||
|
if(flags & Raster::FLIPWAITVSYNCH)
|
||||||
|
SDL_GL_SetSwapInterval(1);
|
||||||
|
else
|
||||||
|
SDL_GL_SetSwapInterval(0);
|
||||||
SDL_GL_SwapWindow(glGlobals.window);
|
SDL_GL_SwapWindow(glGlobals.window);
|
||||||
#else
|
#else
|
||||||
if(flags & Raster::FLIPWAITVSYNCH)
|
if(flags & Raster::FLIPWAITVSYNCH)
|
||||||
@ -1471,70 +1478,164 @@ rasterRenderFast(Raster *raster, int32 x, int32 y)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LIBRW_SDL2
|
#ifdef LIBRW_SDL2
|
||||||
|
|
||||||
|
static void
|
||||||
|
addVideoMode(int displayIndex, int modeIndex)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
SDL_DisplayMode mode;
|
||||||
|
|
||||||
|
SDL_GetDisplayMode(displayIndex, modeIndex, &mode);
|
||||||
|
|
||||||
|
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(int displayIndex)
|
||||||
|
{
|
||||||
|
int i, num, depth;
|
||||||
|
|
||||||
|
num = SDL_GetNumDisplayModes(displayIndex);
|
||||||
|
rwFree(glGlobals.modes);
|
||||||
|
glGlobals.modes = rwNewT(DisplayMode, num+1, ID_DRIVER | MEMDUR_EVENT);
|
||||||
|
|
||||||
|
SDL_GetCurrentDisplayMode(displayIndex, &glGlobals.modes[0].mode);
|
||||||
|
glGlobals.modes[0].flags = 0;
|
||||||
|
glGlobals.numModes = 1;
|
||||||
|
|
||||||
|
for(i = 0; i < num; i++)
|
||||||
|
addVideoMode(displayIndex, 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
openSDL2(EngineOpenParams *openparams)
|
openSDL2(EngineOpenParams *openparams)
|
||||||
{
|
{
|
||||||
if (!openparams){
|
glGlobals.winWidth = openparams->width;
|
||||||
RWERROR((ERR_GENERAL, "openparams invalid"));
|
glGlobals.winHeight = openparams->height;
|
||||||
return 0;
|
glGlobals.winTitle = openparams->windowtitle;
|
||||||
}
|
glGlobals.pWindow = openparams->window;
|
||||||
|
|
||||||
GLenum status;
|
memset(&gl3Caps, 0, sizeof(gl3Caps));
|
||||||
SDL_Window *win;
|
|
||||||
SDL_GLContext ctx;
|
|
||||||
|
|
||||||
/* Init SDL */
|
/* Init SDL */
|
||||||
if(SDL_InitSubSystem(SDL_INIT_VIDEO)){
|
if(SDL_InitSubSystem(SDL_INIT_VIDEO)){
|
||||||
RWERROR((ERR_ENGINEOPEN, SDL_GetError()));
|
RWERROR((ERR_GENERAL, SDL_GetError()));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
SDL_ClearHints();
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
|
||||||
|
|
||||||
int flags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL;
|
makeVideoModeList(0);
|
||||||
if (openparams->fullscreen)
|
|
||||||
flags |= SDL_WINDOW_FULLSCREEN;
|
|
||||||
win = SDL_CreateWindow(openparams->windowtitle, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, openparams->width, openparams->height, flags);
|
|
||||||
if(win == nil){
|
|
||||||
RWERROR((ERR_ENGINEOPEN, SDL_GetError()));
|
|
||||||
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
ctx = SDL_GL_CreateContext(win);
|
|
||||||
|
|
||||||
/* Init GLEW */
|
|
||||||
glewExperimental = GL_TRUE;
|
|
||||||
status = glewInit();
|
|
||||||
if(status != GLEW_OK){
|
|
||||||
RWERROR((ERR_ENGINEOPEN, glewGetErrorString(status)));
|
|
||||||
SDL_GL_DeleteContext(ctx);
|
|
||||||
SDL_DestroyWindow(win);
|
|
||||||
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if(!GLEW_VERSION_3_3){
|
|
||||||
RWERROR((ERR_VERSION, "OpenGL 3.3 needed"));
|
|
||||||
SDL_GL_DeleteContext(ctx);
|
|
||||||
SDL_DestroyWindow(win);
|
|
||||||
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
glGlobals.window = win;
|
|
||||||
glGlobals.glcontext = ctx;
|
|
||||||
*openparams->window = win;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
closeSDL2(void)
|
closeSDL2(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
|
||||||
|
startSDL2(void)
|
||||||
|
{
|
||||||
|
GLenum status;
|
||||||
|
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, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, mode->mode.w, mode->mode.h, SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN);
|
||||||
|
if (win)
|
||||||
|
SDL_SetWindowDisplayMode(win, &mode->mode);
|
||||||
|
} else {
|
||||||
|
win = SDL_CreateWindow(glGlobals.winTitle, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, glGlobals.winWidth, glGlobals.winHeight, SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL);
|
||||||
|
if (win)
|
||||||
|
SDL_SetWindowDisplayMode(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);
|
||||||
|
printf("OpenGL version: %s\n", glGetString(GL_VERSION));
|
||||||
|
|
||||||
|
/* Init GLEW */
|
||||||
|
glewExperimental = GL_TRUE;
|
||||||
|
status = glewInit();
|
||||||
|
if(status != GLEW_OK){
|
||||||
|
RWERROR((ERR_GENERAL, glewGetErrorString(status)));
|
||||||
|
SDL_GL_DeleteContext(ctx);
|
||||||
|
SDL_DestroyWindow(win);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(!GLEW_VERSION_3_3){
|
||||||
|
RWERROR((ERR_GENERAL, "OpenGL 3.3 needed"));
|
||||||
|
SDL_GL_DeleteContext(ctx);
|
||||||
|
SDL_DestroyWindow(win);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
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
|
||||||
|
stopSDL2(void)
|
||||||
{
|
{
|
||||||
SDL_GL_DeleteContext(glGlobals.glcontext);
|
SDL_GL_DeleteContext(glGlobals.glcontext);
|
||||||
SDL_DestroyWindow(glGlobals.window);
|
SDL_DestroyWindow(glGlobals.window);
|
||||||
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -1831,6 +1932,8 @@ finalizeOpenGL(void)
|
|||||||
static int
|
static int
|
||||||
deviceSystemSDL2(DeviceReq req, void *arg, int32 n)
|
deviceSystemSDL2(DeviceReq req, void *arg, int32 n)
|
||||||
{
|
{
|
||||||
|
VideoMode *rwmode;
|
||||||
|
|
||||||
switch(req){
|
switch(req){
|
||||||
case DEVICEOPEN:
|
case DEVICEOPEN:
|
||||||
return openSDL2((EngineOpenParams*)arg);
|
return openSDL2((EngineOpenParams*)arg);
|
||||||
@ -1838,12 +1941,50 @@ deviceSystemSDL2(DeviceReq req, void *arg, int32 n)
|
|||||||
return closeSDL2();
|
return closeSDL2();
|
||||||
|
|
||||||
case DEVICEINIT:
|
case DEVICEINIT:
|
||||||
return initOpenGL();
|
return startSDL2() && initOpenGL();
|
||||||
case DEVICETERM:
|
case DEVICETERM:
|
||||||
return termOpenGL();
|
return termOpenGL() && stopSDL2();
|
||||||
|
|
||||||
// TODO: implement subsystems and video modes
|
case DEVICEFINALIZE:
|
||||||
|
return finalizeOpenGL();
|
||||||
|
|
||||||
|
// TODO: implement subsystems
|
||||||
|
|
||||||
|
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:
|
||||||
|
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:
|
default:
|
||||||
assert(0 && "not implemented");
|
assert(0 && "not implemented");
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user