diff --git a/neo/renderer/qgl.h b/neo/renderer/qgl.h index 0cf2715a..7632136b 100644 --- a/neo/renderer/qgl.h +++ b/neo/renderer/qgl.h @@ -117,11 +117,8 @@ extern PFNGLDEPTHBOUNDSEXTPROC qglDepthBoundsEXT; #if defined( _WIN32 ) && defined(ID_ALLOW_TOOLS) -extern int (WINAPI * qwglChoosePixelFormat)(HDC, CONST PIXELFORMATDESCRIPTOR *); -extern int (WINAPI * qwglDescribePixelFormat) (HDC, int, UINT, LPPIXELFORMATDESCRIPTOR); -extern int (WINAPI * qwglGetPixelFormat)(HDC); -extern BOOL(WINAPI * qwglSetPixelFormat)(HDC, int, CONST PIXELFORMATDESCRIPTOR *); extern BOOL(WINAPI * qwglSwapBuffers)(HDC); +extern int Win_ChoosePixelFormat(HDC hdc); extern BOOL(WINAPI * qwglCopyContext)(HGLRC, HGLRC, UINT); extern HGLRC(WINAPI * qwglCreateContext)(HDC); diff --git a/neo/sys/glimp.cpp b/neo/sys/glimp.cpp index 02c04d87..16076d59 100644 --- a/neo/sys/glimp.cpp +++ b/neo/sys/glimp.cpp @@ -36,8 +36,67 @@ If you have questions concerning this license or the applicable additional terms #if defined(_WIN32) && defined(ID_ALLOW_TOOLS) #include "sys/win32/win_local.h" #include + +// from SDL_windowsopengl.h (internal SDL2 header) +#ifndef WGL_ARB_pixel_format +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_DRAW_TO_BITMAP_ARB 0x2002 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_NEED_PALETTE_ARB 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 +#define WGL_SWAP_METHOD_ARB 0x2007 +#define WGL_NUMBER_OVERLAYS_ARB 0x2008 +#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 +#define WGL_TRANSPARENT_ARB 0x200A +#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 +#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 +#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 +#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A +#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B +#define WGL_SHARE_DEPTH_ARB 0x200C +#define WGL_SHARE_STENCIL_ARB 0x200D +#define WGL_SHARE_ACCUM_ARB 0x200E +#define WGL_SUPPORT_GDI_ARB 0x200F +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_RED_SHIFT_ARB 0x2016 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_GREEN_SHIFT_ARB 0x2018 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_BLUE_SHIFT_ARB 0x201A +#define WGL_ALPHA_BITS_ARB 0x201B +#define WGL_ALPHA_SHIFT_ARB 0x201C +#define WGL_ACCUM_BITS_ARB 0x201D +#define WGL_ACCUM_RED_BITS_ARB 0x201E +#define WGL_ACCUM_GREEN_BITS_ARB 0x201F +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_AUX_BUFFERS_ARB 0x2024 +#define WGL_NO_ACCELERATION_ARB 0x2025 +#define WGL_GENERIC_ACCELERATION_ARB 0x2026 +#define WGL_FULL_ACCELERATION_ARB 0x2027 +#define WGL_SWAP_EXCHANGE_ARB 0x2028 +#define WGL_SWAP_COPY_ARB 0x2029 +#define WGL_SWAP_UNDEFINED_ARB 0x202A +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_TYPE_COLORINDEX_ARB 0x202C #endif +#ifndef WGL_ARB_multisample +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 +#endif + +#endif // _WIN32 and ID_ALLOW_TOOLS + idCVar in_nograb("in_nograb", "0", CVAR_SYSTEM | CVAR_NOCHEAT, "prevents input grabbing"); idCVar r_waylandcompat("r_waylandcompat", "0", CVAR_SYSTEM | CVAR_NOCHEAT | CVAR_ARCHIVE, "wayland compatible framebuffer"); @@ -315,7 +374,7 @@ bool GLimp_Init(glimpParms_t parms) { #if defined(_WIN32) && defined(ID_ALLOW_TOOLS) -#ifndef SDL_VERSION_ATLEAST(2, 0, 0) +#if ! SDL_VERSION_ATLEAST(2, 0, 0) #error "dhewm3 only supports the tools with SDL2, not SDL1!" #endif @@ -334,28 +393,70 @@ bool GLimp_Init(glimpParms_t parms) { // NOTE: hInstance is set in main() win32.hGLRC = qwglGetCurrentContext(); - PIXELFORMATDESCRIPTOR src = + int pfIdx = GetPixelFormat(win32.hDC); + PIXELFORMATDESCRIPTOR src = {}; + if (DescribePixelFormat(win32.hDC, pfIdx, sizeof(PIXELFORMATDESCRIPTOR), &win32.pfd) == 0) { - sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd - 1, // version number - PFD_DRAW_TO_WINDOW | // support window - PFD_SUPPORT_OPENGL | // support OpenGL - PFD_DOUBLEBUFFER, // double buffered - PFD_TYPE_RGBA, // RGBA type - 32, // 32-bit color depth - 0, 0, 0, 0, 0, 0, // color bits ignored - 8, // 8 bit destination alpha - 0, // shift bit ignored - 0, // no accumulation buffer - 0, 0, 0, 0, // accum bits ignored - 24, // 24-bit z-buffer - 8, // 8-bit stencil buffer - 0, // no auxiliary buffer - PFD_MAIN_PLANE, // main layer - 0, // reserved - 0, 0, 0 // layer masks ignored - }; - memcpy(&win32.pfd, &src, sizeof(PIXELFORMATDESCRIPTOR)); + common->Warning("DescribePixelFormat() failed: %d!\n", GetLastError()); + PIXELFORMATDESCRIPTOR src = + { + sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd + 1, // version number + PFD_DRAW_TO_WINDOW | // support window + PFD_SUPPORT_OPENGL | // support OpenGL + PFD_DOUBLEBUFFER, // double buffered + PFD_TYPE_RGBA, // RGBA type + 32, // 32-bit color depth + 0, 0, 0, 0, 0, 0, // color bits ignored + 8, // 8 bit destination alpha + 0, // shift bit ignored + 0, // no accumulation buffer + 0, 0, 0, 0, // accum bits ignored + 24, // 24-bit z-buffer + 8, // 8-bit stencil buffer + 0, // no auxiliary buffer + PFD_MAIN_PLANE, // main layer + 0, // reserved + 0, 0, 0 // layer masks ignored + }; + memcpy(&win32.pfd, &src, sizeof(PIXELFORMATDESCRIPTOR)); + } + + win32.piAttribIList = NULL; + + win32.wglGetPixelFormatAttribivARB = (BOOL(WINAPI*)(HDC,int,int,UINT,const int*,int*))SDL_GL_GetProcAddress("wglGetPixelFormatAttribivARB"); + win32.wglChoosePixelFormatARB = (BOOL(WINAPI*)(HDC,const int*,const FLOAT*,UINT,int*piFormats,UINT*))SDL_GL_GetProcAddress("wglChoosePixelFormatARB"); + + if(win32.wglGetPixelFormatAttribivARB != NULL && win32.wglChoosePixelFormatARB != NULL) { + const int queryAttributes[] = { + // equivalents of all the SDL_GL_* attributes we set above (and ones set implicitly) + WGL_DRAW_TO_WINDOW_ARB, + WGL_RED_BITS_ARB, + WGL_GREEN_BITS_ARB, + WGL_BLUE_BITS_ARB, + WGL_ALPHA_BITS_ARB, + WGL_DOUBLE_BUFFER_ARB, + WGL_DEPTH_BITS_ARB, + WGL_STENCIL_BITS_ARB, + // WGL_ACCUM_*_BITS_ARB - not used + WGL_STEREO_ARB, + WGL_SAMPLE_BUFFERS_ARB, + WGL_SAMPLES_ARB, + // WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB - not used + WGL_ACCELERATION_ARB, + }; + enum { NUM_ATTRIBUTES = sizeof(queryAttributes)/sizeof(queryAttributes[0]) }; + int queryResults[NUM_ATTRIBUTES] = {}; + + win32.wglGetPixelFormatAttribivARB(win32.hDC, pfIdx, PFD_MAIN_PLANE, NUM_ATTRIBUTES, queryAttributes, queryResults); + + static int attribIList[2*NUM_ATTRIBUTES+2] = {}; // +2 for terminating 0, 0 pair + for(int i=0; iError("SDL_GetWindowWMInfo(), which is needed for Tools to work, failed!"); diff --git a/neo/sys/stub/stub_gl.cpp b/neo/sys/stub/stub_gl.cpp index 55a9b0de..1fb7dbdd 100644 --- a/neo/sys/stub/stub_gl.cpp +++ b/neo/sys/stub/stub_gl.cpp @@ -29,6 +29,13 @@ If you have questions concerning this license or the applicable additional terms #include "renderer/tr_local.h" +#ifdef _MSC_VER +#pragma warning(push) +// for each gl function we get an inconsistent dll linkage warning, because SDL_OpenGL.h says they're dllimport +// showing one warning is enough and it doesn't matter anyway (these stubs are for the dedicated server) +#pragma warning( once : 4273 ) +#endif + void APIENTRY glAccum(GLenum op, GLfloat value){}; void APIENTRY glAlphaFunc(GLenum func, GLclampf ref){}; GLboolean APIENTRY glAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences){ return false; }; @@ -388,3 +395,7 @@ void GLimp_SwapBuffers() {}; void GLimp_ActivateContext() {}; void GLimp_DeactivateContext() {}; void GLimp_GrabInput(int flags) {}; + +#ifdef _MSC_VER +#pragma warning(pop) +#endif diff --git a/neo/sys/win32/win_local.h b/neo/sys/win32/win_local.h index 637336dd..216fc483 100644 --- a/neo/sys/win32/win_local.h +++ b/neo/sys/win32/win_local.h @@ -64,7 +64,14 @@ struct Win32Vars_t { #ifdef ID_ALLOW_TOOLS HDC hDC; // handle to device HGLRC hGLRC; // handle to GL rendering context - PIXELFORMATDESCRIPTOR pfd; + PIXELFORMATDESCRIPTOR pfd; // for ChoosePixelFormat + const int* piAttribIList; // for wglChoosePixelFormatARB, if available, set in GLimp_Init() + + // the following are set in GLimp_Init() + BOOL(WINAPI *wglChoosePixelFormatARB) (HDC hdc, const int* piAttribIList, + const FLOAT* pfAttribFList, UINT nMaxFormats, int* piFormats, UINT* nNumFormats); + BOOL(WINAPI *wglGetPixelFormatAttribivARB) (HDC hdc, int iPixelFormat, + int iLayerPlane, UINT nAttributes, const int* piAttributes, int* piValues); #endif static idCVar win_outputDebugString; diff --git a/neo/sys/win32/win_main.cpp b/neo/sys/win32/win_main.cpp index 7da401d7..7d7c8cc7 100644 --- a/neo/sys/win32/win_main.cpp +++ b/neo/sys/win32/win_main.cpp @@ -66,16 +66,8 @@ Win32Vars_t win32; static HMODULE hOpenGL_DLL; -typedef int (WINAPI * PWGLCHOOSEPIXELFORMAT) (HDC, CONST PIXELFORMATDESCRIPTOR *); -typedef int (WINAPI * PWGLDESCRIBEPIXELFORMAT) (HDC, int, UINT, LPPIXELFORMATDESCRIPTOR); -typedef int (WINAPI * PWGLGETPIXELFORMAT)(HDC); -typedef BOOL(WINAPI * PWGLSETPIXELFORMAT)(HDC, int, CONST PIXELFORMATDESCRIPTOR *); typedef BOOL(WINAPI * PWGLSWAPBUFFERS)(HDC); -PWGLCHOOSEPIXELFORMAT qwglChoosePixelFormat; -PWGLDESCRIBEPIXELFORMAT qwglDescribePixelFormat; -PWGLGETPIXELFORMAT qwglGetPixelFormat; -PWGLSETPIXELFORMAT qwglSetPixelFormat; PWGLSWAPBUFFERS qwglSwapBuffers; typedef BOOL(WINAPI * PWGLCOPYCONTEXT)(HGLRC, HGLRC, UINT); @@ -602,7 +594,7 @@ uintptr_t Sys_DLL_Load( const char *dllName ) { } } else { DWORD e = GetLastError(); - LPVOID msgBuf = nullptr; + LPVOID msgBuf = NULL; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | @@ -731,10 +723,6 @@ void Sys_Shutdown( void ) { qwglSwapLayerBuffers = NULL; qwglUseFontBitmaps = NULL; qwglUseFontOutlines = NULL; - qwglChoosePixelFormat = NULL; - qwglDescribePixelFormat = NULL; - qwglGetPixelFormat = NULL; - qwglSetPixelFormat = NULL; qwglSwapBuffers = NULL; #endif // ID_ALLOW_TOOLS @@ -902,12 +890,27 @@ static void loadWGLpointers() { // These by default exist in windows - qwglChoosePixelFormat = ChoosePixelFormat; - qwglDescribePixelFormat = DescribePixelFormat; - qwglGetPixelFormat = GetPixelFormat; - qwglSetPixelFormat = SetPixelFormat; qwglSwapBuffers = SwapBuffers; } + +// calls wglChoosePixelFormatARB() or ChoosePixelFormat() matching the main window from SDL +int Win_ChoosePixelFormat(HDC hdc) +{ + if (win32.wglChoosePixelFormatARB != NULL && win32.piAttribIList != NULL) { + int formats[4]; + UINT numFormats = 0; + if (win32.wglChoosePixelFormatARB(hdc, win32.piAttribIList, NULL, 4, formats, &numFormats) && numFormats > 0) { + return formats[0]; + } + static bool haveWarned = false; + if(!haveWarned) { + common->Warning("wglChoosePixelFormatARB() failed, falling back to ChoosePixelFormat()!\n"); + haveWarned = true; + } + } + // fallback to normal ChoosePixelFormats() - doesn't support MSAA! + return ChoosePixelFormat(hdc, &win32.pfd); +} #endif /* diff --git a/neo/tools/guied/GEViewer.cpp b/neo/tools/guied/GEViewer.cpp index 94ac9b13..826631f2 100644 --- a/neo/tools/guied/GEViewer.cpp +++ b/neo/tools/guied/GEViewer.cpp @@ -453,7 +453,7 @@ bool rvGEViewer::SetupPixelFormat ( void ) HDC hDC = GetDC ( mWnd ); bool result = true; - int pixelFormat = ChoosePixelFormat(hDC, &win32.pfd); + int pixelFormat = Win_ChoosePixelFormat(hDC); if (pixelFormat > 0) { if (SetPixelFormat(hDC, pixelFormat, &win32.pfd) == NULL) diff --git a/neo/tools/guied/GEWorkspace.cpp b/neo/tools/guied/GEWorkspace.cpp index 0a4ece06..c5bcdac2 100644 --- a/neo/tools/guied/GEWorkspace.cpp +++ b/neo/tools/guied/GEWorkspace.cpp @@ -178,7 +178,7 @@ bool rvGEWorkspace::SetupPixelFormat ( void ) HDC hDC = GetDC ( mWnd ); bool result = true; - int pixelFormat = ChoosePixelFormat(hDC, &win32.pfd); + int pixelFormat = Win_ChoosePixelFormat(hDC); if (pixelFormat > 0) { if (SetPixelFormat(hDC, pixelFormat, &win32.pfd) == NULL) diff --git a/neo/tools/radiant/CamWnd.cpp b/neo/tools/radiant/CamWnd.cpp index f8804c71..1e073c39 100644 --- a/neo/tools/radiant/CamWnd.cpp +++ b/neo/tools/radiant/CamWnd.cpp @@ -360,7 +360,7 @@ int CCamWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) { if( qwglMakeCurrent ( hDC, win32.hGLRC ) == FALSE ) { common->Warning("wglMakeCurrent failed: %d", ::GetLastError()); if ( r_multiSamples.GetInteger() > 0 ) { - common->Warning("\n!!! Remember to set r_multiSamples 0 when using the editor !!!\n"); + common->Warning("\n!!! Try setting r_multiSamples 0 when using the editor !!!\n"); } } diff --git a/neo/tools/radiant/WIN_QE3.CPP b/neo/tools/radiant/WIN_QE3.CPP index 0ac00ae0..a2b08a39 100644 --- a/neo/tools/radiant/WIN_QE3.CPP +++ b/neo/tools/radiant/WIN_QE3.CPP @@ -176,7 +176,7 @@ int WINAPI QEW_SetupPixelFormat(HDC hDC, bool zbuffer) { #if 1 - int pixelFormat = ChoosePixelFormat(hDC, &win32.pfd); + int pixelFormat = Win_ChoosePixelFormat(hDC); if (pixelFormat > 0) { if (SetPixelFormat(hDC, pixelFormat, &win32.pfd) == NULL) { Error("SetPixelFormat failed.");