mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge pull request #5863 from willox/develop
Allow switching between OpenGL and software rendering without restarting
This commit is contained in:
commit
6a05aa9e33
|
@ -7,6 +7,7 @@
|
||||||
- Fix: [#5858] Crash when using custom ride with no colour presets.
|
- Fix: [#5858] Crash when using custom ride with no colour presets.
|
||||||
- Fix: [#5872] Incorrect OpenGL rendering of masked sprites
|
- Fix: [#5872] Incorrect OpenGL rendering of masked sprites
|
||||||
- Improved: [#5859] OpenGL rendering performance
|
- Improved: [#5859] OpenGL rendering performance
|
||||||
|
- Improved: [#5863] Switching drawing engines no longer requires the application to restart.
|
||||||
|
|
||||||
0.1.0 (2017-07-12)
|
0.1.0 (2017-07-12)
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -81,8 +81,6 @@ DrawImageShader::~DrawImageShader()
|
||||||
glDeleteBuffers(1, &_vbo);
|
glDeleteBuffers(1, &_vbo);
|
||||||
glDeleteBuffers(1, &_vboInstances);
|
glDeleteBuffers(1, &_vboInstances);
|
||||||
glDeleteVertexArrays(1, &_vao);
|
glDeleteVertexArrays(1, &_vao);
|
||||||
|
|
||||||
glBindVertexArray(_vao);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawImageShader::GetLocations()
|
void DrawImageShader::GetLocations()
|
||||||
|
|
|
@ -41,8 +41,6 @@ DrawLineShader::~DrawLineShader()
|
||||||
{
|
{
|
||||||
glDeleteBuffers(1, &_vbo);
|
glDeleteBuffers(1, &_vbo);
|
||||||
glDeleteVertexArrays(1, &_vao);
|
glDeleteVertexArrays(1, &_vao);
|
||||||
|
|
||||||
glBindVertexArray(_vao);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawLineShader::GetLocations()
|
void DrawLineShader::GetLocations()
|
||||||
|
|
|
@ -43,8 +43,6 @@ FillRectShader::~FillRectShader()
|
||||||
{
|
{
|
||||||
glDeleteBuffers(1, &_vbo);
|
glDeleteBuffers(1, &_vbo);
|
||||||
glDeleteVertexArrays(1, &_vao);
|
glDeleteVertexArrays(1, &_vao);
|
||||||
|
|
||||||
glBindVertexArray(_vao);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FillRectShader::GetLocations()
|
void FillRectShader::GetLocations()
|
||||||
|
|
|
@ -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,13 +133,11 @@ extern "C"
|
||||||
|
|
||||||
void drawing_engine_resize()
|
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)
|
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)
|
||||||
{
|
{
|
||||||
drawing_engine_dispose();
|
if (recreate_window)
|
||||||
drawing_engine_init();
|
{
|
||||||
drawing_engine_resize();
|
context_recreate_window();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
drawing_engine_dispose();
|
||||||
|
drawing_engine_init();
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue