mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-23 15:52:55 +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 x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(defaultDisplay);
|
||||||
sint32 y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(defaultDisplay);
|
sint32 y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(defaultDisplay);
|
||||||
|
|
||||||
// Get saved window size
|
CreateWindow(x, y);
|
||||||
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);
|
|
||||||
|
|
||||||
// Check if steam overlay renderer is loaded into the process
|
// Check if steam overlay renderer is loaded into the process
|
||||||
_steamOverlayActive = _platformUiContext->IsSteamOverlayAttached();
|
_steamOverlayActive = _platformUiContext->IsSteamOverlayAttached();
|
||||||
TriggerResize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CloseWindow() override
|
void CloseWindow() override
|
||||||
{
|
{
|
||||||
drawing_engine_dispose();
|
drawing_engine_dispose();
|
||||||
SDL_DestroyWindow(_window);
|
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
|
void ShowMessageBox(const std::string &message) override
|
||||||
@@ -646,6 +630,41 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
private:
|
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)
|
void OnResize(sint32 width, sint32 height)
|
||||||
{
|
{
|
||||||
// Scale the native window size to the game's canvas size
|
// Scale the native window size to the game's canvas size
|
||||||
|
|||||||
@@ -121,8 +121,14 @@ static const char * TryLoadAllProcAddresses()
|
|||||||
|
|
||||||
namespace OpenGLState
|
namespace OpenGLState
|
||||||
{
|
{
|
||||||
uint16 ActiveTexture = UINT16_MAX;
|
uint16 ActiveTexture;
|
||||||
GLuint CurrentProgram = UINT32_MAX;
|
GLuint CurrentProgram;
|
||||||
|
|
||||||
|
void Reset()
|
||||||
|
{
|
||||||
|
ActiveTexture = UINT16_MAX;
|
||||||
|
CurrentProgram = UINT32_MAX;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLAPI::SetTexture(uint16 index, GLenum type, GLuint texture)
|
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()
|
bool OpenGLAPI::Initialise()
|
||||||
{
|
{
|
||||||
|
OpenGLState::Reset();
|
||||||
|
|
||||||
#ifdef OPENGL_NO_LINK
|
#ifdef OPENGL_NO_LINK
|
||||||
const char * failedProcName = TryLoadAllProcAddresses();
|
const char * failedProcName = TryLoadAllProcAddresses();
|
||||||
if (failedProcName != nullptr)
|
if (failedProcName != nullptr)
|
||||||
|
|||||||
@@ -198,4 +198,6 @@ namespace OpenGLState
|
|||||||
{
|
{
|
||||||
extern uint16 ActiveTexture;
|
extern uint16 ActiveTexture;
|
||||||
extern GLuint CurrentProgram;
|
extern GLuint CurrentProgram;
|
||||||
|
|
||||||
|
void Reset();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -663,6 +663,11 @@ extern "C"
|
|||||||
return GetContext()->GetUiContext()->SetFullscreenMode((FULLSCREEN_MODE)mode);
|
return GetContext()->GetUiContext()->SetFullscreenMode((FULLSCREEN_MODE)mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void context_recreate_window()
|
||||||
|
{
|
||||||
|
GetContext()->GetUiContext()->RecreateWindow();
|
||||||
|
}
|
||||||
|
|
||||||
sint32 context_get_resolutions(Resolution * * outResolutions)
|
sint32 context_get_resolutions(Resolution * * outResolutions)
|
||||||
{
|
{
|
||||||
auto resolutions = GetContext()->GetUiContext()->GetFullscreenResolutions();
|
auto resolutions = GetContext()->GetUiContext()->GetFullscreenResolutions();
|
||||||
|
|||||||
@@ -127,6 +127,7 @@ extern "C"
|
|||||||
bool context_is_input_active();
|
bool context_is_input_active();
|
||||||
void context_trigger_resize();
|
void context_trigger_resize();
|
||||||
void context_set_fullscreen_mode(sint32 mode);
|
void context_set_fullscreen_mode(sint32 mode);
|
||||||
|
void context_recreate_window();
|
||||||
sint32 context_get_resolutions(struct Resolution * * outResolutions);
|
sint32 context_get_resolutions(struct Resolution * * outResolutions);
|
||||||
sint32 context_get_width();
|
sint32 context_get_width();
|
||||||
sint32 context_get_height();
|
sint32 context_get_height();
|
||||||
|
|||||||
@@ -57,20 +57,18 @@ extern "C"
|
|||||||
return _drawingEngineType;
|
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
|
#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
|
// 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
|
// using the same window in an unaccelerated and accelerated context is unsupported by SDL2
|
||||||
requiresRestart = false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return requiresRestart;
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawing_engine_init()
|
void drawing_engine_init()
|
||||||
@@ -135,14 +133,12 @@ extern "C"
|
|||||||
|
|
||||||
void drawing_engine_resize()
|
void drawing_engine_resize()
|
||||||
{
|
{
|
||||||
if (_drawingEngine == nullptr)
|
if (_drawingEngine != nullptr)
|
||||||
{
|
{
|
||||||
drawing_engine_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
IUiContext * uiContext = GetContext()->GetUiContext();
|
IUiContext * uiContext = GetContext()->GetUiContext();
|
||||||
_drawingEngine->Resize(uiContext->GetWidth(), uiContext->GetHeight());
|
_drawingEngine->Resize(uiContext->GetWidth(), uiContext->GetHeight());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void drawing_engine_set_palette(const rct_palette_entry * colours)
|
void drawing_engine_set_palette(const rct_palette_entry * colours)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ extern "C"
|
|||||||
extern rct_string_id DrawingEngineStringIds[3];
|
extern rct_string_id DrawingEngineStringIds[3];
|
||||||
|
|
||||||
sint32 drawing_engine_get_type();
|
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_init();
|
||||||
void drawing_engine_resize();
|
void drawing_engine_resize();
|
||||||
void drawing_engine_set_palette(const rct_palette_entry * colours);
|
void drawing_engine_set_palette(const rct_palette_entry * colours);
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ void platform_draw_require_end();
|
|||||||
void platform_free();
|
void platform_free();
|
||||||
void platform_update_palette(const uint8 *colours, sint32 start_index, sint32 num_colours);
|
void platform_update_palette(const uint8 *colours, sint32 start_index, sint32 num_colours);
|
||||||
void platform_toggle_windowed_mode();
|
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_date_utc(rct2_date *out_date);
|
||||||
void platform_get_time_utc(rct2_time *out_time);
|
void platform_get_time_utc(rct2_time *out_time);
|
||||||
void platform_get_date_local(rct2_date *out_date);
|
void platform_get_date_local(rct2_date *out_date);
|
||||||
|
|||||||
@@ -152,11 +152,19 @@ void platform_toggle_windowed_mode()
|
|||||||
config_save_default();
|
config_save_default();
|
||||||
}
|
}
|
||||||
|
|
||||||
void platform_refresh_video()
|
void platform_refresh_video(bool recreate_window)
|
||||||
{
|
{
|
||||||
|
if (recreate_window)
|
||||||
|
{
|
||||||
|
context_recreate_window();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
drawing_engine_dispose();
|
drawing_engine_dispose();
|
||||||
drawing_engine_init();
|
drawing_engine_init();
|
||||||
drawing_engine_resize();
|
drawing_engine_resize();
|
||||||
|
}
|
||||||
|
|
||||||
drawing_engine_set_palette(gPalette);
|
drawing_engine_set_palette(gPalette);
|
||||||
gfx_invalidate_screen();
|
gfx_invalidate_screen();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ namespace OpenRCT2 { namespace Ui
|
|||||||
public:
|
public:
|
||||||
void CreateWindow() override { }
|
void CreateWindow() override { }
|
||||||
void CloseWindow() override { }
|
void CloseWindow() override { }
|
||||||
|
void RecreateWindow() override { }
|
||||||
void * GetWindow() override { return nullptr; }
|
void * GetWindow() override { return nullptr; }
|
||||||
sint32 GetWidth() override { return 0; }
|
sint32 GetWidth() override { return 0; }
|
||||||
sint32 GetHeight() override { return 0; }
|
sint32 GetHeight() override { return 0; }
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ namespace OpenRCT2
|
|||||||
// Window
|
// Window
|
||||||
virtual void CreateWindow() abstract;
|
virtual void CreateWindow() abstract;
|
||||||
virtual void CloseWindow() abstract;
|
virtual void CloseWindow() abstract;
|
||||||
|
virtual void RecreateWindow() abstract;
|
||||||
virtual void * GetWindow() abstract;
|
virtual void * GetWindow() abstract;
|
||||||
virtual sint32 GetWidth() abstract;
|
virtual sint32 GetWidth() abstract;
|
||||||
virtual sint32 GetHeight() abstract;
|
virtual sint32 GetHeight() abstract;
|
||||||
|
|||||||
@@ -639,7 +639,7 @@ static void window_options_mouseup(rct_window *w, rct_widgetindex widgetIndex)
|
|||||||
break;
|
break;
|
||||||
case WIDX_MINIMIZE_FOCUS_LOSS:
|
case WIDX_MINIMIZE_FOCUS_LOSS:
|
||||||
gConfigGeneral.minimize_fullscreen_focus_loss ^= 1;
|
gConfigGeneral.minimize_fullscreen_focus_loss ^= 1;
|
||||||
platform_refresh_video();
|
platform_refresh_video(false);
|
||||||
config_save_default();
|
config_save_default();
|
||||||
window_invalidate(w);
|
window_invalidate(w);
|
||||||
break;
|
break;
|
||||||
@@ -1308,11 +1308,8 @@ static void window_options_dropdown(rct_window *w, rct_widgetindex widgetIndex,
|
|||||||
sint32 dstEngine = dropdownIndex;
|
sint32 dstEngine = dropdownIndex;
|
||||||
|
|
||||||
gConfigGeneral.drawing_engine = (uint8)dstEngine;
|
gConfigGeneral.drawing_engine = (uint8)dstEngine;
|
||||||
if (drawing_engine_requires_restart(srcEngine, dstEngine)) {
|
bool recreate_window = drawing_engine_requires_new_window(srcEngine, dstEngine);
|
||||||
window_error_open(STR_RESTART_REQUIRED, STR_NONE);
|
platform_refresh_video(recreate_window);
|
||||||
} else {
|
|
||||||
platform_refresh_video();
|
|
||||||
}
|
|
||||||
config_save_default();
|
config_save_default();
|
||||||
window_invalidate(w);
|
window_invalidate(w);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user