mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-22 15:23:01 +01:00
Allow switching between OpenGL and other renderers without restarting
This commit is contained in:
committed by
Ted John
parent
ab39262ccf
commit
ae110a9159
@@ -516,44 +516,28 @@ public:
|
||||
sint32 x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(defaultDisplay);
|
||||
sint32 y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(defaultDisplay);
|
||||
|
||||
// Get saved window size
|
||||
sint32 width = gConfigGeneral.window_width;
|
||||
sint32 height = gConfigGeneral.window_height;
|
||||
if (width <= 0) width = 640;
|
||||
if (height <= 0) height = 480;
|
||||
|
||||
// Create window in window first rather than fullscreen so we have the display the window is on first
|
||||
uint32 flags = SDL_WINDOW_RESIZABLE;
|
||||
if (gConfigGeneral.drawing_engine == DRAWING_ENGINE_OPENGL)
|
||||
{
|
||||
flags |= SDL_WINDOW_OPENGL;
|
||||
}
|
||||
|
||||
_window = SDL_CreateWindow(OPENRCT2_NAME, x, y, width, height, flags);
|
||||
if (_window == nullptr)
|
||||
{
|
||||
SDLException::Throw("SDL_CreateWindow(...)");
|
||||
}
|
||||
|
||||
SDL_SetWindowMinimumSize(_window, 720, 480);
|
||||
SetCursorTrap(gConfigGeneral.trap_cursor);
|
||||
_platformUiContext->SetWindowIcon(_window);
|
||||
|
||||
// Initialise the surface, palette and draw buffer
|
||||
OnResize(width, height);
|
||||
|
||||
UpdateFullscreenResolutions();
|
||||
SetFullscreenMode((FULLSCREEN_MODE)gConfigGeneral.fullscreen_mode);
|
||||
CreateWindow(x, y);
|
||||
|
||||
// Check if steam overlay renderer is loaded into the process
|
||||
_steamOverlayActive = _platformUiContext->IsSteamOverlayAttached();
|
||||
TriggerResize();
|
||||
}
|
||||
|
||||
void CloseWindow() override
|
||||
{
|
||||
drawing_engine_dispose();
|
||||
SDL_DestroyWindow(_window);
|
||||
_window = nullptr;
|
||||
}
|
||||
|
||||
void RecreateWindow() override
|
||||
{
|
||||
// Use the position of the current window for the new window
|
||||
sint32 x, y;
|
||||
SDL_SetWindowFullscreen(_window, 0);
|
||||
SDL_GetWindowPosition(_window, &x, &y);
|
||||
|
||||
CloseWindow();
|
||||
CreateWindow(x, y);
|
||||
}
|
||||
|
||||
void ShowMessageBox(const std::string &message) override
|
||||
@@ -646,6 +630,41 @@ public:
|
||||
|
||||
|
||||
private:
|
||||
void CreateWindow(sint32 x, sint32 y)
|
||||
{
|
||||
// Get saved window size
|
||||
sint32 width = gConfigGeneral.window_width;
|
||||
sint32 height = gConfigGeneral.window_height;
|
||||
if (width <= 0) width = 640;
|
||||
if (height <= 0) height = 480;
|
||||
|
||||
// Create window in window first rather than fullscreen so we have the display the window is on first
|
||||
uint32 flags = SDL_WINDOW_RESIZABLE;
|
||||
if (gConfigGeneral.drawing_engine == DRAWING_ENGINE_OPENGL)
|
||||
{
|
||||
flags |= SDL_WINDOW_OPENGL;
|
||||
}
|
||||
|
||||
_window = SDL_CreateWindow(OPENRCT2_NAME, x, y, width, height, flags);
|
||||
if (_window == nullptr)
|
||||
{
|
||||
SDLException::Throw("SDL_CreateWindow(...)");
|
||||
}
|
||||
|
||||
SDL_SetWindowMinimumSize(_window, 720, 480);
|
||||
SetCursorTrap(gConfigGeneral.trap_cursor);
|
||||
_platformUiContext->SetWindowIcon(_window);
|
||||
|
||||
// Initialise the surface, palette and draw buffer
|
||||
drawing_engine_init();
|
||||
OnResize(width, height);
|
||||
|
||||
UpdateFullscreenResolutions();
|
||||
SetFullscreenMode((FULLSCREEN_MODE)gConfigGeneral.fullscreen_mode);
|
||||
|
||||
TriggerResize();
|
||||
}
|
||||
|
||||
void OnResize(sint32 width, sint32 height)
|
||||
{
|
||||
// Scale the native window size to the game's canvas size
|
||||
|
||||
@@ -121,8 +121,14 @@ static const char * TryLoadAllProcAddresses()
|
||||
|
||||
namespace OpenGLState
|
||||
{
|
||||
uint16 ActiveTexture = UINT16_MAX;
|
||||
GLuint CurrentProgram = UINT32_MAX;
|
||||
uint16 ActiveTexture;
|
||||
GLuint CurrentProgram;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
ActiveTexture = UINT16_MAX;
|
||||
CurrentProgram = UINT32_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLAPI::SetTexture(uint16 index, GLenum type, GLuint texture)
|
||||
@@ -136,6 +142,8 @@ void OpenGLAPI::SetTexture(uint16 index, GLenum type, GLuint texture)
|
||||
|
||||
bool OpenGLAPI::Initialise()
|
||||
{
|
||||
OpenGLState::Reset();
|
||||
|
||||
#ifdef OPENGL_NO_LINK
|
||||
const char * failedProcName = TryLoadAllProcAddresses();
|
||||
if (failedProcName != nullptr)
|
||||
|
||||
@@ -198,4 +198,6 @@ namespace OpenGLState
|
||||
{
|
||||
extern uint16 ActiveTexture;
|
||||
extern GLuint CurrentProgram;
|
||||
|
||||
void Reset();
|
||||
}
|
||||
|
||||
@@ -663,6 +663,11 @@ extern "C"
|
||||
return GetContext()->GetUiContext()->SetFullscreenMode((FULLSCREEN_MODE)mode);
|
||||
}
|
||||
|
||||
void context_recreate_window()
|
||||
{
|
||||
GetContext()->GetUiContext()->RecreateWindow();
|
||||
}
|
||||
|
||||
sint32 context_get_resolutions(Resolution * * outResolutions)
|
||||
{
|
||||
auto resolutions = GetContext()->GetUiContext()->GetFullscreenResolutions();
|
||||
|
||||
@@ -127,6 +127,7 @@ extern "C"
|
||||
bool context_is_input_active();
|
||||
void context_trigger_resize();
|
||||
void context_set_fullscreen_mode(sint32 mode);
|
||||
void context_recreate_window();
|
||||
sint32 context_get_resolutions(struct Resolution * * outResolutions);
|
||||
sint32 context_get_width();
|
||||
sint32 context_get_height();
|
||||
|
||||
@@ -57,20 +57,18 @@ extern "C"
|
||||
return _drawingEngineType;
|
||||
}
|
||||
|
||||
bool drawing_engine_requires_restart(sint32 srcEngine, sint32 dstEngine)
|
||||
bool drawing_engine_requires_new_window(sint32 srcEngine, sint32 dstEngine)
|
||||
{
|
||||
// Linux requires a restart. This could be improved in the future by recreating the window,
|
||||
// https://github.com/OpenRCT2/OpenRCT2/issues/2015
|
||||
bool requiresRestart = true;
|
||||
#ifdef _WIN32
|
||||
if (dstEngine != DRAWING_ENGINE_OPENGL)
|
||||
if (srcEngine != DRAWING_ENGINE_OPENGL && dstEngine != DRAWING_ENGINE_OPENGL)
|
||||
{
|
||||
// Windows is apparently able to switch to hardware rendering on the fly although
|
||||
// using the same window in an unaccelerated and accelerated context is unsupported by SDL2
|
||||
requiresRestart = false;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return requiresRestart;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void drawing_engine_init()
|
||||
@@ -135,13 +133,11 @@ extern "C"
|
||||
|
||||
void drawing_engine_resize()
|
||||
{
|
||||
if (_drawingEngine == nullptr)
|
||||
if (_drawingEngine != nullptr)
|
||||
{
|
||||
drawing_engine_init();
|
||||
IUiContext * uiContext = GetContext()->GetUiContext();
|
||||
_drawingEngine->Resize(uiContext->GetWidth(), uiContext->GetHeight());
|
||||
}
|
||||
|
||||
IUiContext * uiContext = GetContext()->GetUiContext();
|
||||
_drawingEngine->Resize(uiContext->GetWidth(), uiContext->GetHeight());
|
||||
}
|
||||
|
||||
void drawing_engine_set_palette(const rct_palette_entry * colours)
|
||||
|
||||
@@ -27,7 +27,7 @@ extern "C"
|
||||
extern rct_string_id DrawingEngineStringIds[3];
|
||||
|
||||
sint32 drawing_engine_get_type();
|
||||
bool drawing_engine_requires_restart(sint32 srcEngine, sint32 dstEngine);
|
||||
bool drawing_engine_requires_new_window(sint32 srcEngine, sint32 dstEngine);
|
||||
void drawing_engine_init();
|
||||
void drawing_engine_resize();
|
||||
void drawing_engine_set_palette(const rct_palette_entry * colours);
|
||||
|
||||
@@ -86,7 +86,7 @@ void platform_draw_require_end();
|
||||
void platform_free();
|
||||
void platform_update_palette(const uint8 *colours, sint32 start_index, sint32 num_colours);
|
||||
void platform_toggle_windowed_mode();
|
||||
void platform_refresh_video();
|
||||
void platform_refresh_video(bool recreate_window);
|
||||
void platform_get_date_utc(rct2_date *out_date);
|
||||
void platform_get_time_utc(rct2_time *out_time);
|
||||
void platform_get_date_local(rct2_date *out_date);
|
||||
|
||||
@@ -152,11 +152,19 @@ void platform_toggle_windowed_mode()
|
||||
config_save_default();
|
||||
}
|
||||
|
||||
void platform_refresh_video()
|
||||
void platform_refresh_video(bool recreate_window)
|
||||
{
|
||||
drawing_engine_dispose();
|
||||
drawing_engine_init();
|
||||
drawing_engine_resize();
|
||||
if (recreate_window)
|
||||
{
|
||||
context_recreate_window();
|
||||
}
|
||||
else
|
||||
{
|
||||
drawing_engine_dispose();
|
||||
drawing_engine_init();
|
||||
drawing_engine_resize();
|
||||
}
|
||||
|
||||
drawing_engine_set_palette(gPalette);
|
||||
gfx_invalidate_screen();
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ namespace OpenRCT2 { namespace Ui
|
||||
public:
|
||||
void CreateWindow() override { }
|
||||
void CloseWindow() override { }
|
||||
void RecreateWindow() override { }
|
||||
void * GetWindow() override { return nullptr; }
|
||||
sint32 GetWidth() override { return 0; }
|
||||
sint32 GetHeight() override { return 0; }
|
||||
|
||||
@@ -94,6 +94,7 @@ namespace OpenRCT2
|
||||
// Window
|
||||
virtual void CreateWindow() abstract;
|
||||
virtual void CloseWindow() abstract;
|
||||
virtual void RecreateWindow() abstract;
|
||||
virtual void * GetWindow() abstract;
|
||||
virtual sint32 GetWidth() abstract;
|
||||
virtual sint32 GetHeight() abstract;
|
||||
|
||||
@@ -639,7 +639,7 @@ static void window_options_mouseup(rct_window *w, rct_widgetindex widgetIndex)
|
||||
break;
|
||||
case WIDX_MINIMIZE_FOCUS_LOSS:
|
||||
gConfigGeneral.minimize_fullscreen_focus_loss ^= 1;
|
||||
platform_refresh_video();
|
||||
platform_refresh_video(false);
|
||||
config_save_default();
|
||||
window_invalidate(w);
|
||||
break;
|
||||
@@ -1308,11 +1308,8 @@ static void window_options_dropdown(rct_window *w, rct_widgetindex widgetIndex,
|
||||
sint32 dstEngine = dropdownIndex;
|
||||
|
||||
gConfigGeneral.drawing_engine = (uint8)dstEngine;
|
||||
if (drawing_engine_requires_restart(srcEngine, dstEngine)) {
|
||||
window_error_open(STR_RESTART_REQUIRED, STR_NONE);
|
||||
} else {
|
||||
platform_refresh_video();
|
||||
}
|
||||
bool recreate_window = drawing_engine_requires_new_window(srcEngine, dstEngine);
|
||||
platform_refresh_video(recreate_window);
|
||||
config_save_default();
|
||||
window_invalidate(w);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user