拥有一个带有小型触摸屏和大显示屏的信息亭系统,我有一个可以在大屏幕上播放视频的应用程序。出于某种原因,当Direct3D停止(应用程序退出)时,两个屏幕都会闪烁(变黑,然后恢复)。
我将问题简化为只打开焦点窗口的程序,初始化Direct3D设备,然后释放它。在释放(或停止程序而不释放)时,两个屏幕都会闪烁。
熟悉Direct3D的人是否可以看到这个并告诉我,我是否做错了什么?
#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;
}
注意:此程序应在同一视频卡上有2个屏幕的任何设置上运行,但可能需要调整第二个屏幕的宽度/高度(它在BackBufferWidth
中进行了硬编码和BackBufferHeight
)
答案 0 :(得分:1)
不确定这对你是否可行,但在试图围绕互联网的各种例子时,似乎避免闪烁的唯一方法是使用带无边框窗口的窗口模式:
...
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;