Merge remote-tracking branch 'gzdoom/modern' into hw_postprocess

This commit is contained in:
Magnus Norddahl 2018-06-26 02:12:49 +02:00
commit 61d69f5561
18 changed files with 1350 additions and 1176 deletions

View File

@ -495,8 +495,10 @@ set( PLAT_WIN32_SOURCES
win32/i_system.cpp win32/i_system.cpp
win32/i_specialpaths.cpp win32/i_specialpaths.cpp
win32/st_start.cpp win32/st_start.cpp
win32/win32gliface.cpp win32/gl_sysfb.cpp
win32/win32video.cpp ) win32/base_sysfb.cpp
win32/win32basevideo.cpp
win32/win32glvideo.cpp )
set( PLAT_POSIX_SOURCES set( PLAT_POSIX_SOURCES
posix/i_cd.cpp posix/i_cd.cpp
posix/i_steam.cpp ) posix/i_steam.cpp )

View File

@ -114,7 +114,6 @@ void OpenGLFrameBuffer::InitializeState()
} }
gl_LoadExtensions(); gl_LoadExtensions();
Super::InitializeState();
if (first) if (first)
{ {

View File

@ -9,9 +9,9 @@ class FHardwareTexture;
class FSimpleVertexBuffer; class FSimpleVertexBuffer;
class FGLDebug; class FGLDebug;
class OpenGLFrameBuffer : public SystemFrameBuffer class OpenGLFrameBuffer : public SystemGLFrameBuffer
{ {
typedef SystemFrameBuffer Super; typedef SystemGLFrameBuffer Super;
public: public:

View File

@ -44,12 +44,12 @@ typedef struct objc_object NSCursor;
typedef struct objc_object CocoaWindow; typedef struct objc_object CocoaWindow;
#endif #endif
class SystemFrameBuffer : public DFrameBuffer class SystemGLFrameBuffer : public DFrameBuffer
{ {
public: public:
// This must have the same parameters as the Windows version, even if they are not used! // This must have the same parameters as the Windows version, even if they are not used!
SystemFrameBuffer(void *hMonitor, bool fullscreen); SystemGLFrameBuffer(void *hMonitor, bool fullscreen);
~SystemFrameBuffer(); ~SystemGLFrameBuffer();
virtual bool IsFullscreen(); virtual bool IsFullscreen();
virtual void SetVSync(bool vsync); virtual void SetVSync(bool vsync);
@ -78,7 +78,7 @@ protected:
bool m_supportsGamma; bool m_supportsGamma;
uint16_t m_originalGamma[GAMMA_TABLE_SIZE]; uint16_t m_originalGamma[GAMMA_TABLE_SIZE];
SystemFrameBuffer() {} SystemGLFrameBuffer() {}
void SetFullscreenMode(); void SetFullscreenMode();
void SetWindowedMode(); void SetWindowedMode();

View File

@ -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) : DFrameBuffer(vid_defwidth, vid_defheight)
, m_window(CreateWindow(STYLE_MASK_WINDOWED)) , m_window(CreateWindow(STYLE_MASK_WINDOWED))
, m_fullscreen(false) , m_fullscreen(false)
@ -386,7 +386,7 @@ SystemFrameBuffer::SystemFrameBuffer(void*, const bool fullscreen)
FConsoleWindow::GetInstance().Show(false); FConsoleWindow::GetInstance().Show(false);
} }
SystemFrameBuffer::~SystemFrameBuffer() SystemGLFrameBuffer::~SystemGLFrameBuffer()
{ {
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
[nc removeObserver:m_window [nc removeObserver:m_window
@ -397,18 +397,18 @@ SystemFrameBuffer::~SystemFrameBuffer()
object:nil]; object:nil];
} }
bool SystemFrameBuffer::IsFullscreen() bool SystemGLFrameBuffer::IsFullscreen()
{ {
return m_fullscreen; return m_fullscreen;
} }
void SystemFrameBuffer::ToggleFullscreen(bool yes) void SystemGLFrameBuffer::ToggleFullscreen(bool yes)
{ {
SetMode(yes, m_hiDPI); SetMode(yes, m_hiDPI);
} }
void SystemFrameBuffer::SetVSync(bool vsync) void SystemGLFrameBuffer::SetVSync(bool vsync)
{ {
const GLint value = vsync ? 1 : 0; 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]; [[NSOpenGLContext currentContext] flushBuffer];
} }
void SystemFrameBuffer::SetGammaTable(uint16_t* table) void SystemGLFrameBuffer::SetGammaTable(uint16_t* table)
{ {
if (m_supportsGamma) if (m_supportsGamma)
{ {
@ -442,7 +442,7 @@ void SystemFrameBuffer::SetGammaTable(uint16_t* table)
} }
} }
void SystemFrameBuffer::ResetGammaTable() void SystemGLFrameBuffer::ResetGammaTable()
{ {
if (m_supportsGamma) if (m_supportsGamma)
{ {
@ -451,20 +451,20 @@ void SystemFrameBuffer::ResetGammaTable()
} }
int SystemFrameBuffer::GetClientWidth() int SystemGLFrameBuffer::GetClientWidth()
{ {
const int clientWidth = I_GetContentViewSize(m_window).width; const int clientWidth = I_GetContentViewSize(m_window).width;
return clientWidth > 0 ? clientWidth : GetWidth(); return clientWidth > 0 ? clientWidth : GetWidth();
} }
int SystemFrameBuffer::GetClientHeight() int SystemGLFrameBuffer::GetClientHeight()
{ {
const int clientHeight = I_GetContentViewSize(m_window).height; const int clientHeight = I_GetContentViewSize(m_window).height;
return clientHeight > 0 ? clientHeight : GetHeight(); return clientHeight > 0 ? clientHeight : GetHeight();
} }
void SystemFrameBuffer::SetFullscreenMode() void SystemGLFrameBuffer::SetFullscreenMode()
{ {
if (!m_fullscreen) if (!m_fullscreen)
{ {
@ -478,7 +478,7 @@ void SystemFrameBuffer::SetFullscreenMode()
[m_window setFrame:screenFrame display:YES]; [m_window setFrame:screenFrame display:YES];
} }
void SystemFrameBuffer::SetWindowedMode() void SystemGLFrameBuffer::SetWindowedMode()
{ {
if (m_fullscreen) if (m_fullscreen)
{ {
@ -498,7 +498,7 @@ void SystemFrameBuffer::SetWindowedMode()
[m_window exitAppOnClose]; [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]; NSOpenGLView* const glView = [m_window contentView];
[glView setWantsBestResolutionOpenGLSurface:hiDPI]; [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<SystemFrameBuffer*>(screen); return static_cast<SystemGLFrameBuffer*>(screen);
} }
void SystemFrameBuffer::UseHiDPI(const bool hiDPI) void SystemGLFrameBuffer::UseHiDPI(const bool hiDPI)
{ {
if (auto fb = GetSystemFrameBuffer()) 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()) 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()) 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()) 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) 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)]; hotSpot:NSMakePoint(0.0f, 0.0f)];
} }
SystemFrameBuffer::SetCursor(cursor); SystemGLFrameBuffer::SetCursor(cursor);
[pool release]; [pool release];
@ -708,11 +708,11 @@ NSSize I_GetContentViewSize(const NSWindow* const window)
void I_SetMainWindowVisible(bool visible) void I_SetMainWindowVisible(bool visible)
{ {
SystemFrameBuffer::SetWindowVisible(visible); SystemGLFrameBuffer::SetWindowVisible(visible);
} }
// each platform has its own specific version of this function. // each platform has its own specific version of this function.
void I_SetWindowTitle(const char* title) void I_SetWindowTitle(const char* title)
{ {
SystemFrameBuffer::SetWindowTitle(title); SystemGLFrameBuffer::SetWindowTitle(title);
} }

View File

@ -5,14 +5,14 @@
#include "v_video.h" #include "v_video.h"
class SystemFrameBuffer : public DFrameBuffer class SystemGLFrameBuffer : public DFrameBuffer
{ {
typedef DFrameBuffer Super; typedef DFrameBuffer Super;
public: public:
// this must have the same parameters as the Windows version, even if they are not used! // this must have the same parameters as the Windows version, even if they are not used!
SystemFrameBuffer (void *hMonitor, bool fullscreen); SystemGLFrameBuffer (void *hMonitor, bool fullscreen);
~SystemFrameBuffer (); ~SystemGLFrameBuffer ();
void ForceBuffering (bool force); void ForceBuffering (bool force);
@ -34,7 +34,7 @@ protected:
void ResetGammaTable(); void ResetGammaTable();
void InitializeState(); void InitializeState();
SystemFrameBuffer () {} SystemGLFrameBuffer () {}
uint8_t GammaTable[3][256]; uint8_t GammaTable[3][256];
bool UpdatePending; bool UpdatePending;

View File

@ -123,7 +123,7 @@ SDLGLVideo::~SDLGLVideo ()
DFrameBuffer *SDLGLVideo::CreateFrameBuffer () DFrameBuffer *SDLGLVideo::CreateFrameBuffer ()
{ {
SystemFrameBuffer *fb = new OpenGLFrameBuffer(0, fullscreen); SystemGLFrameBuffer *fb = new OpenGLFrameBuffer(0, fullscreen);
return fb; return fb;
} }
@ -179,7 +179,7 @@ IVideo *gl_CreateVideo()
// FrameBuffer implementation ----------------------------------------------- // FrameBuffer implementation -----------------------------------------------
SystemFrameBuffer::SystemFrameBuffer (void *, bool fullscreen) SystemGLFrameBuffer::SystemGLFrameBuffer (void *, bool fullscreen)
: DFrameBuffer (vid_defwidth, vid_defheight) : DFrameBuffer (vid_defwidth, vid_defheight)
{ {
// NOTE: Core profiles were added with GL 3.2, so there's no sense trying // 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) 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) if (m_supportsGamma)
{ {
@ -287,7 +287,7 @@ void SystemFrameBuffer::SetGammaTable(uint16_t *tbl)
} }
} }
void SystemFrameBuffer::ResetGammaTable() void SystemGLFrameBuffer::ResetGammaTable()
{ {
if (m_supportsGamma) 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; return (SDL_GetWindowFlags (Screen) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0;
} }
void SystemFrameBuffer::SetVSync( bool vsync ) void SystemGLFrameBuffer::SetVSync( bool vsync )
{ {
#if defined (__APPLE__) #if defined (__APPLE__)
const GLint value = vsync ? 1 : 0; const GLint value = vsync ? 1 : 0;
@ -318,7 +318,7 @@ void SystemFrameBuffer::SetVSync( bool vsync )
#endif #endif
} }
void SystemFrameBuffer::SwapBuffers() void SystemGLFrameBuffer::SwapBuffers()
{ {
#if !defined(__APPLE__) && !defined(__OpenBSD__) #if !defined(__APPLE__) && !defined(__OpenBSD__)
if (vid_maxfps && !cl_capfps) if (vid_maxfps && !cl_capfps)
@ -330,19 +330,19 @@ void SystemFrameBuffer::SwapBuffers()
SDL_GL_SwapWindow (Screen); SDL_GL_SwapWindow (Screen);
} }
void SystemFrameBuffer::ToggleFullscreen(bool yes) void SystemGLFrameBuffer::ToggleFullscreen(bool yes)
{ {
SDL_SetWindowFullscreen(Screen, yes ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); SDL_SetWindowFullscreen(Screen, yes ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
} }
int SystemFrameBuffer::GetClientWidth() int SystemGLFrameBuffer::GetClientWidth()
{ {
int width = 0; int width = 0;
SDL_GL_GetDrawableSize(Screen, &width, nullptr); SDL_GL_GetDrawableSize(Screen, &width, nullptr);
return width; return width;
} }
int SystemFrameBuffer::GetClientHeight() int SystemGLFrameBuffer::GetClientHeight()
{ {
int height = 0; int height = 0;
SDL_GL_GetDrawableSize(Screen, nullptr, &height); 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. // each platform has its own specific version of this function.
void I_SetWindowTitle(const char* caption) void I_SetWindowTitle(const char* caption)
{ {
auto window = static_cast<SystemFrameBuffer *>(screen)->GetSDLWindow(); auto window = static_cast<SystemGLFrameBuffer *>(screen)->GetSDLWindow();
if (caption) if (caption)
SDL_SetWindowTitle(window, caption); SDL_SetWindowTitle(window, caption);
else else

387
src/win32/base_sysfb.cpp Normal file
View File

@ -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 <windows.h>
#include <GL/gl.h>
#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<Win32BaseVideo *>(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;
}

42
src/win32/base_sysfb.h Normal file
View File

@ -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;
};

146
src/win32/gl_sysfb.cpp Normal file
View File

@ -0,0 +1,146 @@
/*
**
**
**---------------------------------------------------------------------------
** 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 <windows.h>
#include <GL/gl.h>
#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 "win32glvideo.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/system/gl_framebuffer.h"
extern HWND Window;
PFNWGLSWAPINTERVALEXTPROC myWglSwapIntervalExtProc;
// 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
CUSTOM_CVAR(Bool, vr_enable_quadbuffered, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
{
Printf("You must restart " GAMENAME " to switch quad stereo mode\n");
}
EXTERN_CVAR(Int, vid_defwidth)
EXTERN_CVAR(Int, vid_defheight)
//==========================================================================
//
// Windows framebuffer
//
//==========================================================================
//==========================================================================
//
//
//
//==========================================================================
SystemGLFrameBuffer::SystemGLFrameBuffer(void *hMonitor, bool fullscreen) : SystemBaseFrameBuffer(hMonitor, fullscreen)
{
if (!static_cast<Win32GLVideo *>(Video)->InitHardware(Window, 0))
{
I_FatalError("Unable to initialize OpenGL");
return;
}
HDC hDC = GetDC(Window);
const char *wglext = nullptr;
myWglSwapIntervalExtProc = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
auto myWglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
if (myWglGetExtensionsStringARB)
{
wglext = myWglGetExtensionsStringARB(hDC);
}
else
{
auto myWglGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)wglGetProcAddress("wglGetExtensionsStringEXT");
if (myWglGetExtensionsStringEXT)
{
wglext = myWglGetExtensionsStringEXT();
}
}
SwapInterval = 1;
if (wglext != nullptr)
{
if (strstr(wglext, "WGL_EXT_swap_control_tear"))
{
SwapInterval = -1;
}
}
ReleaseDC(Window, hDC);
enable_quadbuffered = vr_enable_quadbuffered;
}
//==========================================================================
//
//
//
//==========================================================================
EXTERN_CVAR(Bool, vid_vsync);
CUSTOM_CVAR(Bool, gl_control_tear, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
{
vid_vsync.Callback();
}
void SystemGLFrameBuffer::SetVSync (bool vsync)
{
if (myWglSwapIntervalExtProc != NULL) myWglSwapIntervalExtProc(vsync ? (gl_control_tear? SwapInterval : 1) : 0);
}
void SystemGLFrameBuffer::SwapBuffers()
{
// Limiting the frame rate is as simple as waiting for the timer to signal this event.
I_FPSLimit();
::SwapBuffers(static_cast<Win32GLVideo *>(Video)->m_hDC);
}

View File

@ -1,51 +1,20 @@
#ifndef __WIN32_GL_SYSFB_H__ #pragma once
#define __WIN32_GL_SYSFB_H__
#include "v_video.h" #include "base_sysfb.h"
class SystemFrameBuffer : public DFrameBuffer class SystemGLFrameBuffer : public SystemBaseFrameBuffer
{ {
typedef DFrameBuffer Super; typedef SystemBaseFrameBuffer Super;
void SaveWindowedPos();
void RestoreWindowedPos();
public: public:
SystemFrameBuffer() {} SystemGLFrameBuffer() {}
// Actually, hMonitor is a HMONITOR, but it's passed as a void * as there // Actually, hMonitor is a HMONITOR, but it's passed as a void * as there
// look to be some cross-platform bits in the way. // look to be some cross-platform bits in the way.
SystemFrameBuffer(void *hMonitor, bool fullscreen); SystemGLFrameBuffer(void *hMonitor, bool fullscreen);
virtual ~SystemFrameBuffer();
void SetVSync (bool vsync); void SetVSync (bool vsync);
void SwapBuffers(); void SwapBuffers();
int GetClientWidth() override;
int GetClientHeight() override;
bool IsFullscreen() override;
void ToggleFullscreen(bool yes) override;
void InitializeState();
protected: protected:
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; int SwapInterval;
friend class Win32GLVideo;
}; };
#endif // __WIN32_GL_SYSFB_H__

View File

@ -43,6 +43,7 @@
#include "doomstat.h" #include "doomstat.h"
#include "m_argv.h" #include "m_argv.h"
#include "version.h" #include "version.h"
#include "win32glvideo.h"
#include "swrenderer/r_swrenderer.h" #include "swrenderer/r_swrenderer.h"
EXTERN_CVAR (Bool, fullscreen) EXTERN_CVAR (Bool, fullscreen)
@ -124,7 +125,7 @@ void I_InitGraphics ()
// are the active app. Huh? // are the active app. Huh?
} }
Video = gl_CreateVideo(); Video = new Win32GLVideo();
if (Video == NULL) if (Video == NULL)
I_FatalError ("Failed to initialize display"); I_FatalError ("Failed to initialize display");

View File

@ -0,0 +1,211 @@
/*
** 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 <windows.h>
#include <GL/gl.h>
#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"
CVAR(Int, vid_adapter, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
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<MonitorEnumState *>(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<DumpAdaptersState *>(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));
}

View File

@ -0,0 +1,33 @@
#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:
virtual void Shutdown() = 0;
};

File diff suppressed because it is too large Load Diff

445
src/win32/win32glvideo.cpp Normal file
View File

@ -0,0 +1,445 @@
/*
** 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 <windows.h>
#include <GL/gl.h>
#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 "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()
{
SetPixelFormat();
}
//==========================================================================
//
//
//
//==========================================================================
DFrameBuffer *Win32GLVideo::CreateFrameBuffer()
{
SystemGLFrameBuffer *fb;
fb = new OpenGLFrameBuffer(m_hMonitor, fullscreen);
return fb;
}
//==========================================================================
//
//
//
//==========================================================================
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);
}

27
src/win32/win32glvideo.h Normal file
View File

@ -0,0 +1,27 @@
#pragma once
#include "win32basevideo.h"
//==========================================================================
//
//
//
//==========================================================================
class Win32GLVideo : public Win32BaseVideo
{
public:
Win32GLVideo();
DFrameBuffer *CreateFrameBuffer() override;
bool InitHardware(HWND Window, int multisample);
void Shutdown();
protected:
HGLRC m_hRC;
HWND InitDummy();
void ShutdownDummy(HWND dummy);
bool SetPixelFormat();
bool SetupPixelFormat(int multisample);
};

View File

@ -1,44 +0,0 @@
/*
** 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.
**---------------------------------------------------------------------------
**
*/
#define _WIN32_WINNT 0x0501
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <mmsystem.h>
// HEADER FILES ------------------------------------------------------------
#include "c_cvars.h"
#include "i_system.h"