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: [#5872] Incorrect OpenGL rendering of masked sprites
|
||||
- Improved: [#5859] OpenGL rendering performance
|
||||
- Improved: [#5863] Switching drawing engines no longer requires the application to restart.
|
||||
|
||||
0.1.0 (2017-07-12)
|
||||
------------------------------------------------------------------------
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -81,8 +81,6 @@ DrawImageShader::~DrawImageShader()
|
|||
glDeleteBuffers(1, &_vbo);
|
||||
glDeleteBuffers(1, &_vboInstances);
|
||||
glDeleteVertexArrays(1, &_vao);
|
||||
|
||||
glBindVertexArray(_vao);
|
||||
}
|
||||
|
||||
void DrawImageShader::GetLocations()
|
||||
|
|
|
@ -41,8 +41,6 @@ DrawLineShader::~DrawLineShader()
|
|||
{
|
||||
glDeleteBuffers(1, &_vbo);
|
||||
glDeleteVertexArrays(1, &_vao);
|
||||
|
||||
glBindVertexArray(_vao);
|
||||
}
|
||||
|
||||
void DrawLineShader::GetLocations()
|
||||
|
|
|
@ -43,8 +43,6 @@ FillRectShader::~FillRectShader()
|
|||
{
|
||||
glDeleteBuffers(1, &_vbo);
|
||||
glDeleteVertexArrays(1, &_vao);
|
||||
|
||||
glBindVertexArray(_vao);
|
||||
}
|
||||
|
||||
void FillRectShader::GetLocations()
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue