Why do I get an access violation after changing to windowed when fullscreen works perfectly?

Started by
4 comments, last by FrankieTheSkin 4 years, 4 months ago

Hi,

I'm trying to change my engine from using real fullscreen to using a fullscreen window, but after changing the .Windowed parameter from FALSE to TRUE, it crashes, even though it works perfectly in real fullscreen, and I can't figure out why. :-/

if (D3D = Direct3DCreate9(D3D_SDK_VERSION))
{
  D3DPRESENT_PARAMETERS pp      = {0};

    pp.hDeviceWindow            = MainWnd;
    pp.BackBufferCount          = 1;
    pp.BackBufferWidth          = ScreenW;
    pp.BackBufferHeight         = ScreenH;
    pp.BackBufferFormat         = D3DFMT_X8R8G8B8;
    pp.SwapEffect               = D3DSWAPEFFECT_DISCARD;
    pp.PresentationInterval     = VertSnc?D3DPRESENT_INTERVAL_ONE:D3DPRESENT_INTERVAL_IMMEDIATE;
    pp.Windowed                 = FALSE; // FALSE works, TRUE doesn't, I don't know why.

    if (D3D->CreateDevice(NULL, D3DDEVTYPE_HAL, MainWnd, D3DCREATE_MULTITHREADED | D3DCREATE_HARDWARE_VERTEXPROCESSING, &pp, &Gfx) != D3D_OK || Gfx->GetRenderTarget(0, &BkB) != D3D_OK)
    {
      D3D->Release();

      return false;
    }
Advertisement

Create a new window each time
The same usually happens in X11 on Linux because it's really hard to keep track of all the hidden side-effects that are changed in the background. Simply tweaking until it works on your computer would be a terrible idea, so a workaround is to create a new backend window every time you toggle fullscreen on and off. You can keep the frontend window's handle in your engine's API to hide that the actual window is being replaced under the hood.

Borderless window fullscreen
Unless you're using a thick CRT monitor, native resolution change isn't really a thing anymore. It's all emulated on the GPU by graphics drivers (while totally breaking your desktop icons and the timing of V-sync) or the display's signal processor (which doesn't support any resolution on the signal processor). If you can't change the resolution to make it faster anymore, you might as well just use a borderless window stretched to fit the screen to be a lot more future proof than telling the display exactly how to do its job. We honestly have no idea if displays will even have v-sync in a few years.

Oh, I might have failed to clarify, I'm not talking about toggling, I mean changing the mode upon first creation, stays the same throughout, no toggling at all. But thanks anyway, your answer may come in handy for someone else who is looking for that and stumbles upon my question. :-)

What do you mean by "real fullscreen" and "fullscreen window"?

Did the values for ScreenW and ScreenH come from EnumAdapterModes?

Real fullscreen means setting the .Windowed parameter to FALSE and setting any available resolution, which works perfectly. Fullscreen window means setting the .Windowed parameter to TRUE, making the window cover the entire screen at the current desktop resolution and creating a backbuffer matching the window size. You could call a fullscreen window fake fullscreen. Any different resolution would be emulated with a render target of an appropriate size, which then is rendered to cover the entire backbuffer.

This topic is closed to new replies.

Advertisement