XMLGameEngine

An engine for describing games built around Xerces, exprtk, and SFML.

View the Project on GitHub beefviper/XMLGameEngine

40. One window or two in XGEGUI

Status: built (gui/, lib/source/window*.cpp, Engine::pump(), Engine::isWindowOpen(); tests/test_engine_input.cpp). Checked on 2026-10-02 on Linux under a virtual X server with Mesa’s software OpenGL: the Qt renderer, the SDL2 backend and the OpenGL (GLFW) backend were switched between, in one window and in two, many times over, with the game playing, paused, stepped and closed from the game window’s side. SFML 3 and raylib could not be built in that environment and were only compiled by reading; Windows is where the author runs it, and the agent has not.

Background

38 and 39 first put every video library inside the one XGEGUI window, next to the tree. Only the Qt renderer fits there naturally. SFML 3 and SDL2 were made to adopt a platform window that Qt made, and raylib and GLFW, which always make a window of their own, were made to draw to a buffer that was read back and drawn again by Qt. Sharing one OpenGL context between Qt and a library then went wrong in ways that took a context keeper around every call to fix. That embedding was the most expensive part of the front end and the least like what each library is meant for.

Decision

XGEGUI shows the game in one of two layouts, and the user chooses.

Moving between them

What is gone

The library backends have one way of opening: a window of their own. Everything that existed only to embed them was removed from lib/ and gui/:

The engine and the Window interface are otherwise the same. Engine::replaceWindow() is still how the video library changes in a running game.

What was added

Why the picture is an ordinary widget

The game view used to be a QOpenGLWidget when Qt had OpenGL, which presents each frame on the display’s vertical blank. It is now an ordinary widget, drawn by Qt’s raster engine, and the application uses no OpenGL through Qt at all. The reason is the one that caused the embedding code: Qt keeps its own record of which OpenGL context is current and trusts it, and a library makes its own context current on the same thread. What was seen on Linux: after a library had run, a QOpenGLWidget created or moved into the main window drew nothing, and a controls window that had once held one showed noise. A window that has held a QOpenGLWidget appears to go on flushing through OpenGL, which would explain both. Keeping the two apart would mean a guard around every call into a library again. With no Qt OpenGL there is nothing to guard.

The price is that the Qt renderer no longer waits for the display’s refresh. On Windows the desktop compositor presents every window, so a raster window does not tear, but a frame can be shown a refresh late or twice; the game’s own clock decides when it steps either way. If the smoothness matters, the way back is a QOpenGLWidget in the one-window layout only, with a guard around library calls; that is the code this design removed.

Settled points

Approximations