From 52102f3d4a744c1bedacb5cef6dc6e49b441a3af Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 24 Jun 2018 20:11:08 +0200 Subject: [PATCH 1/7] - moved the Win32GLVideo class to its own file. This and SystemFrameBuffer need splitting up to support both Vulkan and OpenGL --- src/win32/gl_sysfb.h | 3 + src/win32/win32gliface.cpp | 578 +------------------------------------ src/win32/win32glvideo.h | 42 +++ src/win32/win32video.cpp | 565 +++++++++++++++++++++++++++++++++++- 4 files changed, 605 insertions(+), 583 deletions(-) create mode 100644 src/win32/win32glvideo.h diff --git a/src/win32/gl_sysfb.h b/src/win32/gl_sysfb.h index 34dfeac423..b1c862d275 100644 --- a/src/win32/gl_sysfb.h +++ b/src/win32/gl_sysfb.h @@ -30,6 +30,9 @@ public: protected: + void GetCenteredPos(int in_w, int in_h, int &winx, int &winy, int &winw, int &winh, int &scrwidth, int &scrheight); + void KeepWindowOnScreen(int &winx, int &winy, int winw, int winh, int scrwidth, int scrheight); + void PositionWindow(bool fullscreen); void ResetGammaTable(); diff --git a/src/win32/win32gliface.cpp b/src/win32/win32gliface.cpp index c8fc87ffbd..06a48f4da6 100644 --- a/src/win32/win32gliface.cpp +++ b/src/win32/win32gliface.cpp @@ -50,6 +50,7 @@ #include "v_text.h" #include "m_argv.h" #include "doomerrors.h" +#include "win32glvideo.h" #include "gl/renderer/gl_renderer.h" #include "gl/system/gl_framebuffer.h" @@ -61,9 +62,6 @@ extern "C" { __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; } -// these get used before GLEW is initialized so we have to use separate pointers with different names -PFNWGLCHOOSEPIXELFORMATARBPROC myWglChoosePixelFormatARB; // = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); -PFNWGLCREATECONTEXTATTRIBSARBPROC myWglCreateContextAttribsARB; PFNWGLSWAPINTERVALEXTPROC myWglSwapIntervalExtProc; CVAR(Int, vid_adapter, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) @@ -74,11 +72,6 @@ CVAR(Int, win_w, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Int, win_h, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Bool, win_maximized, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -CUSTOM_CVAR(Bool, gl_debug, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) -{ - Printf("This won't take effect until " GAMENAME " is restarted.\n"); -} - // For broadest GL compatibility, require user to explicitly enable quad-buffered stereo mode. // Setting vr_enable_quadbuffered_stereo does not automatically invoke quad-buffered stereo, // but makes it possible for subsequent "vr_mode 7" to invoke quad-buffered stereo @@ -89,575 +82,6 @@ CUSTOM_CVAR(Bool, vr_enable_quadbuffered, false, CVAR_ARCHIVE | CVAR_GLOBALCONFI EXTERN_CVAR(Int, vid_defwidth) EXTERN_CVAR(Int, vid_defheight) -EXTERN_CVAR(Int, vid_adapter) -EXTERN_CVAR(Bool, fullscreen) - - -//========================================================================== -// -// -// -//========================================================================== - -class Win32GLVideo : public IVideo -{ -public: - Win32GLVideo(int parm); - virtual ~Win32GLVideo(); - - DFrameBuffer *CreateFrameBuffer (); - void DumpAdapters(); - bool InitHardware(HWND Window, int multisample); - void Shutdown(); - - HDC m_hDC; - -protected: - HMODULE hmRender; - - char m_DisplayDeviceBuffer[CCHDEVICENAME]; - char *m_DisplayDeviceName; - HMONITOR m_hMonitor; - - HWND m_Window; - HGLRC m_hRC; - - HWND InitDummy(); - void ShutdownDummy(HWND dummy); - bool SetPixelFormat(); - bool SetupPixelFormat(int multisample); - - void GetDisplayDeviceName(); -public: - -}; - -//========================================================================== -// -// -// -//========================================================================== - -Win32GLVideo::Win32GLVideo(int parm) -{ - I_SetWndProc(); - - GetDisplayDeviceName(); - SetPixelFormat(); - -} - -//========================================================================== -// -// -// -//========================================================================== - -Win32GLVideo::~Win32GLVideo() -{ -} - -//========================================================================== -// -// -// -//========================================================================== - -struct MonitorEnumState -{ - int curIdx; - HMONITOR hFoundMonitor; -}; - -static BOOL CALLBACK GetDisplayDeviceNameMonitorEnumProc(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData) -{ - MonitorEnumState *state = reinterpret_cast(dwData); - - MONITORINFOEX mi; - mi.cbSize = sizeof mi; - GetMonitorInfo(hMonitor, &mi); - - // This assumes the monitors are returned by EnumDisplayMonitors in the - // order they're found in the Direct3D9 adapters list. Fingers crossed... - if (state->curIdx == vid_adapter) - { - state->hFoundMonitor = hMonitor; - - // Don't stop enumeration; this makes EnumDisplayMonitors fail. I like - // proper fails. - } - - ++state->curIdx; - - return TRUE; -} - -//========================================================================== -// -// -// -//========================================================================== - -void Win32GLVideo::GetDisplayDeviceName() -{ - // If anything goes wrong, anything at all, everything uses the primary - // monitor. - m_DisplayDeviceName = 0; - m_hMonitor = 0; - - MonitorEnumState mes; - - mes.curIdx = 1; - mes.hFoundMonitor = 0; - - // Could also use EnumDisplayDevices, I guess. That might work. - if (EnumDisplayMonitors(0, 0, &GetDisplayDeviceNameMonitorEnumProc, LPARAM(&mes))) - { - if (mes.hFoundMonitor) - { - MONITORINFOEX mi; - - mi.cbSize = sizeof mi; - - if (GetMonitorInfo(mes.hFoundMonitor, &mi)) - { - strcpy(m_DisplayDeviceBuffer, mi.szDevice); - m_DisplayDeviceName = m_DisplayDeviceBuffer; - - m_hMonitor = mes.hFoundMonitor; - } - } - } -} - -//========================================================================== -// -// -// -//========================================================================== - -DFrameBuffer *Win32GLVideo::CreateFrameBuffer() -{ - SystemFrameBuffer *fb; - - fb = new OpenGLFrameBuffer(m_hMonitor, fullscreen); - return fb; -} - -//========================================================================== -// -// -// -//========================================================================== - -struct DumpAdaptersState -{ - unsigned index; - char *displayDeviceName; -}; - -static BOOL CALLBACK DumpAdaptersMonitorEnumProc(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData) -{ - DumpAdaptersState *state = reinterpret_cast(dwData); - - MONITORINFOEX mi; - mi.cbSize=sizeof mi; - - char moreinfo[64] = ""; - - bool active = true; - - if (GetMonitorInfo(hMonitor, &mi)) - { - bool primary = !!(mi.dwFlags & MONITORINFOF_PRIMARY); - - mysnprintf(moreinfo, countof(moreinfo), " [%ldx%ld @ (%ld,%ld)]%s", - mi.rcMonitor.right - mi.rcMonitor.left, - mi.rcMonitor.bottom - mi.rcMonitor.top, - mi.rcMonitor.left, mi.rcMonitor.top, - primary ? " (Primary)" : ""); - - if (!state->displayDeviceName && !primary) - active = false;//primary selected, but this ain't primary - else if (state->displayDeviceName && strcmp(state->displayDeviceName, mi.szDevice) != 0) - active = false;//this isn't the selected one - } - - Printf("%s%u. %s\n", - active ? TEXTCOLOR_BOLD : "", - state->index, - moreinfo); - - ++state->index; - - return TRUE; -} - -//========================================================================== -// -// -// -//========================================================================== - -void Win32GLVideo::DumpAdapters() -{ - DumpAdaptersState das; - - das.index = 1; - das.displayDeviceName = m_DisplayDeviceName; - - EnumDisplayMonitors(0, 0, DumpAdaptersMonitorEnumProc, LPARAM(&das)); -} - -//========================================================================== -// -// -// -//========================================================================== - -HWND Win32GLVideo::InitDummy() -{ - HMODULE g_hInst = GetModuleHandle(NULL); - HWND dummy; - //Create a rect structure for the size/position of the window - RECT windowRect; - windowRect.left = 0; - windowRect.right = 64; - windowRect.top = 0; - windowRect.bottom = 64; - - //Window class structure - WNDCLASS wc; - - //Fill in window class struct - wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; - wc.lpfnWndProc = (WNDPROC) DefWindowProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = g_hInst; - wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = NULL; - wc.lpszMenuName = NULL; - wc.lpszClassName = "GZDoomOpenGLDummyWindow"; - - //Register window class - if(!RegisterClass(&wc)) - { - return 0; - } - - //Set window style & extended style - DWORD style, exStyle; - exStyle = WS_EX_CLIENTEDGE; - style = WS_SYSMENU | WS_BORDER | WS_CAPTION;// | WS_VISIBLE; - - //Adjust the window size so that client area is the size requested - AdjustWindowRectEx(&windowRect, style, false, exStyle); - - //Create Window - if(!(dummy = CreateWindowEx(exStyle, - "GZDoomOpenGLDummyWindow", - "GZDOOM", - WS_CLIPSIBLINGS | WS_CLIPCHILDREN | style, - 0, 0, - windowRect.right-windowRect.left, - windowRect.bottom-windowRect.top, - NULL, NULL, - g_hInst, - NULL))) - { - UnregisterClass("GZDoomOpenGLDummyWindow", g_hInst); - return 0; - } - ShowWindow(dummy, SW_HIDE); - - return dummy; -} - -//========================================================================== -// -// -// -//========================================================================== - -void Win32GLVideo::ShutdownDummy(HWND dummy) -{ - DestroyWindow(dummy); - UnregisterClass("GZDoomOpenGLDummyWindow", GetModuleHandle(NULL)); -} - - -//========================================================================== -// -// -// -//========================================================================== - -bool Win32GLVideo::SetPixelFormat() -{ - HDC hDC; - HGLRC hRC; - HWND dummy; - - PIXELFORMATDESCRIPTOR pfd = { - sizeof(PIXELFORMATDESCRIPTOR), - 1, - PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, - PFD_TYPE_RGBA, - 32, // color depth - 0, 0, 0, 0, 0, 0, - 0, - 0, - 0, - 0, 0, 0, 0, - 16, // z depth - 0, // stencil buffer - 0, - PFD_MAIN_PLANE, - 0, - 0, 0, 0 - }; - - int pixelFormat; - - // we have to create a dummy window to init stuff from or the full init stuff fails - dummy = InitDummy(); - - hDC = GetDC(dummy); - pixelFormat = ChoosePixelFormat(hDC, &pfd); - DescribePixelFormat(hDC, pixelFormat, sizeof(pfd), &pfd); - - ::SetPixelFormat(hDC, pixelFormat, &pfd); - - hRC = wglCreateContext(hDC); - wglMakeCurrent(hDC, hRC); - - myWglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); - myWglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB"); - // any extra stuff here? - - wglMakeCurrent(NULL, NULL); - wglDeleteContext(hRC); - ReleaseDC(dummy, hDC); - ShutdownDummy(dummy); - - return true; -} - -//========================================================================== -// -// -// -//========================================================================== - -bool Win32GLVideo::SetupPixelFormat(int multisample) -{ - int i; - int colorDepth; - HDC deskDC; - int attributes[28]; - int pixelFormat; - unsigned int numFormats; - float attribsFloat[] = {0.0f, 0.0f}; - - deskDC = GetDC(GetDesktopWindow()); - colorDepth = GetDeviceCaps(deskDC, BITSPIXEL); - ReleaseDC(GetDesktopWindow(), deskDC); - - if (myWglChoosePixelFormatARB) - { - again: - attributes[0] = WGL_RED_BITS_ARB; //bits - attributes[1] = 8; - attributes[2] = WGL_GREEN_BITS_ARB; //bits - attributes[3] = 8; - attributes[4] = WGL_BLUE_BITS_ARB; //bits - attributes[5] = 8; - attributes[6] = WGL_ALPHA_BITS_ARB; - attributes[7] = 8; - attributes[8] = WGL_DEPTH_BITS_ARB; - attributes[9] = 24; - attributes[10] = WGL_STENCIL_BITS_ARB; - attributes[11] = 8; - - attributes[12] = WGL_DRAW_TO_WINDOW_ARB; //required to be true - attributes[13] = true; - attributes[14] = WGL_SUPPORT_OPENGL_ARB; - attributes[15] = true; - attributes[16] = WGL_DOUBLE_BUFFER_ARB; - attributes[17] = true; - - if (multisample > 0) - { - attributes[18] = WGL_SAMPLE_BUFFERS_ARB; - attributes[19] = true; - attributes[20] = WGL_SAMPLES_ARB; - attributes[21] = multisample; - i = 22; - } - else - { - i = 18; - } - - attributes[i++] = WGL_ACCELERATION_ARB; //required to be FULL_ACCELERATION_ARB - attributes[i++] = WGL_FULL_ACCELERATION_ARB; - - if (vr_enable_quadbuffered) - { - // [BB] Starting with driver version 314.07, NVIDIA GeForce cards support OpenGL quad buffered - // stereo rendering with 3D Vision hardware. Select the corresponding attribute here. - attributes[i++] = WGL_STEREO_ARB; - attributes[i++] = true; - } - - attributes[i++] = 0; - attributes[i++] = 0; - - if (!myWglChoosePixelFormatARB(m_hDC, attributes, attribsFloat, 1, &pixelFormat, &numFormats)) - { - Printf("R_OPENGL: Couldn't choose pixel format. Retrying in compatibility mode\n"); - goto oldmethod; - } - - if (numFormats == 0) - { - if (vr_enable_quadbuffered) - { - Printf("R_OPENGL: No valid pixel formats found for VR quadbuffering. Retrying without this feature\n"); - vr_enable_quadbuffered = false; - goto again; - } - Printf("R_OPENGL: No valid pixel formats found. Retrying in compatibility mode\n"); - goto oldmethod; - } - } - else - { - oldmethod: - // If wglChoosePixelFormatARB is not found we have to do it the old fashioned way. - static PIXELFORMATDESCRIPTOR pfd = { - sizeof(PIXELFORMATDESCRIPTOR), - 1, - PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, - PFD_TYPE_RGBA, - 32, // color depth - 0, 0, 0, 0, 0, 0, - 0, - 0, - 0, - 0, 0, 0, 0, - 32, // z depth - 8, // stencil buffer - 0, - PFD_MAIN_PLANE, - 0, - 0, 0, 0 - }; - - pixelFormat = ChoosePixelFormat(m_hDC, &pfd); - DescribePixelFormat(m_hDC, pixelFormat, sizeof(pfd), &pfd); - - if (pfd.dwFlags & PFD_GENERIC_FORMAT) - { - I_Error("R_OPENGL: OpenGL driver not accelerated!"); - return false; - } - } - - if (!::SetPixelFormat(m_hDC, pixelFormat, NULL)) - { - I_Error("R_OPENGL: Couldn't set pixel format.\n"); - return false; - } - return true; -} - -//========================================================================== -// -// -// -//========================================================================== - -bool Win32GLVideo::InitHardware (HWND Window, int multisample) -{ - m_Window=Window; - m_hDC = GetDC(Window); - - if (!SetupPixelFormat(multisample)) - { - return false; - } - - int prof = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; - const char *version = Args->CheckValue("-glversion"); - - if (version != nullptr && strtod(version, nullptr) < 3.0) prof = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; - - for (; prof <= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; prof++) - { - m_hRC = NULL; - if (myWglCreateContextAttribsARB != NULL) - { - // let's try to get the best version possible. Some drivers only give us the version we request - // which breaks all version checks for feature support. The highest used features we use are from version 4.4, and 3.0 is a requirement. - static int versions[] = { 46, 45, 44, 43, 42, 41, 40, 33, 32, 31, 30, -1 }; - - for (int i = 0; versions[i] > 0; i++) - { - int ctxAttribs[] = { - WGL_CONTEXT_MAJOR_VERSION_ARB, versions[i] / 10, - WGL_CONTEXT_MINOR_VERSION_ARB, versions[i] % 10, - WGL_CONTEXT_FLAGS_ARB, gl_debug ? WGL_CONTEXT_DEBUG_BIT_ARB : 0, - WGL_CONTEXT_PROFILE_MASK_ARB, prof, - 0 - }; - - m_hRC = myWglCreateContextAttribsARB(m_hDC, 0, ctxAttribs); - if (m_hRC != NULL) break; - } - } - - if (m_hRC == NULL && prof == WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB) - { - m_hRC = wglCreateContext(m_hDC); - if (m_hRC == NULL) - { - I_Error("R_OPENGL: Unable to create an OpenGL render context.\n"); - return false; - } - } - - if (m_hRC != NULL) - { - wglMakeCurrent(m_hDC, m_hRC); - return true; - } - } - // We get here if the driver doesn't support the modern context creation API which always means an old driver. - I_Error ("R_OPENGL: Unable to create an OpenGL render context. Insufficient driver support for context creation\n"); - return false; -} - -//========================================================================== -// -// -// -//========================================================================== - -void Win32GLVideo::Shutdown() -{ - if (m_hRC) - { - wglMakeCurrent(0, 0); - wglDeleteContext(m_hRC); - } - if (m_hDC) ReleaseDC(m_Window, m_hDC); -} - - - //========================================================================== diff --git a/src/win32/win32glvideo.h b/src/win32/win32glvideo.h new file mode 100644 index 0000000000..cb54a1e22a --- /dev/null +++ b/src/win32/win32glvideo.h @@ -0,0 +1,42 @@ +#pragma once + +#include "v_video.h" + +//========================================================================== +// +// +// +//========================================================================== + +class Win32GLVideo : public IVideo +{ +public: + Win32GLVideo(int parm); + virtual ~Win32GLVideo(); + + DFrameBuffer *CreateFrameBuffer(); + void DumpAdapters(); + bool InitHardware(HWND Window, int multisample); + void Shutdown(); + + HDC m_hDC; + +protected: + HMODULE hmRender; + + char m_DisplayDeviceBuffer[CCHDEVICENAME]; + char *m_DisplayDeviceName; + HMONITOR m_hMonitor; + + HWND m_Window; + HGLRC m_hRC; + + HWND InitDummy(); + void ShutdownDummy(HWND dummy); + bool SetPixelFormat(); + bool SetupPixelFormat(int multisample); + + void GetDisplayDeviceName(); +public: + +}; diff --git a/src/win32/win32video.cpp b/src/win32/win32video.cpp index 517c02c02e..4ed3bb5013 100644 --- a/src/win32/win32video.cpp +++ b/src/win32/win32video.cpp @@ -32,13 +32,566 @@ ** */ -#define _WIN32_WINNT 0x0501 -#define WIN32_LEAN_AND_MEAN #include -#include +#include +#include "wglext.h" -// HEADER FILES ------------------------------------------------------------ - -#include "c_cvars.h" +#include "gl_sysfb.h" +#include "hardware.h" +#include "x86.h" +#include "templates.h" +#include "version.h" +#include "c_console.h" +#include "v_video.h" +#include "i_input.h" #include "i_system.h" +#include "doomstat.h" +#include "v_text.h" +#include "m_argv.h" +#include "doomerrors.h" +#include "win32glvideo.h" + +#include "gl/system/gl_framebuffer.h" + +EXTERN_CVAR(Int, vid_adapter) +EXTERN_CVAR(Bool, fullscreen) +EXTERN_CVAR(Bool, vr_enable_quadbuffered) + +CUSTOM_CVAR(Bool, gl_debug, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) +{ + Printf("This won't take effect until " GAMENAME " is restarted.\n"); +} + +// these get used before GLEW is initialized so we have to use separate pointers with different names +PFNWGLCHOOSEPIXELFORMATARBPROC myWglChoosePixelFormatARB; // = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); +PFNWGLCREATECONTEXTATTRIBSARBPROC myWglCreateContextAttribsARB; + + +//========================================================================== +// +// +// +//========================================================================== + +Win32GLVideo::Win32GLVideo(int parm) +{ + I_SetWndProc(); + + GetDisplayDeviceName(); + SetPixelFormat(); + +} + +//========================================================================== +// +// +// +//========================================================================== + +Win32GLVideo::~Win32GLVideo() +{ +} + +//========================================================================== +// +// +// +//========================================================================== + +struct MonitorEnumState +{ + int curIdx; + HMONITOR hFoundMonitor; +}; + +static BOOL CALLBACK GetDisplayDeviceNameMonitorEnumProc(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData) +{ + MonitorEnumState *state = reinterpret_cast(dwData); + + MONITORINFOEX mi; + mi.cbSize = sizeof mi; + GetMonitorInfo(hMonitor, &mi); + + // This assumes the monitors are returned by EnumDisplayMonitors in the + // order they're found in the Direct3D9 adapters list. Fingers crossed... + if (state->curIdx == vid_adapter) + { + state->hFoundMonitor = hMonitor; + + // Don't stop enumeration; this makes EnumDisplayMonitors fail. I like + // proper fails. + } + + ++state->curIdx; + + return TRUE; +} + +//========================================================================== +// +// +// +//========================================================================== + +void Win32GLVideo::GetDisplayDeviceName() +{ + // If anything goes wrong, anything at all, everything uses the primary + // monitor. + m_DisplayDeviceName = 0; + m_hMonitor = 0; + + MonitorEnumState mes; + + mes.curIdx = 1; + mes.hFoundMonitor = 0; + + // Could also use EnumDisplayDevices, I guess. That might work. + if (EnumDisplayMonitors(0, 0, &GetDisplayDeviceNameMonitorEnumProc, LPARAM(&mes))) + { + if (mes.hFoundMonitor) + { + MONITORINFOEX mi; + + mi.cbSize = sizeof mi; + + if (GetMonitorInfo(mes.hFoundMonitor, &mi)) + { + strcpy(m_DisplayDeviceBuffer, mi.szDevice); + m_DisplayDeviceName = m_DisplayDeviceBuffer; + + m_hMonitor = mes.hFoundMonitor; + } + } + } +} + +//========================================================================== +// +// +// +//========================================================================== + +DFrameBuffer *Win32GLVideo::CreateFrameBuffer() +{ + SystemFrameBuffer *fb; + + fb = new OpenGLFrameBuffer(m_hMonitor, fullscreen); + return fb; +} + +//========================================================================== +// +// +// +//========================================================================== + +struct DumpAdaptersState +{ + unsigned index; + char *displayDeviceName; +}; + +static BOOL CALLBACK DumpAdaptersMonitorEnumProc(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData) +{ + DumpAdaptersState *state = reinterpret_cast(dwData); + + MONITORINFOEX mi; + mi.cbSize = sizeof mi; + + char moreinfo[64] = ""; + + bool active = true; + + if (GetMonitorInfo(hMonitor, &mi)) + { + bool primary = !!(mi.dwFlags & MONITORINFOF_PRIMARY); + + mysnprintf(moreinfo, countof(moreinfo), " [%ldx%ld @ (%ld,%ld)]%s", + mi.rcMonitor.right - mi.rcMonitor.left, + mi.rcMonitor.bottom - mi.rcMonitor.top, + mi.rcMonitor.left, mi.rcMonitor.top, + primary ? " (Primary)" : ""); + + if (!state->displayDeviceName && !primary) + active = false;//primary selected, but this ain't primary + else if (state->displayDeviceName && strcmp(state->displayDeviceName, mi.szDevice) != 0) + active = false;//this isn't the selected one + } + + Printf("%s%u. %s\n", + active ? TEXTCOLOR_BOLD : "", + state->index, + moreinfo); + + ++state->index; + + return TRUE; +} + +//========================================================================== +// +// +// +//========================================================================== + +void Win32GLVideo::DumpAdapters() +{ + DumpAdaptersState das; + + das.index = 1; + das.displayDeviceName = m_DisplayDeviceName; + + EnumDisplayMonitors(0, 0, DumpAdaptersMonitorEnumProc, LPARAM(&das)); +} + +//========================================================================== +// +// +// +//========================================================================== + +HWND Win32GLVideo::InitDummy() +{ + HMODULE g_hInst = GetModuleHandle(NULL); + HWND dummy; + //Create a rect structure for the size/position of the window + RECT windowRect; + windowRect.left = 0; + windowRect.right = 64; + windowRect.top = 0; + windowRect.bottom = 64; + + //Window class structure + WNDCLASS wc; + + //Fill in window class struct + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + wc.lpfnWndProc = (WNDPROC)DefWindowProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = g_hInst; + wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + wc.lpszClassName = "GZDoomOpenGLDummyWindow"; + + //Register window class + if (!RegisterClass(&wc)) + { + return 0; + } + + //Set window style & extended style + DWORD style, exStyle; + exStyle = WS_EX_CLIENTEDGE; + style = WS_SYSMENU | WS_BORDER | WS_CAPTION;// | WS_VISIBLE; + + //Adjust the window size so that client area is the size requested + AdjustWindowRectEx(&windowRect, style, false, exStyle); + + //Create Window + if (!(dummy = CreateWindowEx(exStyle, + "GZDoomOpenGLDummyWindow", + "GZDOOM", + WS_CLIPSIBLINGS | WS_CLIPCHILDREN | style, + 0, 0, + windowRect.right - windowRect.left, + windowRect.bottom - windowRect.top, + NULL, NULL, + g_hInst, + NULL))) + { + UnregisterClass("GZDoomOpenGLDummyWindow", g_hInst); + return 0; + } + ShowWindow(dummy, SW_HIDE); + + return dummy; +} + +//========================================================================== +// +// +// +//========================================================================== + +void Win32GLVideo::ShutdownDummy(HWND dummy) +{ + DestroyWindow(dummy); + UnregisterClass("GZDoomOpenGLDummyWindow", GetModuleHandle(NULL)); +} + + +//========================================================================== +// +// +// +//========================================================================== + +bool Win32GLVideo::SetPixelFormat() +{ + HDC hDC; + HGLRC hRC; + HWND dummy; + + PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), + 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, + 32, // color depth + 0, 0, 0, 0, 0, 0, + 0, + 0, + 0, + 0, 0, 0, 0, + 16, // z depth + 0, // stencil buffer + 0, + PFD_MAIN_PLANE, + 0, + 0, 0, 0 + }; + + int pixelFormat; + + // we have to create a dummy window to init stuff from or the full init stuff fails + dummy = InitDummy(); + + hDC = GetDC(dummy); + pixelFormat = ChoosePixelFormat(hDC, &pfd); + DescribePixelFormat(hDC, pixelFormat, sizeof(pfd), &pfd); + + ::SetPixelFormat(hDC, pixelFormat, &pfd); + + hRC = wglCreateContext(hDC); + wglMakeCurrent(hDC, hRC); + + myWglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); + myWglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB"); + // any extra stuff here? + + wglMakeCurrent(NULL, NULL); + wglDeleteContext(hRC); + ReleaseDC(dummy, hDC); + ShutdownDummy(dummy); + + return true; +} + +//========================================================================== +// +// +// +//========================================================================== + +bool Win32GLVideo::SetupPixelFormat(int multisample) +{ + int i; + int colorDepth; + HDC deskDC; + int attributes[28]; + int pixelFormat; + unsigned int numFormats; + float attribsFloat[] = { 0.0f, 0.0f }; + + deskDC = GetDC(GetDesktopWindow()); + colorDepth = GetDeviceCaps(deskDC, BITSPIXEL); + ReleaseDC(GetDesktopWindow(), deskDC); + + if (myWglChoosePixelFormatARB) + { + again: + attributes[0] = WGL_RED_BITS_ARB; //bits + attributes[1] = 8; + attributes[2] = WGL_GREEN_BITS_ARB; //bits + attributes[3] = 8; + attributes[4] = WGL_BLUE_BITS_ARB; //bits + attributes[5] = 8; + attributes[6] = WGL_ALPHA_BITS_ARB; + attributes[7] = 8; + attributes[8] = WGL_DEPTH_BITS_ARB; + attributes[9] = 24; + attributes[10] = WGL_STENCIL_BITS_ARB; + attributes[11] = 8; + + attributes[12] = WGL_DRAW_TO_WINDOW_ARB; //required to be true + attributes[13] = true; + attributes[14] = WGL_SUPPORT_OPENGL_ARB; + attributes[15] = true; + attributes[16] = WGL_DOUBLE_BUFFER_ARB; + attributes[17] = true; + + if (multisample > 0) + { + attributes[18] = WGL_SAMPLE_BUFFERS_ARB; + attributes[19] = true; + attributes[20] = WGL_SAMPLES_ARB; + attributes[21] = multisample; + i = 22; + } + else + { + i = 18; + } + + attributes[i++] = WGL_ACCELERATION_ARB; //required to be FULL_ACCELERATION_ARB + attributes[i++] = WGL_FULL_ACCELERATION_ARB; + + if (vr_enable_quadbuffered) + { + // [BB] Starting with driver version 314.07, NVIDIA GeForce cards support OpenGL quad buffered + // stereo rendering with 3D Vision hardware. Select the corresponding attribute here. + attributes[i++] = WGL_STEREO_ARB; + attributes[i++] = true; + } + + attributes[i++] = 0; + attributes[i++] = 0; + + if (!myWglChoosePixelFormatARB(m_hDC, attributes, attribsFloat, 1, &pixelFormat, &numFormats)) + { + Printf("R_OPENGL: Couldn't choose pixel format. Retrying in compatibility mode\n"); + goto oldmethod; + } + + if (numFormats == 0) + { + if (vr_enable_quadbuffered) + { + Printf("R_OPENGL: No valid pixel formats found for VR quadbuffering. Retrying without this feature\n"); + vr_enable_quadbuffered = false; + goto again; + } + Printf("R_OPENGL: No valid pixel formats found. Retrying in compatibility mode\n"); + goto oldmethod; + } + } + else + { + oldmethod: + // If wglChoosePixelFormatARB is not found we have to do it the old fashioned way. + static PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), + 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, + 32, // color depth + 0, 0, 0, 0, 0, 0, + 0, + 0, + 0, + 0, 0, 0, 0, + 32, // z depth + 8, // stencil buffer + 0, + PFD_MAIN_PLANE, + 0, + 0, 0, 0 + }; + + pixelFormat = ChoosePixelFormat(m_hDC, &pfd); + DescribePixelFormat(m_hDC, pixelFormat, sizeof(pfd), &pfd); + + if (pfd.dwFlags & PFD_GENERIC_FORMAT) + { + I_Error("R_OPENGL: OpenGL driver not accelerated!"); + return false; + } + } + + if (!::SetPixelFormat(m_hDC, pixelFormat, NULL)) + { + I_Error("R_OPENGL: Couldn't set pixel format.\n"); + return false; + } + return true; +} + +//========================================================================== +// +// +// +//========================================================================== + +bool Win32GLVideo::InitHardware(HWND Window, int multisample) +{ + m_Window = Window; + m_hDC = GetDC(Window); + + if (!SetupPixelFormat(multisample)) + { + return false; + } + + int prof = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; + const char *version = Args->CheckValue("-glversion"); + + if (version != nullptr && strtod(version, nullptr) < 3.0) prof = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; + + for (; prof <= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; prof++) + { + m_hRC = NULL; + if (myWglCreateContextAttribsARB != NULL) + { + // let's try to get the best version possible. Some drivers only give us the version we request + // which breaks all version checks for feature support. The highest used features we use are from version 4.4, and 3.0 is a requirement. + static int versions[] = { 46, 45, 44, 43, 42, 41, 40, 33, 32, 31, 30, -1 }; + + for (int i = 0; versions[i] > 0; i++) + { + int ctxAttribs[] = { + WGL_CONTEXT_MAJOR_VERSION_ARB, versions[i] / 10, + WGL_CONTEXT_MINOR_VERSION_ARB, versions[i] % 10, + WGL_CONTEXT_FLAGS_ARB, gl_debug ? WGL_CONTEXT_DEBUG_BIT_ARB : 0, + WGL_CONTEXT_PROFILE_MASK_ARB, prof, + 0 + }; + + m_hRC = myWglCreateContextAttribsARB(m_hDC, 0, ctxAttribs); + if (m_hRC != NULL) break; + } + } + + if (m_hRC == NULL && prof == WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB) + { + m_hRC = wglCreateContext(m_hDC); + if (m_hRC == NULL) + { + I_Error("R_OPENGL: Unable to create an OpenGL render context.\n"); + return false; + } + } + + if (m_hRC != NULL) + { + wglMakeCurrent(m_hDC, m_hRC); + return true; + } + } + // We get here if the driver doesn't support the modern context creation API which always means an old driver. + I_Error("R_OPENGL: Unable to create an OpenGL render context. Insufficient driver support for context creation\n"); + return false; +} + +//========================================================================== +// +// +// +//========================================================================== + +void Win32GLVideo::Shutdown() +{ + if (m_hRC) + { + wglMakeCurrent(0, 0); + wglDeleteContext(m_hRC); + } + if (m_hDC) ReleaseDC(m_Window, m_hDC); +} + + + + From e7365be0d13973d307b91cef9143f8976829aedf Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 24 Jun 2018 20:16:30 +0200 Subject: [PATCH 2/7] - renamed SystemFrameBuffer to SystemGLFrameBuffer. ... because with Vulkan there needs to be some hint what API this is for. --- src/gl/system/gl_framebuffer.h | 4 +-- src/posix/cocoa/gl_sysfb.h | 8 +++--- src/posix/cocoa/i_video.mm | 48 +++++++++++++++++----------------- src/posix/sdl/gl_sysfb.h | 8 +++--- src/posix/sdl/sdlglvideo.cpp | 26 +++++++++--------- src/win32/gl_sysfb.h | 8 +++--- src/win32/win32gliface.cpp | 32 +++++++++++------------ src/win32/win32video.cpp | 2 +- 8 files changed, 68 insertions(+), 68 deletions(-) diff --git a/src/gl/system/gl_framebuffer.h b/src/gl/system/gl_framebuffer.h index dd002c9296..d7aa5760a0 100644 --- a/src/gl/system/gl_framebuffer.h +++ b/src/gl/system/gl_framebuffer.h @@ -9,9 +9,9 @@ class FHardwareTexture; class FSimpleVertexBuffer; class FGLDebug; -class OpenGLFrameBuffer : public SystemFrameBuffer +class OpenGLFrameBuffer : public SystemGLFrameBuffer { - typedef SystemFrameBuffer Super; + typedef SystemGLFrameBuffer Super; public: diff --git a/src/posix/cocoa/gl_sysfb.h b/src/posix/cocoa/gl_sysfb.h index 7eefa0fd9f..39c8f8ab44 100644 --- a/src/posix/cocoa/gl_sysfb.h +++ b/src/posix/cocoa/gl_sysfb.h @@ -44,12 +44,12 @@ typedef struct objc_object NSCursor; typedef struct objc_object CocoaWindow; #endif -class SystemFrameBuffer : public DFrameBuffer +class SystemGLFrameBuffer : public DFrameBuffer { public: // This must have the same parameters as the Windows version, even if they are not used! - SystemFrameBuffer(void *hMonitor, bool fullscreen); - ~SystemFrameBuffer(); + SystemGLFrameBuffer(void *hMonitor, bool fullscreen); + ~SystemGLFrameBuffer(); virtual bool IsFullscreen(); virtual void SetVSync(bool vsync); @@ -78,7 +78,7 @@ protected: bool m_supportsGamma; uint16_t m_originalGamma[GAMMA_TABLE_SIZE]; - SystemFrameBuffer() {} + SystemGLFrameBuffer() {} void SetFullscreenMode(); void SetWindowedMode(); diff --git a/src/posix/cocoa/i_video.mm b/src/posix/cocoa/i_video.mm index d44be138e9..9305e708f4 100644 --- a/src/posix/cocoa/i_video.mm +++ b/src/posix/cocoa/i_video.mm @@ -319,7 +319,7 @@ NSOpenGLPixelFormat* CreatePixelFormat(const NSOpenGLPixelFormatAttribute profil // --------------------------------------------------------------------------- -SystemFrameBuffer::SystemFrameBuffer(void*, const bool fullscreen) +SystemGLFrameBuffer::SystemGLFrameBuffer(void*, const bool fullscreen) : DFrameBuffer(vid_defwidth, vid_defheight) , m_window(CreateWindow(STYLE_MASK_WINDOWED)) , m_fullscreen(false) @@ -386,7 +386,7 @@ SystemFrameBuffer::SystemFrameBuffer(void*, const bool fullscreen) FConsoleWindow::GetInstance().Show(false); } -SystemFrameBuffer::~SystemFrameBuffer() +SystemGLFrameBuffer::~SystemGLFrameBuffer() { NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; [nc removeObserver:m_window @@ -397,18 +397,18 @@ SystemFrameBuffer::~SystemFrameBuffer() object:nil]; } -bool SystemFrameBuffer::IsFullscreen() +bool SystemGLFrameBuffer::IsFullscreen() { return m_fullscreen; } -void SystemFrameBuffer::ToggleFullscreen(bool yes) +void SystemGLFrameBuffer::ToggleFullscreen(bool yes) { SetMode(yes, m_hiDPI); } -void SystemFrameBuffer::SetVSync(bool vsync) +void SystemGLFrameBuffer::SetVSync(bool vsync) { const GLint value = vsync ? 1 : 0; @@ -417,16 +417,16 @@ void SystemFrameBuffer::SetVSync(bool vsync) } -void SystemFrameBuffer::InitializeState() +void SystemGLFrameBuffer::InitializeState() { } -void SystemFrameBuffer::SwapBuffers() +void SystemGLFrameBuffer::SwapBuffers() { [[NSOpenGLContext currentContext] flushBuffer]; } -void SystemFrameBuffer::SetGammaTable(uint16_t* table) +void SystemGLFrameBuffer::SetGammaTable(uint16_t* table) { if (m_supportsGamma) { @@ -442,7 +442,7 @@ void SystemFrameBuffer::SetGammaTable(uint16_t* table) } } -void SystemFrameBuffer::ResetGammaTable() +void SystemGLFrameBuffer::ResetGammaTable() { if (m_supportsGamma) { @@ -451,20 +451,20 @@ void SystemFrameBuffer::ResetGammaTable() } -int SystemFrameBuffer::GetClientWidth() +int SystemGLFrameBuffer::GetClientWidth() { const int clientWidth = I_GetContentViewSize(m_window).width; return clientWidth > 0 ? clientWidth : GetWidth(); } -int SystemFrameBuffer::GetClientHeight() +int SystemGLFrameBuffer::GetClientHeight() { const int clientHeight = I_GetContentViewSize(m_window).height; return clientHeight > 0 ? clientHeight : GetHeight(); } -void SystemFrameBuffer::SetFullscreenMode() +void SystemGLFrameBuffer::SetFullscreenMode() { if (!m_fullscreen) { @@ -478,7 +478,7 @@ void SystemFrameBuffer::SetFullscreenMode() [m_window setFrame:screenFrame display:YES]; } -void SystemFrameBuffer::SetWindowedMode() +void SystemGLFrameBuffer::SetWindowedMode() { if (m_fullscreen) { @@ -498,7 +498,7 @@ void SystemFrameBuffer::SetWindowedMode() [m_window exitAppOnClose]; } -void SystemFrameBuffer::SetMode(const bool fullscreen, const bool hiDPI) +void SystemGLFrameBuffer::SetMode(const bool fullscreen, const bool hiDPI) { NSOpenGLView* const glView = [m_window contentView]; [glView setWantsBestResolutionOpenGLSurface:hiDPI]; @@ -532,12 +532,12 @@ void SystemFrameBuffer::SetMode(const bool fullscreen, const bool hiDPI) } -static SystemFrameBuffer* GetSystemFrameBuffer() +static SystemGLFrameBuffer* GetSystemFrameBuffer() { - return static_cast(screen); + return static_cast(screen); } -void SystemFrameBuffer::UseHiDPI(const bool hiDPI) +void SystemGLFrameBuffer::UseHiDPI(const bool hiDPI) { if (auto fb = GetSystemFrameBuffer()) { @@ -545,7 +545,7 @@ void SystemFrameBuffer::UseHiDPI(const bool hiDPI) } } -void SystemFrameBuffer::SetCursor(NSCursor* cursor) +void SystemGLFrameBuffer::SetCursor(NSCursor* cursor) { if (auto fb = GetSystemFrameBuffer()) { @@ -557,7 +557,7 @@ void SystemFrameBuffer::SetCursor(NSCursor* cursor) } } -void SystemFrameBuffer::SetWindowVisible(bool visible) +void SystemGLFrameBuffer::SetWindowVisible(bool visible) { if (auto fb = GetSystemFrameBuffer()) { @@ -574,7 +574,7 @@ void SystemFrameBuffer::SetWindowVisible(bool visible) } } -void SystemFrameBuffer::SetWindowTitle(const char* title) +void SystemGLFrameBuffer::SetWindowTitle(const char* title) { if (auto fb = GetSystemFrameBuffer()) { @@ -627,7 +627,7 @@ void I_SetFPSLimit(int limit) CUSTOM_CVAR(Bool, vid_hidpi, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) { - SystemFrameBuffer::UseHiDPI(self); + SystemGLFrameBuffer::UseHiDPI(self); } @@ -688,7 +688,7 @@ bool I_SetCursor(FTexture* cursorpic) hotSpot:NSMakePoint(0.0f, 0.0f)]; } - SystemFrameBuffer::SetCursor(cursor); + SystemGLFrameBuffer::SetCursor(cursor); [pool release]; @@ -708,11 +708,11 @@ NSSize I_GetContentViewSize(const NSWindow* const window) void I_SetMainWindowVisible(bool visible) { - SystemFrameBuffer::SetWindowVisible(visible); + SystemGLFrameBuffer::SetWindowVisible(visible); } // each platform has its own specific version of this function. void I_SetWindowTitle(const char* title) { - SystemFrameBuffer::SetWindowTitle(title); + SystemGLFrameBuffer::SetWindowTitle(title); } diff --git a/src/posix/sdl/gl_sysfb.h b/src/posix/sdl/gl_sysfb.h index 6282b4e407..16f2171ce3 100644 --- a/src/posix/sdl/gl_sysfb.h +++ b/src/posix/sdl/gl_sysfb.h @@ -5,14 +5,14 @@ #include "v_video.h" -class SystemFrameBuffer : public DFrameBuffer +class SystemGLFrameBuffer : public DFrameBuffer { typedef DFrameBuffer Super; public: // this must have the same parameters as the Windows version, even if they are not used! - SystemFrameBuffer (void *hMonitor, bool fullscreen); - ~SystemFrameBuffer (); + SystemGLFrameBuffer (void *hMonitor, bool fullscreen); + ~SystemGLFrameBuffer (); void ForceBuffering (bool force); @@ -34,7 +34,7 @@ protected: void ResetGammaTable(); void InitializeState(); - SystemFrameBuffer () {} + SystemGLFrameBuffer () {} uint8_t GammaTable[3][256]; bool UpdatePending; diff --git a/src/posix/sdl/sdlglvideo.cpp b/src/posix/sdl/sdlglvideo.cpp index d6f495c6db..42c7a7c201 100644 --- a/src/posix/sdl/sdlglvideo.cpp +++ b/src/posix/sdl/sdlglvideo.cpp @@ -123,7 +123,7 @@ SDLGLVideo::~SDLGLVideo () DFrameBuffer *SDLGLVideo::CreateFrameBuffer () { - SystemFrameBuffer *fb = new OpenGLFrameBuffer(0, fullscreen); + SystemGLFrameBuffer *fb = new OpenGLFrameBuffer(0, fullscreen); return fb; } @@ -179,7 +179,7 @@ IVideo *gl_CreateVideo() // FrameBuffer implementation ----------------------------------------------- -SystemFrameBuffer::SystemFrameBuffer (void *, bool fullscreen) +SystemGLFrameBuffer::SystemGLFrameBuffer (void *, bool fullscreen) : DFrameBuffer (vid_defwidth, vid_defheight) { // NOTE: Core profiles were added with GL 3.2, so there's no sense trying @@ -257,7 +257,7 @@ SystemFrameBuffer::SystemFrameBuffer (void *, bool fullscreen) } } -SystemFrameBuffer::~SystemFrameBuffer () +SystemGLFrameBuffer::~SystemGLFrameBuffer () { if (Screen) { @@ -275,11 +275,11 @@ SystemFrameBuffer::~SystemFrameBuffer () -void SystemFrameBuffer::InitializeState() +void SystemGLFrameBuffer::InitializeState() { } -void SystemFrameBuffer::SetGammaTable(uint16_t *tbl) +void SystemGLFrameBuffer::SetGammaTable(uint16_t *tbl) { if (m_supportsGamma) { @@ -287,7 +287,7 @@ void SystemFrameBuffer::SetGammaTable(uint16_t *tbl) } } -void SystemFrameBuffer::ResetGammaTable() +void SystemGLFrameBuffer::ResetGammaTable() { if (m_supportsGamma) { @@ -295,12 +295,12 @@ void SystemFrameBuffer::ResetGammaTable() } } -bool SystemFrameBuffer::IsFullscreen () +bool SystemGLFrameBuffer::IsFullscreen () { return (SDL_GetWindowFlags (Screen) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0; } -void SystemFrameBuffer::SetVSync( bool vsync ) +void SystemGLFrameBuffer::SetVSync( bool vsync ) { #if defined (__APPLE__) const GLint value = vsync ? 1 : 0; @@ -318,7 +318,7 @@ void SystemFrameBuffer::SetVSync( bool vsync ) #endif } -void SystemFrameBuffer::SwapBuffers() +void SystemGLFrameBuffer::SwapBuffers() { #if !defined(__APPLE__) && !defined(__OpenBSD__) if (vid_maxfps && !cl_capfps) @@ -330,19 +330,19 @@ void SystemFrameBuffer::SwapBuffers() SDL_GL_SwapWindow (Screen); } -void SystemFrameBuffer::ToggleFullscreen(bool yes) +void SystemGLFrameBuffer::ToggleFullscreen(bool yes) { SDL_SetWindowFullscreen(Screen, yes ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); } -int SystemFrameBuffer::GetClientWidth() +int SystemGLFrameBuffer::GetClientWidth() { int width = 0; SDL_GL_GetDrawableSize(Screen, &width, nullptr); return width; } -int SystemFrameBuffer::GetClientHeight() +int SystemGLFrameBuffer::GetClientHeight() { int height = 0; SDL_GL_GetDrawableSize(Screen, nullptr, &height); @@ -388,7 +388,7 @@ void ProcessSDLWindowEvent(const SDL_WindowEvent &event) // each platform has its own specific version of this function. void I_SetWindowTitle(const char* caption) { - auto window = static_cast(screen)->GetSDLWindow(); + auto window = static_cast(screen)->GetSDLWindow(); if (caption) SDL_SetWindowTitle(window, caption); else diff --git a/src/win32/gl_sysfb.h b/src/win32/gl_sysfb.h index b1c862d275..fe098fcbd9 100644 --- a/src/win32/gl_sysfb.h +++ b/src/win32/gl_sysfb.h @@ -3,7 +3,7 @@ #include "v_video.h" -class SystemFrameBuffer : public DFrameBuffer +class SystemGLFrameBuffer : public DFrameBuffer { typedef DFrameBuffer Super; @@ -11,11 +11,11 @@ class SystemFrameBuffer : public DFrameBuffer void RestoreWindowedPos(); public: - SystemFrameBuffer() {} + SystemGLFrameBuffer() {} // Actually, hMonitor is a HMONITOR, but it's passed as a void * as there // look to be some cross-platform bits in the way. - SystemFrameBuffer(void *hMonitor, bool fullscreen); - virtual ~SystemFrameBuffer(); + SystemGLFrameBuffer(void *hMonitor, bool fullscreen); + virtual ~SystemGLFrameBuffer(); void SetVSync (bool vsync); void SwapBuffers(); diff --git a/src/win32/win32gliface.cpp b/src/win32/win32gliface.cpp index 06a48f4da6..ff814f8d1e 100644 --- a/src/win32/win32gliface.cpp +++ b/src/win32/win32gliface.cpp @@ -97,7 +97,7 @@ EXTERN_CVAR(Int, vid_defheight) // //========================================================================== -static void GetCenteredPos(int in_w, int in_h, int &winx, int &winy, int &winw, int &winh, int &scrwidth, int &scrheight) + void SystemGLFrameBuffer::GetCenteredPos(int in_w, int in_h, int &winx, int &winy, int &winw, int &winh, int &scrwidth, int &scrheight) { DEVMODE displaysettings; RECT rect; @@ -125,7 +125,7 @@ static void GetCenteredPos(int in_w, int in_h, int &winx, int &winy, int &winw, // //========================================================================== -static void KeepWindowOnScreen(int &winx, int &winy, int winw, int winh, int scrwidth, int scrheight) +void SystemGLFrameBuffer::KeepWindowOnScreen(int &winx, int &winy, int winw, int winh, int scrwidth, int scrheight) { // If the window is too large to fit entirely on the screen, at least // keep its upperleft corner visible. @@ -153,7 +153,7 @@ static void KeepWindowOnScreen(int &winx, int &winy, int winw, int winh, int scr // //========================================================================== -void SystemFrameBuffer::SaveWindowedPos() +void SystemGLFrameBuffer::SaveWindowedPos() { // Don't save if we were run with the -0 option. if (Args->CheckParm("-0")) @@ -204,7 +204,7 @@ void SystemFrameBuffer::SaveWindowedPos() // //========================================================================== -void SystemFrameBuffer::RestoreWindowedPos() +void SystemGLFrameBuffer::RestoreWindowedPos() { int winx, winy, winw, winh, scrwidth, scrheight; @@ -239,7 +239,7 @@ void SystemFrameBuffer::RestoreWindowedPos() // //========================================================================== -void SystemFrameBuffer::PositionWindow(bool fullscreen) +void SystemGLFrameBuffer::PositionWindow(bool fullscreen) { RECT r; LONG style, exStyle; @@ -298,7 +298,7 @@ void SystemFrameBuffer::PositionWindow(bool fullscreen) // //========================================================================== -SystemFrameBuffer::SystemFrameBuffer(void *hMonitor, bool fullscreen) : DFrameBuffer(vid_defwidth, vid_defheight) +SystemGLFrameBuffer::SystemGLFrameBuffer(void *hMonitor, bool fullscreen) : DFrameBuffer(vid_defwidth, vid_defheight) { m_Monitor = hMonitor; m_displayDeviceName = 0; @@ -346,7 +346,7 @@ SystemFrameBuffer::SystemFrameBuffer(void *hMonitor, bool fullscreen) : DFrameBu // //========================================================================== -SystemFrameBuffer::~SystemFrameBuffer() +SystemGLFrameBuffer::~SystemGLFrameBuffer() { ResetGammaTable(); SaveWindowedPos(); @@ -367,7 +367,7 @@ SystemFrameBuffer::~SystemFrameBuffer() // //========================================================================== -void SystemFrameBuffer::InitializeState() +void SystemGLFrameBuffer::InitializeState() { } @@ -377,7 +377,7 @@ void SystemFrameBuffer::InitializeState() // //========================================================================== -void SystemFrameBuffer::ResetGammaTable() +void SystemGLFrameBuffer::ResetGammaTable() { if (m_supportsGamma) { @@ -387,7 +387,7 @@ void SystemFrameBuffer::ResetGammaTable() } } -void SystemFrameBuffer::SetGammaTable(uint16_t *tbl) +void SystemGLFrameBuffer::SetGammaTable(uint16_t *tbl) { if (m_supportsGamma) { @@ -403,7 +403,7 @@ void SystemFrameBuffer::SetGammaTable(uint16_t *tbl) // //========================================================================== -bool SystemFrameBuffer::IsFullscreen() +bool SystemGLFrameBuffer::IsFullscreen() { return m_Fullscreen; } @@ -414,7 +414,7 @@ bool SystemFrameBuffer::IsFullscreen() // //========================================================================== -void SystemFrameBuffer::ToggleFullscreen(bool yes) +void SystemGLFrameBuffer::ToggleFullscreen(bool yes) { PositionWindow(yes); } @@ -430,12 +430,12 @@ CUSTOM_CVAR(Bool, gl_control_tear, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) vid_vsync.Callback(); } -void SystemFrameBuffer::SetVSync (bool vsync) +void SystemGLFrameBuffer::SetVSync (bool vsync) { if (myWglSwapIntervalExtProc != NULL) myWglSwapIntervalExtProc(vsync ? (gl_control_tear? SwapInterval : 1) : 0); } -void SystemFrameBuffer::SwapBuffers() +void SystemGLFrameBuffer::SwapBuffers() { // Limiting the frame rate is as simple as waiting for the timer to signal this event. I_FPSLimit(); @@ -448,14 +448,14 @@ void SystemFrameBuffer::SwapBuffers() // //========================================================================== -int SystemFrameBuffer::GetClientWidth() +int SystemGLFrameBuffer::GetClientWidth() { RECT rect = { 0 }; GetClientRect(Window, &rect); return rect.right - rect.left; } -int SystemFrameBuffer::GetClientHeight() +int SystemGLFrameBuffer::GetClientHeight() { RECT rect = { 0 }; GetClientRect(Window, &rect); diff --git a/src/win32/win32video.cpp b/src/win32/win32video.cpp index 4ed3bb5013..6b3796a98c 100644 --- a/src/win32/win32video.cpp +++ b/src/win32/win32video.cpp @@ -173,7 +173,7 @@ void Win32GLVideo::GetDisplayDeviceName() DFrameBuffer *Win32GLVideo::CreateFrameBuffer() { - SystemFrameBuffer *fb; + SystemGLFrameBuffer *fb; fb = new OpenGLFrameBuffer(m_hMonitor, fullscreen); return fb; From c2d24e1dd33910d1cfb1d70d4c68075b94af031e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 24 Jun 2018 20:31:35 +0200 Subject: [PATCH 3/7] - renamed a file. --- src/win32/{win32video.cpp => win32glvideo.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/win32/{win32video.cpp => win32glvideo.cpp} (100%) diff --git a/src/win32/win32video.cpp b/src/win32/win32glvideo.cpp similarity index 100% rename from src/win32/win32video.cpp rename to src/win32/win32glvideo.cpp From 1519514dd7d06fa7262d818222033067d8e338be Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 24 Jun 2018 20:47:00 +0200 Subject: [PATCH 4/7] - split Win32GLVideo in two so that the OpenGL independent part can be used for Vulkan as well. --- src/CMakeLists.txt | 3 +- src/win32/hardware.cpp | 3 +- src/win32/win32basevideo.cpp | 210 +++++++++++++++++++++++++++++++++++ src/win32/win32basevideo.h | 32 ++++++ src/win32/win32gliface.cpp | 5 - src/win32/win32glvideo.cpp | 154 +------------------------ src/win32/win32glvideo.h | 23 +--- 7 files changed, 251 insertions(+), 179 deletions(-) create mode 100644 src/win32/win32basevideo.cpp create mode 100644 src/win32/win32basevideo.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d77e733e02..d7c3bd1050 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -496,7 +496,8 @@ set( PLAT_WIN32_SOURCES win32/i_specialpaths.cpp win32/st_start.cpp win32/win32gliface.cpp - win32/win32video.cpp ) + win32/win32basevideo.cpp + win32/win32glvideo.cpp ) set( PLAT_POSIX_SOURCES posix/i_cd.cpp posix/i_steam.cpp ) diff --git a/src/win32/hardware.cpp b/src/win32/hardware.cpp index 5c665e7815..6c4fd007b6 100644 --- a/src/win32/hardware.cpp +++ b/src/win32/hardware.cpp @@ -43,6 +43,7 @@ #include "doomstat.h" #include "m_argv.h" #include "version.h" +#include "win32glvideo.h" #include "swrenderer/r_swrenderer.h" EXTERN_CVAR (Bool, fullscreen) @@ -124,7 +125,7 @@ void I_InitGraphics () // are the active app. Huh? } - Video = gl_CreateVideo(); + Video = new Win32GLVideo(); if (Video == NULL) I_FatalError ("Failed to initialize display"); diff --git a/src/win32/win32basevideo.cpp b/src/win32/win32basevideo.cpp new file mode 100644 index 0000000000..25a97811d8 --- /dev/null +++ b/src/win32/win32basevideo.cpp @@ -0,0 +1,210 @@ +/* +** win32video.cpp +** Code to let ZDoom draw to the screen +** +**--------------------------------------------------------------------------- +** Copyright 1998-2006 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include +#include +#include "wglext.h" + +#include "gl_sysfb.h" +#include "hardware.h" +#include "x86.h" +#include "templates.h" +#include "version.h" +#include "c_console.h" +#include "v_video.h" +#include "i_input.h" +#include "i_system.h" +#include "doomstat.h" +#include "v_text.h" +#include "m_argv.h" +#include "doomerrors.h" +#include "Win32BaseVideo.h" + +#include "gl/system/gl_framebuffer.h" + +EXTERN_CVAR(Int, vid_adapter) +EXTERN_CVAR(Bool, fullscreen) +EXTERN_CVAR(Bool, vr_enable_quadbuffered) + +//========================================================================== +// +// +// +//========================================================================== + +Win32BaseVideo::Win32BaseVideo() +{ + I_SetWndProc(); + + GetDisplayDeviceName(); +} + +//========================================================================== +// +// +// +//========================================================================== + +struct MonitorEnumState +{ + int curIdx; + HMONITOR hFoundMonitor; +}; + +static BOOL CALLBACK GetDisplayDeviceNameMonitorEnumProc(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData) +{ + MonitorEnumState *state = reinterpret_cast(dwData); + + MONITORINFOEX mi; + mi.cbSize = sizeof mi; + GetMonitorInfo(hMonitor, &mi); + + // This assumes the monitors are returned by EnumDisplayMonitors in the + // order they're found in the Direct3D9 adapters list. Fingers crossed... + if (state->curIdx == vid_adapter) + { + state->hFoundMonitor = hMonitor; + + // Don't stop enumeration; this makes EnumDisplayMonitors fail. I like + // proper fails. + } + + ++state->curIdx; + + return TRUE; +} + +//========================================================================== +// +// +// +//========================================================================== + +void Win32BaseVideo::GetDisplayDeviceName() +{ + // If anything goes wrong, anything at all, everything uses the primary + // monitor. + m_DisplayDeviceName = 0; + m_hMonitor = 0; + + MonitorEnumState mes; + + mes.curIdx = 1; + mes.hFoundMonitor = 0; + + // Could also use EnumDisplayDevices, I guess. That might work. + if (EnumDisplayMonitors(0, 0, &GetDisplayDeviceNameMonitorEnumProc, LPARAM(&mes))) + { + if (mes.hFoundMonitor) + { + MONITORINFOEX mi; + + mi.cbSize = sizeof mi; + + if (GetMonitorInfo(mes.hFoundMonitor, &mi)) + { + strcpy(m_DisplayDeviceBuffer, mi.szDevice); + m_DisplayDeviceName = m_DisplayDeviceBuffer; + + m_hMonitor = mes.hFoundMonitor; + } + } + } +} + +//========================================================================== +// +// +// +//========================================================================== + +struct DumpAdaptersState +{ + unsigned index; + char *displayDeviceName; +}; + +static BOOL CALLBACK DumpAdaptersMonitorEnumProc(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData) +{ + DumpAdaptersState *state = reinterpret_cast(dwData); + + MONITORINFOEX mi; + mi.cbSize = sizeof mi; + + char moreinfo[64] = ""; + + bool active = true; + + if (GetMonitorInfo(hMonitor, &mi)) + { + bool primary = !!(mi.dwFlags & MONITORINFOF_PRIMARY); + + mysnprintf(moreinfo, countof(moreinfo), " [%ldx%ld @ (%ld,%ld)]%s", + mi.rcMonitor.right - mi.rcMonitor.left, + mi.rcMonitor.bottom - mi.rcMonitor.top, + mi.rcMonitor.left, mi.rcMonitor.top, + primary ? " (Primary)" : ""); + + if (!state->displayDeviceName && !primary) + active = false;//primary selected, but this ain't primary + else if (state->displayDeviceName && strcmp(state->displayDeviceName, mi.szDevice) != 0) + active = false;//this isn't the selected one + } + + Printf("%s%u. %s\n", + active ? TEXTCOLOR_BOLD : "", + state->index, + moreinfo); + + ++state->index; + + return TRUE; +} + +//========================================================================== +// +// +// +//========================================================================== + +void Win32BaseVideo::DumpAdapters() +{ + DumpAdaptersState das; + + das.index = 1; + das.displayDeviceName = m_DisplayDeviceName; + + EnumDisplayMonitors(0, 0, DumpAdaptersMonitorEnumProc, LPARAM(&das)); +} + diff --git a/src/win32/win32basevideo.h b/src/win32/win32basevideo.h new file mode 100644 index 0000000000..5897febe3a --- /dev/null +++ b/src/win32/win32basevideo.h @@ -0,0 +1,32 @@ +#pragma once + +#include "v_video.h" + +//========================================================================== +// +// +// +//========================================================================== + +class Win32BaseVideo : public IVideo +{ +public: + Win32BaseVideo(); + + void DumpAdapters(); + + HDC m_hDC; + +protected: + HMODULE hmRender; + + char m_DisplayDeviceBuffer[CCHDEVICENAME]; + char *m_DisplayDeviceName; + HMONITOR m_hMonitor; + + HWND m_Window; + + void GetDisplayDeviceName(); +public: + +}; diff --git a/src/win32/win32gliface.cpp b/src/win32/win32gliface.cpp index ff814f8d1e..868ea19e58 100644 --- a/src/win32/win32gliface.cpp +++ b/src/win32/win32gliface.cpp @@ -461,8 +461,3 @@ int SystemGLFrameBuffer::GetClientHeight() GetClientRect(Window, &rect); return rect.bottom - rect.top; } - -IVideo *gl_CreateVideo() -{ - return new Win32GLVideo(0); -} diff --git a/src/win32/win32glvideo.cpp b/src/win32/win32glvideo.cpp index 6b3796a98c..2da91f9e2d 100644 --- a/src/win32/win32glvideo.cpp +++ b/src/win32/win32glvideo.cpp @@ -73,96 +73,9 @@ PFNWGLCREATECONTEXTATTRIBSARBPROC myWglCreateContextAttribsARB; // //========================================================================== -Win32GLVideo::Win32GLVideo(int parm) +Win32GLVideo::Win32GLVideo() { - I_SetWndProc(); - - GetDisplayDeviceName(); SetPixelFormat(); - -} - -//========================================================================== -// -// -// -//========================================================================== - -Win32GLVideo::~Win32GLVideo() -{ -} - -//========================================================================== -// -// -// -//========================================================================== - -struct MonitorEnumState -{ - int curIdx; - HMONITOR hFoundMonitor; -}; - -static BOOL CALLBACK GetDisplayDeviceNameMonitorEnumProc(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData) -{ - MonitorEnumState *state = reinterpret_cast(dwData); - - MONITORINFOEX mi; - mi.cbSize = sizeof mi; - GetMonitorInfo(hMonitor, &mi); - - // This assumes the monitors are returned by EnumDisplayMonitors in the - // order they're found in the Direct3D9 adapters list. Fingers crossed... - if (state->curIdx == vid_adapter) - { - state->hFoundMonitor = hMonitor; - - // Don't stop enumeration; this makes EnumDisplayMonitors fail. I like - // proper fails. - } - - ++state->curIdx; - - return TRUE; -} - -//========================================================================== -// -// -// -//========================================================================== - -void Win32GLVideo::GetDisplayDeviceName() -{ - // If anything goes wrong, anything at all, everything uses the primary - // monitor. - m_DisplayDeviceName = 0; - m_hMonitor = 0; - - MonitorEnumState mes; - - mes.curIdx = 1; - mes.hFoundMonitor = 0; - - // Could also use EnumDisplayDevices, I guess. That might work. - if (EnumDisplayMonitors(0, 0, &GetDisplayDeviceNameMonitorEnumProc, LPARAM(&mes))) - { - if (mes.hFoundMonitor) - { - MONITORINFOEX mi; - - mi.cbSize = sizeof mi; - - if (GetMonitorInfo(mes.hFoundMonitor, &mi)) - { - strcpy(m_DisplayDeviceBuffer, mi.szDevice); - m_DisplayDeviceName = m_DisplayDeviceBuffer; - - m_hMonitor = mes.hFoundMonitor; - } - } - } } //========================================================================== @@ -185,71 +98,6 @@ DFrameBuffer *Win32GLVideo::CreateFrameBuffer() // //========================================================================== -struct DumpAdaptersState -{ - unsigned index; - char *displayDeviceName; -}; - -static BOOL CALLBACK DumpAdaptersMonitorEnumProc(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData) -{ - DumpAdaptersState *state = reinterpret_cast(dwData); - - MONITORINFOEX mi; - mi.cbSize = sizeof mi; - - char moreinfo[64] = ""; - - bool active = true; - - if (GetMonitorInfo(hMonitor, &mi)) - { - bool primary = !!(mi.dwFlags & MONITORINFOF_PRIMARY); - - mysnprintf(moreinfo, countof(moreinfo), " [%ldx%ld @ (%ld,%ld)]%s", - mi.rcMonitor.right - mi.rcMonitor.left, - mi.rcMonitor.bottom - mi.rcMonitor.top, - mi.rcMonitor.left, mi.rcMonitor.top, - primary ? " (Primary)" : ""); - - if (!state->displayDeviceName && !primary) - active = false;//primary selected, but this ain't primary - else if (state->displayDeviceName && strcmp(state->displayDeviceName, mi.szDevice) != 0) - active = false;//this isn't the selected one - } - - Printf("%s%u. %s\n", - active ? TEXTCOLOR_BOLD : "", - state->index, - moreinfo); - - ++state->index; - - return TRUE; -} - -//========================================================================== -// -// -// -//========================================================================== - -void Win32GLVideo::DumpAdapters() -{ - DumpAdaptersState das; - - das.index = 1; - das.displayDeviceName = m_DisplayDeviceName; - - EnumDisplayMonitors(0, 0, DumpAdaptersMonitorEnumProc, LPARAM(&das)); -} - -//========================================================================== -// -// -// -//========================================================================== - HWND Win32GLVideo::InitDummy() { HMODULE g_hInst = GetModuleHandle(NULL); diff --git a/src/win32/win32glvideo.h b/src/win32/win32glvideo.h index cb54a1e22a..84c2abd133 100644 --- a/src/win32/win32glvideo.h +++ b/src/win32/win32glvideo.h @@ -1,6 +1,6 @@ #pragma once -#include "v_video.h" +#include "win32basevideo.h" //========================================================================== // @@ -8,35 +8,20 @@ // //========================================================================== -class Win32GLVideo : public IVideo +class Win32GLVideo : public Win32BaseVideo { public: - Win32GLVideo(int parm); - virtual ~Win32GLVideo(); + Win32GLVideo(); - DFrameBuffer *CreateFrameBuffer(); - void DumpAdapters(); + DFrameBuffer *CreateFrameBuffer() override; bool InitHardware(HWND Window, int multisample); void Shutdown(); - HDC m_hDC; - protected: - HMODULE hmRender; - - char m_DisplayDeviceBuffer[CCHDEVICENAME]; - char *m_DisplayDeviceName; - HMONITOR m_hMonitor; - - HWND m_Window; HGLRC m_hRC; HWND InitDummy(); void ShutdownDummy(HWND dummy); bool SetPixelFormat(); bool SetupPixelFormat(int multisample); - - void GetDisplayDeviceName(); -public: - }; From 66d13b6e80de059f6cebd5ffe6ae861c067e0345 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 24 Jun 2018 20:55:05 +0200 Subject: [PATCH 5/7] - renamed another file. --- src/CMakeLists.txt | 2 +- src/win32/{win32gliface.cpp => gl_sysfb.cpp} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/win32/{win32gliface.cpp => gl_sysfb.cpp} (100%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d7c3bd1050..78316fbfe4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -495,7 +495,7 @@ set( PLAT_WIN32_SOURCES win32/i_system.cpp win32/i_specialpaths.cpp win32/st_start.cpp - win32/win32gliface.cpp + win32/gl_sysfb.cpp win32/win32basevideo.cpp win32/win32glvideo.cpp ) set( PLAT_POSIX_SOURCES diff --git a/src/win32/win32gliface.cpp b/src/win32/gl_sysfb.cpp similarity index 100% rename from src/win32/win32gliface.cpp rename to src/win32/gl_sysfb.cpp From daf8703fc9964b0fb196476c741a791d3997d901 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 24 Jun 2018 21:26:32 +0200 Subject: [PATCH 6/7] - split up Win32's SystemGLFrameBuffer as well to get the shareable parts between OpenGL and Vulkan into a base class. --- src/CMakeLists.txt | 1 + src/gl/system/gl_framebuffer.cpp | 1 - src/win32/gl_sysfb.cpp | 321 +------------------------------ src/win32/gl_sysfb.h | 42 +--- src/win32/win32basevideo.cpp | 3 +- src/win32/win32basevideo.h | 1 + 6 files changed, 10 insertions(+), 359 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 78316fbfe4..0f578c4c56 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -496,6 +496,7 @@ set( PLAT_WIN32_SOURCES win32/i_specialpaths.cpp win32/st_start.cpp win32/gl_sysfb.cpp + win32/base_sysfb.cpp win32/win32basevideo.cpp win32/win32glvideo.cpp ) set( PLAT_POSIX_SOURCES diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index c30f22c63d..6f0171b0ce 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -114,7 +114,6 @@ void OpenGLFrameBuffer::InitializeState() } gl_LoadExtensions(); - Super::InitializeState(); if (first) { diff --git a/src/win32/gl_sysfb.cpp b/src/win32/gl_sysfb.cpp index 868ea19e58..5229408585 100644 --- a/src/win32/gl_sysfb.cpp +++ b/src/win32/gl_sysfb.cpp @@ -57,21 +57,8 @@ extern HWND Window; -extern "C" { - __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; - __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; -} - PFNWGLSWAPINTERVALEXTPROC myWglSwapIntervalExtProc; -CVAR(Int, vid_adapter, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) - -CVAR(Int, win_x, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -CVAR(Int, win_y, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -CVAR(Int, win_w, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -CVAR(Int, win_h, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -CVAR(Bool, win_maximized, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) - // For broadest GL compatibility, require user to explicitly enable quad-buffered stereo mode. // Setting vr_enable_quadbuffered_stereo does not automatically invoke quad-buffered stereo, // but makes it possible for subsequent "vr_mode 7" to invoke quad-buffered stereo @@ -97,218 +84,14 @@ EXTERN_CVAR(Int, vid_defheight) // //========================================================================== - void SystemGLFrameBuffer::GetCenteredPos(int in_w, int in_h, int &winx, int &winy, int &winw, int &winh, int &scrwidth, int &scrheight) +SystemGLFrameBuffer::SystemGLFrameBuffer(void *hMonitor, bool fullscreen) : SystemBaseFrameBuffer(hMonitor, fullscreen) { - DEVMODE displaysettings; - RECT rect; - int cx, cy; - - memset(&displaysettings, 0, sizeof(displaysettings)); - displaysettings.dmSize = sizeof(displaysettings); - EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &displaysettings); - scrwidth = (int)displaysettings.dmPelsWidth; - scrheight = (int)displaysettings.dmPelsHeight; - GetWindowRect(Window, &rect); - cx = scrwidth / 2; - cy = scrheight / 2; - if (in_w > 0) winw = in_w; - else winw = rect.right - rect.left; - if (in_h > 0) winh = in_h; - else winh = rect.bottom - rect.top; - winx = cx - winw / 2; - winy = cy - winh / 2; -} - -//========================================================================== -// -// -// -//========================================================================== - -void SystemGLFrameBuffer::KeepWindowOnScreen(int &winx, int &winy, int winw, int winh, int scrwidth, int scrheight) -{ - // If the window is too large to fit entirely on the screen, at least - // keep its upperleft corner visible. - if (winx + winw > scrwidth) - { - winx = scrwidth - winw; - } - if (winx < 0) - { - winx = 0; - } - if (winy + winh > scrheight) - { - winy = scrheight - winh; - } - if (winy < 0) - { - winy = 0; - } -} - -//========================================================================== -// -// -// -//========================================================================== - -void SystemGLFrameBuffer::SaveWindowedPos() -{ - // Don't save if we were run with the -0 option. - if (Args->CheckParm("-0")) - { - return; - } - // Make sure we only save the window position if it's not fullscreen. - static const int WINDOW_STYLE = WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX; - if ((GetWindowLong(Window, GWL_STYLE) & WINDOW_STYLE) == WINDOW_STYLE) - { - RECT wrect; - - if (GetWindowRect(Window, &wrect)) - { - // If (win_x,win_y) specify to center the window, don't change them - // if the window is still centered. - if (win_x < 0 || win_y < 0 || win_w < 0 || win_h < 0) - { - int winx, winy, winw, winh, scrwidth, scrheight; - - GetCenteredPos(win_w, win_h, winx, winy, winw, winh, scrwidth, scrheight); - KeepWindowOnScreen(winx, winy, winw, winh, scrwidth, scrheight); - if (win_x < 0 && winx == wrect.left) - { - wrect.left = win_x; - } - if (win_y < 0 && winy == wrect.top) - { - wrect.top = win_y; - } - wrect.right = winw + wrect.left; - wrect.bottom = winh + wrect.top; - } - - win_x = wrect.left; - win_y = wrect.top; - win_w = wrect.right - wrect.left; - win_h = wrect.bottom - wrect.top; - } - - win_maximized = IsZoomed(Window) == TRUE; - } -} - -//========================================================================== -// -// -// -//========================================================================== - -void SystemGLFrameBuffer::RestoreWindowedPos() -{ - int winx, winy, winw, winh, scrwidth, scrheight; - - GetCenteredPos(win_w, win_h, winx, winy, winw, winh, scrwidth, scrheight); - - // Just move to (0,0) if we were run with the -0 option. - if (Args->CheckParm("-0")) - { - winx = winy = 0; - } - else - { - if (win_x >= 0) - { - winx = win_x; - } - if (win_y >= 0) - { - winy = win_y; - } - KeepWindowOnScreen(winx, winy, winw, winh, scrwidth, scrheight); - } - SetWindowPos(Window, nullptr, winx, winy, winw, winh, SWP_NOZORDER | SWP_FRAMECHANGED); - - if (win_maximized && !Args->CheckParm("-0")) - ShowWindow(Window, SW_MAXIMIZE); -} - -//========================================================================== -// -// -// -//========================================================================== - -void SystemGLFrameBuffer::PositionWindow(bool fullscreen) -{ - RECT r; - LONG style, exStyle; - - RECT monRect; - - if (!m_Fullscreen) SaveWindowedPos(); - if (m_Monitor) - { - MONITORINFOEX mi; - mi.cbSize = sizeof mi; - - if (GetMonitorInfo(HMONITOR(m_Monitor), &mi)) - { - strcpy(m_displayDeviceNameBuffer, mi.szDevice); - m_displayDeviceName = m_displayDeviceNameBuffer; - monRect = mi.rcMonitor; - } - } - - ShowWindow(Window, SW_SHOW); - - GetWindowRect(Window, &r); - style = WS_VISIBLE | WS_CLIPSIBLINGS; - exStyle = 0; - - if (fullscreen) - style |= WS_POPUP; - else - { - style |= WS_OVERLAPPEDWINDOW; - exStyle |= WS_EX_WINDOWEDGE; - } - - SetWindowLong(Window, GWL_STYLE, style); - SetWindowLong(Window, GWL_EXSTYLE, exStyle); - - m_Fullscreen = fullscreen; - if (fullscreen) - { - SetWindowPos(Window, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); - MoveWindow(Window, monRect.left, monRect.top, monRect.right-monRect.left, monRect.bottom-monRect.top, FALSE); - - // And now, seriously, it IS in the right place. Promise. - } - else - { - RestoreWindowedPos(); - } - SetSize(GetClientWidth(), GetClientHeight()); -} - -//========================================================================== -// -// -// -//========================================================================== - -SystemGLFrameBuffer::SystemGLFrameBuffer(void *hMonitor, bool fullscreen) : DFrameBuffer(vid_defwidth, vid_defheight) -{ - m_Monitor = hMonitor; - m_displayDeviceName = 0; - PositionWindow(fullscreen); - if (!static_cast(Video)->InitHardware(Window, 0)) { I_FatalError("Unable to initialize OpenGL"); return; } + HDC hDC = GetDC(Window); const char *wglext = nullptr; @@ -334,91 +117,10 @@ SystemGLFrameBuffer::SystemGLFrameBuffer(void *hMonitor, bool fullscreen) : DFra SwapInterval = -1; } } - - m_supportsGamma = !!GetDeviceGammaRamp(hDC, (void *)m_origGamma); ReleaseDC(Window, hDC); enable_quadbuffered = vr_enable_quadbuffered; } -//========================================================================== -// -// -// -//========================================================================== - -SystemGLFrameBuffer::~SystemGLFrameBuffer() -{ - ResetGammaTable(); - SaveWindowedPos(); - - ShowWindow (Window, SW_SHOW); - SetWindowLong(Window, GWL_STYLE, WS_VISIBLE | WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW); - SetWindowLong(Window, GWL_EXSTYLE, WS_EX_WINDOWEDGE); - SetWindowPos(Window, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); - I_GetEvent(); - - static_cast(Video)->Shutdown(); -} - - -//========================================================================== -// -// -// -//========================================================================== - -void SystemGLFrameBuffer::InitializeState() -{ -} - -//========================================================================== -// -// -// -//========================================================================== - -void SystemGLFrameBuffer::ResetGammaTable() -{ - if (m_supportsGamma) - { - HDC hDC = GetDC(Window); - SetDeviceGammaRamp(hDC, (void *)m_origGamma); - ReleaseDC(Window, hDC); - } -} - -void SystemGLFrameBuffer::SetGammaTable(uint16_t *tbl) -{ - if (m_supportsGamma) - { - HDC hDC = GetDC(Window); - SetDeviceGammaRamp(hDC, (void *)tbl); - ReleaseDC(Window, hDC); - } -} - -//========================================================================== -// -// -// -//========================================================================== - -bool SystemGLFrameBuffer::IsFullscreen() -{ - return m_Fullscreen; -} - -//========================================================================== -// -// -// -//========================================================================== - -void SystemGLFrameBuffer::ToggleFullscreen(bool yes) -{ - PositionWindow(yes); -} - //========================================================================== // // @@ -442,22 +144,3 @@ void SystemGLFrameBuffer::SwapBuffers() ::SwapBuffers(static_cast(Video)->m_hDC); } -//========================================================================== -// -// -// -//========================================================================== - -int SystemGLFrameBuffer::GetClientWidth() -{ - RECT rect = { 0 }; - GetClientRect(Window, &rect); - return rect.right - rect.left; -} - -int SystemGLFrameBuffer::GetClientHeight() -{ - RECT rect = { 0 }; - GetClientRect(Window, &rect); - return rect.bottom - rect.top; -} diff --git a/src/win32/gl_sysfb.h b/src/win32/gl_sysfb.h index fe098fcbd9..52afbf040d 100644 --- a/src/win32/gl_sysfb.h +++ b/src/win32/gl_sysfb.h @@ -1,54 +1,20 @@ -#ifndef __WIN32_GL_SYSFB_H__ -#define __WIN32_GL_SYSFB_H__ +#pragma once -#include "v_video.h" +#include "base_sysfb.h" -class SystemGLFrameBuffer : public DFrameBuffer +class SystemGLFrameBuffer : public SystemBaseFrameBuffer { - typedef DFrameBuffer Super; - - void SaveWindowedPos(); - void RestoreWindowedPos(); + typedef SystemBaseFrameBuffer Super; public: SystemGLFrameBuffer() {} // Actually, hMonitor is a HMONITOR, but it's passed as a void * as there // look to be some cross-platform bits in the way. SystemGLFrameBuffer(void *hMonitor, bool fullscreen); - virtual ~SystemGLFrameBuffer(); void SetVSync (bool vsync); void SwapBuffers(); - int GetClientWidth() override; - int GetClientHeight() override; - - bool IsFullscreen() override; - void ToggleFullscreen(bool yes) override; - - void InitializeState(); - protected: - - void GetCenteredPos(int in_w, int in_h, int &winx, int &winy, int &winw, int &winh, int &scrwidth, int &scrheight); - void KeepWindowOnScreen(int &winx, int &winy, int winw, int winh, int scrwidth, int scrheight); - - void PositionWindow(bool fullscreen); - - void ResetGammaTable(); - void SetGammaTable(uint16_t * tbl); - - float m_Gamma, m_Brightness, m_Contrast; - uint16_t m_origGamma[768]; - bool m_supportsGamma; - bool m_Fullscreen; - char m_displayDeviceNameBuffer[32/*CCHDEVICENAME*/]; // do not use windows.h constants here! - char *m_displayDeviceName; - void *m_Monitor; int SwapInterval; - - friend class Win32GLVideo; - }; - -#endif // __WIN32_GL_SYSFB_H__ diff --git a/src/win32/win32basevideo.cpp b/src/win32/win32basevideo.cpp index 25a97811d8..a444b7da23 100644 --- a/src/win32/win32basevideo.cpp +++ b/src/win32/win32basevideo.cpp @@ -53,7 +53,8 @@ #include "gl/system/gl_framebuffer.h" -EXTERN_CVAR(Int, vid_adapter) +CVAR(Int, vid_adapter, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) + EXTERN_CVAR(Bool, fullscreen) EXTERN_CVAR(Bool, vr_enable_quadbuffered) diff --git a/src/win32/win32basevideo.h b/src/win32/win32basevideo.h index 5897febe3a..258e564444 100644 --- a/src/win32/win32basevideo.h +++ b/src/win32/win32basevideo.h @@ -28,5 +28,6 @@ protected: void GetDisplayDeviceName(); public: + virtual void Shutdown() = 0; }; From 5d14ae68a69bb0a707977b018967381e07e4b2f7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 24 Jun 2018 23:54:25 +0200 Subject: [PATCH 7/7] - missed two added files. --- src/win32/base_sysfb.cpp | 387 +++++++++++++++++++++++++++++++++++++++ src/win32/base_sysfb.h | 42 +++++ 2 files changed, 429 insertions(+) create mode 100644 src/win32/base_sysfb.cpp create mode 100644 src/win32/base_sysfb.h diff --git a/src/win32/base_sysfb.cpp b/src/win32/base_sysfb.cpp new file mode 100644 index 0000000000..5e2f5c21ea --- /dev/null +++ b/src/win32/base_sysfb.cpp @@ -0,0 +1,387 @@ +/* +** +** +**--------------------------------------------------------------------------- +** Copyright 2003-2005 Tim Stump +** Copyright 2005-2016 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include "wglext.h" + +#include "gl_sysfb.h" +#include "hardware.h" +#include "x86.h" +#include "templates.h" +#include "version.h" +#include "c_console.h" +#include "v_video.h" +#include "i_input.h" +#include "i_system.h" +#include "doomstat.h" +#include "v_text.h" +#include "m_argv.h" +#include "doomerrors.h" +#include "base_sysfb.h" +#include "win32basevideo.h" + + +extern HWND Window; + +extern "C" { + __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; + __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; +} + +CVAR(Int, win_x, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +CVAR(Int, win_y, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +CVAR(Int, win_w, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +CVAR(Int, win_h, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +CVAR(Bool, win_maximized, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) + +EXTERN_CVAR(Int, vid_defwidth) +EXTERN_CVAR(Int, vid_defheight) + + +//========================================================================== +// +// Windows framebuffer +// +//========================================================================== + + +//========================================================================== +// +// +// +//========================================================================== + + void SystemBaseFrameBuffer::GetCenteredPos(int in_w, int in_h, int &winx, int &winy, int &winw, int &winh, int &scrwidth, int &scrheight) +{ + DEVMODE displaysettings; + RECT rect; + int cx, cy; + + memset(&displaysettings, 0, sizeof(displaysettings)); + displaysettings.dmSize = sizeof(displaysettings); + EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &displaysettings); + scrwidth = (int)displaysettings.dmPelsWidth; + scrheight = (int)displaysettings.dmPelsHeight; + GetWindowRect(Window, &rect); + cx = scrwidth / 2; + cy = scrheight / 2; + if (in_w > 0) winw = in_w; + else winw = rect.right - rect.left; + if (in_h > 0) winh = in_h; + else winh = rect.bottom - rect.top; + winx = cx - winw / 2; + winy = cy - winh / 2; +} + +//========================================================================== +// +// +// +//========================================================================== + +void SystemBaseFrameBuffer::KeepWindowOnScreen(int &winx, int &winy, int winw, int winh, int scrwidth, int scrheight) +{ + // If the window is too large to fit entirely on the screen, at least + // keep its upperleft corner visible. + if (winx + winw > scrwidth) + { + winx = scrwidth - winw; + } + if (winx < 0) + { + winx = 0; + } + if (winy + winh > scrheight) + { + winy = scrheight - winh; + } + if (winy < 0) + { + winy = 0; + } +} + +//========================================================================== +// +// +// +//========================================================================== + +void SystemBaseFrameBuffer::SaveWindowedPos() +{ + // Don't save if we were run with the -0 option. + if (Args->CheckParm("-0")) + { + return; + } + // Make sure we only save the window position if it's not fullscreen. + static const int WINDOW_STYLE = WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX; + if ((GetWindowLong(Window, GWL_STYLE) & WINDOW_STYLE) == WINDOW_STYLE) + { + RECT wrect; + + if (GetWindowRect(Window, &wrect)) + { + // If (win_x,win_y) specify to center the window, don't change them + // if the window is still centered. + if (win_x < 0 || win_y < 0 || win_w < 0 || win_h < 0) + { + int winx, winy, winw, winh, scrwidth, scrheight; + + GetCenteredPos(win_w, win_h, winx, winy, winw, winh, scrwidth, scrheight); + KeepWindowOnScreen(winx, winy, winw, winh, scrwidth, scrheight); + if (win_x < 0 && winx == wrect.left) + { + wrect.left = win_x; + } + if (win_y < 0 && winy == wrect.top) + { + wrect.top = win_y; + } + wrect.right = winw + wrect.left; + wrect.bottom = winh + wrect.top; + } + + win_x = wrect.left; + win_y = wrect.top; + win_w = wrect.right - wrect.left; + win_h = wrect.bottom - wrect.top; + } + + win_maximized = IsZoomed(Window) == TRUE; + } +} + +//========================================================================== +// +// +// +//========================================================================== + +void SystemBaseFrameBuffer::RestoreWindowedPos() +{ + int winx, winy, winw, winh, scrwidth, scrheight; + + GetCenteredPos(win_w, win_h, winx, winy, winw, winh, scrwidth, scrheight); + + // Just move to (0,0) if we were run with the -0 option. + if (Args->CheckParm("-0")) + { + winx = winy = 0; + } + else + { + if (win_x >= 0) + { + winx = win_x; + } + if (win_y >= 0) + { + winy = win_y; + } + KeepWindowOnScreen(winx, winy, winw, winh, scrwidth, scrheight); + } + SetWindowPos(Window, nullptr, winx, winy, winw, winh, SWP_NOZORDER | SWP_FRAMECHANGED); + + if (win_maximized && !Args->CheckParm("-0")) + ShowWindow(Window, SW_MAXIMIZE); +} + +//========================================================================== +// +// +// +//========================================================================== + +void SystemBaseFrameBuffer::PositionWindow(bool fullscreen) +{ + RECT r; + LONG style, exStyle; + + RECT monRect; + + if (!m_Fullscreen) SaveWindowedPos(); + if (m_Monitor) + { + MONITORINFOEX mi; + mi.cbSize = sizeof mi; + + if (GetMonitorInfo(HMONITOR(m_Monitor), &mi)) + { + strcpy(m_displayDeviceNameBuffer, mi.szDevice); + m_displayDeviceName = m_displayDeviceNameBuffer; + monRect = mi.rcMonitor; + } + } + + ShowWindow(Window, SW_SHOW); + + GetWindowRect(Window, &r); + style = WS_VISIBLE | WS_CLIPSIBLINGS; + exStyle = 0; + + if (fullscreen) + style |= WS_POPUP; + else + { + style |= WS_OVERLAPPEDWINDOW; + exStyle |= WS_EX_WINDOWEDGE; + } + + SetWindowLong(Window, GWL_STYLE, style); + SetWindowLong(Window, GWL_EXSTYLE, exStyle); + + m_Fullscreen = fullscreen; + if (fullscreen) + { + SetWindowPos(Window, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); + MoveWindow(Window, monRect.left, monRect.top, monRect.right-monRect.left, monRect.bottom-monRect.top, FALSE); + + // And now, seriously, it IS in the right place. Promise. + } + else + { + RestoreWindowedPos(); + } + SetSize(GetClientWidth(), GetClientHeight()); +} + +//========================================================================== +// +// +// +//========================================================================== + +SystemBaseFrameBuffer::SystemBaseFrameBuffer(void *hMonitor, bool fullscreen) : DFrameBuffer(vid_defwidth, vid_defheight) +{ + m_Monitor = hMonitor; + m_displayDeviceName = 0; + PositionWindow(fullscreen); + + HDC hDC = GetDC(Window); + + m_supportsGamma = !!GetDeviceGammaRamp(hDC, (void *)m_origGamma); + ReleaseDC(Window, hDC); +} + +//========================================================================== +// +// +// +//========================================================================== + +SystemBaseFrameBuffer::~SystemBaseFrameBuffer() +{ + ResetGammaTable(); + SaveWindowedPos(); + + ShowWindow (Window, SW_SHOW); + SetWindowLong(Window, GWL_STYLE, WS_VISIBLE | WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW); + SetWindowLong(Window, GWL_EXSTYLE, WS_EX_WINDOWEDGE); + SetWindowPos(Window, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); + I_GetEvent(); + + static_cast(Video)->Shutdown(); +} + + +//========================================================================== +// +// +// +//========================================================================== + +void SystemBaseFrameBuffer::ResetGammaTable() +{ + if (m_supportsGamma) + { + HDC hDC = GetDC(Window); + SetDeviceGammaRamp(hDC, (void *)m_origGamma); + ReleaseDC(Window, hDC); + } +} + +void SystemBaseFrameBuffer::SetGammaTable(uint16_t *tbl) +{ + if (m_supportsGamma) + { + HDC hDC = GetDC(Window); + SetDeviceGammaRamp(hDC, (void *)tbl); + ReleaseDC(Window, hDC); + } +} + +//========================================================================== +// +// +// +//========================================================================== + +bool SystemBaseFrameBuffer::IsFullscreen() +{ + return m_Fullscreen; +} + +//========================================================================== +// +// +// +//========================================================================== + +void SystemBaseFrameBuffer::ToggleFullscreen(bool yes) +{ + PositionWindow(yes); +} + +//========================================================================== +// +// +// +//========================================================================== + +int SystemBaseFrameBuffer::GetClientWidth() +{ + RECT rect = { 0 }; + GetClientRect(Window, &rect); + return rect.right - rect.left; +} + +int SystemBaseFrameBuffer::GetClientHeight() +{ + RECT rect = { 0 }; + GetClientRect(Window, &rect); + return rect.bottom - rect.top; +} diff --git a/src/win32/base_sysfb.h b/src/win32/base_sysfb.h new file mode 100644 index 0000000000..01672c2806 --- /dev/null +++ b/src/win32/base_sysfb.h @@ -0,0 +1,42 @@ +#pragma once + +#include "v_video.h" + +class SystemBaseFrameBuffer : public DFrameBuffer +{ + typedef DFrameBuffer Super; + + void SaveWindowedPos(); + void RestoreWindowedPos(); + +public: + SystemBaseFrameBuffer() {} + // Actually, hMonitor is a HMONITOR, but it's passed as a void * as there + // look to be some cross-platform bits in the way. + SystemBaseFrameBuffer(void *hMonitor, bool fullscreen); + virtual ~SystemBaseFrameBuffer(); + + int GetClientWidth() override; + int GetClientHeight() override; + + bool IsFullscreen() override; + void ToggleFullscreen(bool yes) override; + +protected: + + void GetCenteredPos(int in_w, int in_h, int &winx, int &winy, int &winw, int &winh, int &scrwidth, int &scrheight); + void KeepWindowOnScreen(int &winx, int &winy, int winw, int winh, int scrwidth, int scrheight); + + void PositionWindow(bool fullscreen); + + void ResetGammaTable(); + void SetGammaTable(uint16_t * tbl); + + float m_Gamma, m_Brightness, m_Contrast; + uint16_t m_origGamma[768]; + bool m_supportsGamma; + bool m_Fullscreen; + char m_displayDeviceNameBuffer[32/*CCHDEVICENAME*/]; // do not use windows.h constants here! + char *m_displayDeviceName; + void *m_Monitor; +};