我正在尝试创建一个充满屏幕的无边框窗口 http://pcgamingwiki.com/wiki/Glossary%3aBorderless_fullscreen_windowed带有 OpenGL 视口。问题是,当我将窗口和视口设置为与桌面大小相同时,窗口在失去和获得焦点、退出和创建时会闪烁黑色。这可能与 Windows 将窗口设置为某种真正的“全屏”模式有关。这似乎不会发生在使用这种类型的无边框全屏窗口的其他应用程序(DirectX?)中。
我相信SFML 有这个问题的一个变体 http://en.sfml-dev.org/forums/index.php?topic=12002.0.
有一个解决方法:不要将窗口设置为桌面的确切大小。例如,使窗口的宽度比桌面的宽度多一个像素。
Below is an SSCCE http://www.sscce.org/ without error checking that shows what I'm talking about. This will create a borderless fullscreen window with a desktop-sized OpenGL viewport displaying an ugly green color (exit with AltF4). You can change the line #define FIX_BUG 0
to #define FIX_BUG 1
which just adds one extra pixel to the window's width to see what the behavior I want looks like.
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#pragma comment(lib, "OpenGL32.lib")
#define FIX_BUG 0
void MyRegisterClass(HINSTANCE hInstance);
HWND MyCreateWindow(HINSTANCE hInstance);
void MySetupOpenGLContext(HWND hWnd);
void MySetPixelFormat(HDC hDC);
RECT MyGetDesktopRect();
void MyLoadOpenGLFunctions();
#define APIENTRYP APIENTRY *
#define GLAPI extern
#define GL_COLOR 0x1800
typedef int GLint;
typedef int GLsizei;
typedef unsigned int GLenum;
typedef float GLfloat;
typedef void (APIENTRYP PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
PFNGLVIEWPORTPROC glViewport;
typedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat *value);
PFNGLCLEARBUFFERFVPROC glClearBufferfv;
static const char *windowClass = "CLASS";
static const char *windowTitle = "TITLE";
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {
MyRegisterClass(hInstance);
const HWND hWnd = MyCreateWindow(hInstance);
MySetupOpenGLContext(hWnd);
ShowWindow(hWnd, nCmdShow);
HDC hDC = GetDC(hWnd);
MSG msg;
while (IsWindow(hWnd)) {
while (PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
const GLfloat color[] = {0.5f, 0.5f, 0.0f, 1.0f};
glClearBufferfv(GL_COLOR, 0, color);
SwapBuffers(hDC);
}
return 0;
}
void MyRegisterClass(HINSTANCE hInstance) {
WNDCLASSEX wcex = {0};
wcex.cbSize = sizeof wcex;
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wcex.lpfnWndProc = &DefWindowProc;
wcex.hInstance = hInstance;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH) (COLOR_WINDOWFRAME + 1);
wcex.lpszClassName = windowClass;
RegisterClassEx(&wcex);
}
HWND MyCreateWindow(HINSTANCE hInstance) {
RECT dRect = MyGetDesktopRect();
return CreateWindow(windowClass, windowTitle, WS_POPUP,
0, 0, dRect.right + FIX_BUG, dRect.bottom,
NULL, NULL, hInstance, NULL);
}
void MySetupOpenGLContext(HWND hWnd) {
HDC hDC = GetDC(hWnd);
MySetPixelFormat(hDC);
HGLRC hGLRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hGLRC);
MyLoadOpenGLFunctions();
RECT dRect = MyGetDesktopRect();
glViewport(0, 0, dRect.right, dRect.bottom);
}
void MySetPixelFormat(HDC hDC) {
PIXELFORMATDESCRIPTOR pfd = {0};
pfd.nSize = sizeof pfd;
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 24;
pfd.cStencilBits = 8;
pfd.iLayerType = PFD_MAIN_PLANE;
int format = ChoosePixelFormat(hDC, &pfd);
SetPixelFormat(hDC, format, &pfd);
}
RECT MyGetDesktopRect() {
RECT desktopRect;
const HWND hDesktop = GetDesktopWindow();
GetWindowRect(hDesktop, &desktopRect);
return desktopRect;
}
void MyLoadOpenGLFunctions() {
glViewport = (PFNGLVIEWPORTPROC) GetProcAddress(GetModuleHandleA("OpenGL32.dll"), "glViewport");
glClearBufferfv = (PFNGLCLEARBUFFERFVPROC) wglGetProcAddress("glClearBufferfv");
}
Github 要点 https://gist.github.com/matteckert/11016920#file-glborderless-cpp | Raw Text https://gist.githubusercontent.com/matteckert/11016920/raw/7f5770e2f436142965fde716f21bffb4a5f5c80c/glborderless.cpp
为什么会发生这种情况?有没有办法将窗口设置为桌面的确切大小来获得我想要的行为?
我的平台:Visual Studio 2013 / 64位Windows 8 / AMD Radeon HD6850。