My attempt would roughly be like this:
Code: Select all
bool vid_renderer_changed = false;
CUSTOM_CVAR (Int, vid_renderer, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
{
vid_renderer_changed = true;
setmodeneeded = true;
}
bool V_DoModeSetup (int width, int height, int bits)
{
if (vid_renderer_changed)
{
vid_renderer_changed = false;
delete screen;
screen = nullptr;
I_DeleteRenderer();
Renderer = nullptr;
I_CreateRenderer();
}
DFrameBuffer *buff = I_SetMode (width, height, screen);
... the rest of the function as it looks like today ..
}
The "setmodeneeded = true" is to fool zdoom into moving to a point in the code where I'm sure it is safe to delete screen. Once screen is deleted, I know the OpenGL window is gone, so we switch renderer. The I_SetMode call then creates a new screen, which the current V_DoModeSetup then assigns to the global screen variable. That means I can be sure that the rest of zdoom can handle a new screen at this point. The big unknown is whether the code can also handle a new renderer at this very spot.
The main reason I don't attempt to do anything in the CUSTOM_CVAR handler is because I have no idea when zdoom might call it in its game loop.