How do I stop Direct3D from flickering on release when setting up multiple titles?

You have a kiosk system with a small touchscreen and a large display, and I have an app that plays videos well on a large display. For some reason, when Direct3D stops (the application exits), both screens flicker (black out and then recover).

I've simplified the problem to a program that simply opens the focus window, initializes the Direct3D device, and then frees it up. When released (or stopped without releasing), both screens flicker.

Can anyone familiar with Direct3D look at this and tell me that I am doing something wrong?

#include <iostream>
#include <windows.h>
#include <d3d9.h>

const char g_szClassName[] = "myWindowClass";

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_CLOSE:
        DestroyWindow(hwnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {

    WNDCLASSEX wc;

    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = 0;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    if (!RegisterClassEx(&wc)) {
        MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    HWND hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        g_szClassName,
        "Focus Window",
        WS_POPUP | WS_VISIBLE,
        CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
        NULL, NULL, hInstance, NULL);

    if (hwnd == NULL) {
        MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    IDirect3D9* m_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
    if (m_pD3D == NULL) {
        MessageBox(NULL, "Failed to initialize direct3D!", "Error!", MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // second display is 1920 x 1080

    D3DPRESENT_PARAMETERS m_param;
    ZeroMemory(&m_param, sizeof(m_param));
    m_param.BackBufferWidth = 1920;
    m_param.BackBufferHeight = 1080;
    m_param.BackBufferFormat = D3DFMT_X8R8G8B8;
    m_param.BackBufferCount = 1;
    m_param.MultiSampleType = D3DMULTISAMPLE_NONE;
    m_param.SwapEffect = D3DSWAPEFFECT_COPY;
    m_param.hDeviceWindow = hwnd;
    m_param.Windowed = FALSE;
    m_param.Flags = D3DPRESENTFLAG_VIDEO;
    m_param.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
    m_param.PresentationInterval = D3DPRESENT_INTERVAL_ONE;

    HRESULT hr;
    IDirect3DDevice9* m_pD3DD;
    hr = m_pD3D->CreateDevice(
        1,
        D3DDEVTYPE_HAL,
        hwnd,
        D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED,
        &m_param,
        &m_pD3DD
    );

    if (hr != S_OK) {
        MessageBox(NULL, "Failed to create direct3D device!", "Error!", MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    Sleep(3000);

    // flicker occurs here
    m_pD3DD->Release();
    m_pD3D->Release();

    return 0;

}

      

NOTE. This program should run on any setup with two screens on one video card, but may need to adjust the width / height of the second screen (it is hardcoded into BackBufferWidth

and BackBufferHeight

)

+3


source to share


1 answer


Not sure if this is doable for you, but trying various examples around firewalls it seems the only way to avoid flicker is to use windowed mode with a borderless window:



...

HWND hwnd = CreateWindowEx(
    0,
    g_szClassName,
    "Focus Window",
    WS_POPUP | WS_VISIBLE, // <-- borderless window
    800, 0,                // <-- position on 2nd screen
    1920, 1080,            // <-- fill entire 2nd screen
    NULL, NULL, hInstance, NULL);

...

D3DPRESENT_PARAMETERS m_param;
ZeroMemory(&m_param, sizeof(m_param));
m_param.BackBufferWidth = 1920;
m_param.BackBufferHeight = 1080;
m_param.BackBufferFormat = D3DFMT_X8R8G8B8;
m_param.BackBufferCount = 1;
m_param.MultiSampleType = D3DMULTISAMPLE_NONE;
m_param.SwapEffect = D3DSWAPEFFECT_COPY;
m_param.hDeviceWindow = hwnd;
m_param.Windowed = TRUE;   // <-- use windowed mode
m_param.Flags = D3DPRESENTFLAG_VIDEO;
m_param.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
m_param.PresentationInterval = D3DPRESENT_INTERVAL_ONE;

      

+1


source







All Articles