diff --git a/gzdoom.vcproj b/gzdoom.vcproj index e24992960..b7e52df62 100644 --- a/gzdoom.vcproj +++ b/gzdoom.vcproj @@ -1,7 +1,7 @@ + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + @@ -1847,14 +1855,6 @@ Outputs="$(IntDir)/$(InputName).obj" /> - - - @@ -2231,7 +2231,7 @@ /> - - - @@ -2460,6 +2452,14 @@ AdditionalIncludeDirectories="src\win32;$(NoInherit)" /> + + + @@ -2774,7 +2774,7 @@ /> - - - + + + + + + + + + + + + + + + + + + + @@ -3234,7 +3274,7 @@ /> - - - + + + m_Extensions; -#if !defined (unix) && !defined (__APPLE__) -HWND m_Window; -HDC m_hDC; -HGLRC m_hRC; -#endif - #define gl pgl RenderContext * gl; @@ -71,143 +60,6 @@ RenderContext * gl; int occlusion_type=0; -//========================================================================== -// -// -// -//========================================================================== - -#if !defined (unix) && !defined (__APPLE__) -static HWND 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; -} - -//========================================================================== -// -// -// -//========================================================================== - -static void ShutdownDummy(HWND dummy) -{ - DestroyWindow(dummy); - UnregisterClass("GZDoomOpenGLDummyWindow", GetModuleHandle(NULL)); -} - - -//========================================================================== -// -// -// -//========================================================================== - -static bool ReadInitExtensions() -{ - 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); - - wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); - wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB"); - // any extra stuff here? - - wglMakeCurrent(NULL, NULL); - wglDeleteContext(hRC); - ReleaseDC(dummy, hDC); - ShutdownDummy(dummy); - - return true; -} -#endif //========================================================================== // @@ -296,12 +148,6 @@ static void APIENTRY LoadExtensions() if (strcmp(version, "2.1") >= 0) gl->flags|=RFL_GL_21; if (strcmp(version, "3.0") >= 0) gl->flags|=RFL_GL_30; - -#if !defined (unix) && !defined (__APPLE__) - PFNWGLSWAPINTERVALEXTPROC vs = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); - if (vs) gl->SetVSync = vs; -#endif - glGetIntegerv(GL_MAX_TEXTURE_SIZE,&gl->max_texturesize); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); @@ -437,21 +283,6 @@ static void APIENTRY LoadExtensions() gl->flags|=RFL_FRAMEBUFFER; } -#if 0 - else if (CheckExtension("GL_EXT_framebuffer_object") && - CheckExtension("GL_EXT_packed_depth_stencil")) - { - gl->GenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)wglGetProcAddress("glGenFramebuffersEXT"); - gl->BindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress("glBindFramebufferEXT"); - gl->FramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)wglGetProcAddress("glFramebufferTexture2DEXT"); - gl->GenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)wglGetProcAddress("glGenRenderbuffersEXT"); - gl->BindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)wglGetProcAddress("glBindRenderbufferEXT"); - gl->RenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)wglGetProcAddress("glRenderbufferStorageEXT"); - gl->FramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)wglGetProcAddress("glFramebufferRenderbufferEXT"); - - gl->flags|=RFL_FRAMEBUFFER; - } -#endif #if 0 if (CheckExtension("GL_ARB_texture_buffer_object") && @@ -509,372 +340,6 @@ static void APIENTRY PrintStartupLog() // //========================================================================== -#if !defined (unix) && !defined (__APPLE__) -static bool SetupPixelFormat(HDC hDC, bool allowsoftware, bool nostencil, int multisample) -{ - int colorDepth; - HDC deskDC; - int attributes[26]; - int pixelFormat; - unsigned int numFormats; - float attribsFloat[] = {0.0f, 0.0f}; - int stencil; - - deskDC = GetDC(GetDesktopWindow()); - colorDepth = GetDeviceCaps(deskDC, BITSPIXEL); - ReleaseDC(GetDesktopWindow(), deskDC); - - /* - if (!nostencil && colorDepth < 32) - { - Printf("R_OPENGL: Desktop not in 32 bit mode!\n"); - return false; - } - */ - - if (!nostencil) - { - for (stencil=1;stencil>=0;stencil--) - { - if (wglChoosePixelFormatARB && stencil) - { - 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; - - attributes[18] = WGL_ACCELERATION_ARB; //required to be FULL_ACCELERATION_ARB - if (allowsoftware) - { - attributes[19] = WGL_NO_ACCELERATION_ARB; - } - else - { - attributes[19] = WGL_FULL_ACCELERATION_ARB; - } - - if (multisample > 0) - { - attributes[20] = WGL_SAMPLE_BUFFERS_ARB; - attributes[21] = true; - attributes[22] = WGL_SAMPLES_ARB; - attributes[23] = multisample; - } - else - { - attributes[20] = 0; - attributes[21] = 0; - attributes[22] = 0; - attributes[23] = 0; - } - - attributes[24] = 0; - attributes[25] = 0; - - if (!wglChoosePixelFormatARB(hDC, attributes, attribsFloat, 1, &pixelFormat, &numFormats)) - { - Printf("R_OPENGL: Couldn't choose pixel format. Retrying in compatibility mode\n"); - goto oldmethod; - } - - if (numFormats == 0) - { - Printf("R_OPENGL: No valid pixel formats found. Retrying in compatibility mode\n"); - goto oldmethod; - } - - break; - } - 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 - stencil*8, // stencil buffer - 0, - PFD_MAIN_PLANE, - 0, - 0, 0, 0 - }; - - pixelFormat = ChoosePixelFormat(hDC, &pfd); - DescribePixelFormat(hDC, pixelFormat, sizeof(pfd), &pfd); - - if (pfd.dwFlags & PFD_GENERIC_FORMAT) - { - if (!allowsoftware) - { - if (stencil==0) - { - // not accelerated! - Printf("R_OPENGL: OpenGL driver not accelerated! Falling back to software renderer.\n"); - return false; - } - else - { - Printf("R_OPENGL: OpenGL driver not accelerated! Retrying in compatibility mode\n"); - continue; - } - } - } - break; - } - } - } - else - { - // Use the cheapest mode available and let's hope the driver can handle this... - stencil=0; - - // 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, - 16, // 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 - }; - - pixelFormat = ChoosePixelFormat(hDC, &pfd); - DescribePixelFormat(hDC, pixelFormat, sizeof(pfd), &pfd); - - if (pfd.dwFlags & PFD_GENERIC_FORMAT) - { - if (!allowsoftware) - { - Printf("R_OPENGL: OpenGL driver not accelerated! Falling back to software renderer.\n"); - return false; - } - } - } - if (stencil==0) - { - gl->flags|=RFL_NOSTENCIL; - } - - if (!SetPixelFormat(hDC, pixelFormat, NULL)) - { - Printf("R_OPENGL: Couldn't set pixel format.\n"); - return false; - } - return true; -} -#else - -static bool SetupPixelFormat(bool allowsoftware, bool nostencil, int multisample) -{ - int stencil; - - if (!nostencil) - { - stencil=1; - SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 ); - SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 ); - SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 ); - SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8 ); - SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 24 ); - SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 8 ); -// SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); - if (multisample > 0) { - SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1 ); - SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, multisample ); - } - } - else - { - // Use the cheapest mode available and let's hope the driver can handle this... - stencil=0; - - SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 4 ); - SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 4 ); - SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 4 ); - SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 4 ); - SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 ); - //SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 )*/ - } - if (stencil==0) - { - gl->flags|=RFL_NOSTENCIL; - } - return true; -} -#endif - - -//========================================================================== -// -// -// -//========================================================================== - -#if !defined (unix) && !defined (__APPLE__) -CVAR(Bool, gl_debug, false, 0) - -static bool APIENTRY InitHardware (HWND Window, bool allowsoftware, bool nostencil, int multisample) -{ - m_Window=Window; - m_hDC = GetDC(Window); - - if (!SetupPixelFormat(m_hDC, allowsoftware, nostencil, multisample)) - { - Printf ("R_OPENGL: Reverting to software mode...\n"); - return false; - } - - m_hRC = 0; - if (wglCreateContextAttribsARB != NULL) - { - int ctxAttribs[] = { - WGL_CONTEXT_MAJOR_VERSION_ARB, 3, - WGL_CONTEXT_MINOR_VERSION_ARB, 3, - WGL_CONTEXT_FLAGS_ARB, gl_debug? WGL_CONTEXT_DEBUG_BIT_ARB : 0, - WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, - 0 - }; - - m_hRC = wglCreateContextAttribsARB(m_hDC, 0, ctxAttribs); - } - if (m_hRC == 0) - { - m_hRC = wglCreateContext(m_hDC); - } - - if (m_hRC == NULL) - { - Printf ("R_OPENGL: Couldn't create render context. Reverting to software mode...\n"); - return false; - } - - wglMakeCurrent(m_hDC, m_hRC); - return true; -} - -#else -static bool APIENTRY InitHardware (bool allowsoftware, bool nostencil, int multisample) -{ - if (!SetupPixelFormat(allowsoftware, nostencil, multisample)) - { - Printf ("R_OPENGL: Reverting to software mode...\n"); - return false; - } - return true; -} -#endif - - -//========================================================================== -// -// -// -//========================================================================== - -#if !defined (unix) && !defined (__APPLE__) -static void APIENTRY Shutdown() -{ - if (m_hRC) - { - wglMakeCurrent(0, 0); - wglDeleteContext(m_hRC); - } - if (m_hDC) ReleaseDC(m_Window, m_hDC); -} - - -static bool APIENTRY SetFullscreen(const char *devicename, int w, int h, int bits, int hz) -{ - DEVMODE dm; - - if (w==0) - { - ChangeDisplaySettingsEx(devicename, 0, 0, 0, 0); - } - else - { - dm.dmSize = sizeof(DEVMODE); - dm.dmSpecVersion = DM_SPECVERSION;//Somebody owes me... - dm.dmDriverExtra = 0;//...1 hour of my life back - dm.dmPelsWidth = w; - dm.dmPelsHeight = h; - dm.dmBitsPerPel = bits; - dm.dmDisplayFrequency = hz; - dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY; - if (DISP_CHANGE_SUCCESSFUL != ChangeDisplaySettingsEx(devicename, &dm, 0, CDS_FULLSCREEN, 0)) - { - dm.dmFields &= ~DM_DISPLAYFREQUENCY; - return DISP_CHANGE_SUCCESSFUL == ChangeDisplaySettingsEx(devicename, &dm, 0, CDS_FULLSCREEN, 0); - } - } - return true; -} -#endif -//========================================================================== -// -// -// -//========================================================================== - -static void APIENTRY iSwapBuffers() -{ -#if !defined (unix) && !defined (__APPLE__) - SwapBuffers(m_hDC); -#else - SDL_GL_SwapBuffers (); -#endif -} - -static BOOL APIENTRY SetVSync( int vsync ) -{ -#if defined (__APPLE__) - return kCGLNoError == CGLSetParameter( CGLGetCurrentContext(), kCGLCPSwapInterval, &vsync ); -#else // !__APPLE__ - // empty placeholder - return false; -#endif // __APPLE__ -} - -//========================================================================== -// -// -// -//========================================================================== - static void APIENTRY glBlendEquationDummy (GLenum mode) { // If this is not supported all non-existent modes are @@ -969,12 +434,6 @@ static void APIENTRY SetTextureMode(int type) // //========================================================================== -/* -extern "C" -{ - -__declspec(dllexport) -*/ void APIENTRY GetContext(RenderContext & gl) { ::gl=≷ @@ -984,14 +443,6 @@ void APIENTRY GetContext(RenderContext & gl) gl.LoadExtensions = LoadExtensions; gl.SetTextureMode = SetTextureMode; gl.PrintStartupLog = PrintStartupLog; - gl.InitHardware = InitHardware; -#if !defined (unix) && !defined (__APPLE__) - gl.Shutdown = Shutdown; -#endif - gl.SwapBuffers = iSwapBuffers; -#if !defined (unix) && !defined (__APPLE__) - gl.SetFullscreen = SetFullscreen; -#endif gl.Begin = glBegin; gl.End = glEnd; @@ -1069,13 +520,6 @@ void APIENTRY GetContext(RenderContext & gl) gl.Flush = glFlush; gl.BlendEquation = glBlendEquationDummy; - gl.SetVSync = SetVSync; - -#if !defined (unix) && !defined (__APPLE__) - ReadInitExtensions(); - //GL is not yet inited in UNIX version, read them later in LoadExtensions -#endif - } diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index a6c583343..5473f3e03 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -70,16 +70,6 @@ struct RenderContext void (APIENTRY * LoadExtensions) (); void (APIENTRY * SetTextureMode) (int type); void (APIENTRY * PrintStartupLog) (); - BOOL (APIENTRY * SetVSync) (int on); -#if !defined (unix) && !defined (__APPLE__) - bool (APIENTRY * InitHardware) (HWND, bool allowsoftware, bool nostencil, int multisample); - void (APIENTRY * Shutdown) (); -#else - bool (APIENTRY * InitHardware) (bool allowsoftware, bool nostencil, int multisample); -#endif - void (APIENTRY * SwapBuffers) (); - bool (APIENTRY * SetFullscreen) (const char *devicename, int w, int h, int bits, int hz); - void (APIENTRY * Begin) (GLenum mode); void (APIENTRY * End) (void); @@ -247,8 +237,6 @@ struct RenderContext }; -typedef void (APIENTRY * GetContextProc)(RenderContext & gl); - void APIENTRY GetContext(RenderContext & gl); #endif diff --git a/src/gl/system/gl_system.h b/src/gl/system/gl_system.h index 5dc6cf5b5..d2430bd63 100644 --- a/src/gl/system/gl_system.h +++ b/src/gl/system/gl_system.h @@ -5,8 +5,10 @@ //#define __wtypes_h__ #define WIN32_LEAN_AND_MEAN #define _WIN32_WINDOWS 0x410 +#ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0501 // Support the mouse wheel and session notification. #define _WIN32_IE 0x0500 +#endif #define DIRECTINPUT_VERSION 0x800 #define DIRECTDRAW_VERSION 0x0300 diff --git a/src/sdl/sdlglvideo.cpp b/src/sdl/sdlglvideo.cpp index 9ee54b4e8..3285b8ed5 100644 --- a/src/sdl/sdlglvideo.cpp +++ b/src/sdl/sdlglvideo.cpp @@ -279,6 +279,67 @@ bool SDLGLVideo::SetResolution (int width, int height, int bits) return true; // We must return true because the old video context no longer exists. } +//========================================================================== +// +// +// +//========================================================================== + +bool SDLGLVideo::SetupPixelFormat(bool allowsoftware, bool nostencil, int multisample) +{ + int stencil; + + if (!nostencil) + { + stencil=1; + SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 ); + SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 ); + SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 ); + SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8 ); + SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 24 ); + SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 8 ); +// SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + if (multisample > 0) { + SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1 ); + SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, multisample ); + } + } + else + { + // Use the cheapest mode available and let's hope the driver can handle this... + stencil=0; + + SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 4 ); + SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 4 ); + SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 4 ); + SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 4 ); + SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 ); + //SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 )*/ + } + if (stencil==0) + { + gl.flags|=RFL_NOSTENCIL; + } + return true; +} + +//========================================================================== +// +// +// +//========================================================================== + +bool SDLGLVideo::InitHardware (bool allowsoftware, bool nostencil, int multisample) +{ + if (!SetupPixelFormat(allowsoftware, nostencil, multisample)) + { + Printf ("R_OPENGL: Reverting to software mode...\n"); + return false; + } + return true; +} + + // FrameBuffer implementation ----------------------------------------------- SDLGLFB::SDLGLFB (void *, int width, int height, int, int, bool fullscreen) @@ -294,7 +355,7 @@ SDLGLFB::SDLGLFB (void *, int width, int height, int, int, bool fullscreen) UpdatePending = false; - if (!gl.InitHardware(false, gl_vid_compatibility, localmultisample)) + if (!static_cast(Video)->InitHardware(false, gl_vid_compatibility, localmultisample)) { vid_renderer = 0; return; @@ -335,6 +396,9 @@ SDLGLFB::~SDLGLFB () } } + + + void SDLGLFB::InitializeState() { int value = 0; @@ -417,3 +481,8 @@ void SDLGLFB::NewRefreshRate () { } +void SDLGLFB::SwapBuffers() +{ + SDL_GL_SwapBuffers (); +} + diff --git a/src/sdl/sdlglvideo.h b/src/sdl/sdlglvideo.h index 35175e421..4fbdf3e9a 100644 --- a/src/sdl/sdlglvideo.h +++ b/src/sdl/sdlglvideo.h @@ -27,6 +27,9 @@ class SDLGLVideo : public IVideo bool NextMode (int *width, int *height, bool *letterbox); bool SetResolution (int width, int height, int bits); + bool SetupPixelFormat(bool allowsoftware, bool nostencil, int multisample); + bool InitHardware (bool allowsoftware, bool nostencil, int multisample); + private: int IteratorMode; int IteratorBits; @@ -50,6 +53,7 @@ public: bool IsFullscreen (); virtual void SetVSync( bool vsync ); + void SwapBuffers(); void NewRefreshRate (); diff --git a/src/win32/hardware.cpp b/src/win32/hardware.cpp index cd009c206..e9d1bc5e6 100644 --- a/src/win32/hardware.cpp +++ b/src/win32/hardware.cpp @@ -56,12 +56,15 @@ EXTERN_CVAR (Float, vid_winscale) CVAR(Int, win_x, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Int, win_y, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -#include "win32gliface.h" +extern HWND Window; bool ForceWindowed; IVideo *Video; +// do not include GL headers here, only declare the necessary functions. +IVideo *gl_CreateVideo(); +FRenderer *gl_CreateInterface(); void I_RestartRenderer(); int currentrenderer = -1; @@ -134,7 +137,7 @@ void I_InitGraphics () ticker.SetGenericRepDefault (val, CVAR_Bool); //currentrenderer = vid_renderer; - if (currentrenderer==1) Video = new Win32GLVideo(0); + if (currentrenderer==1) Video = gl_CreateVideo(); else Video = new Win32Video (0); if (Video == NULL) diff --git a/src/win32/win32gliface.cpp b/src/win32/win32gliface.cpp index af6bf42cd..e13dce63d 100644 --- a/src/win32/win32gliface.cpp +++ b/src/win32/win32gliface.cpp @@ -27,6 +27,8 @@ CUSTOM_CVAR(Int, gl_vid_multisample, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_ Printf("This won't take effect until "GAMENAME" is restarted.\n"); } +CVAR(Bool, gl_debug, false, 0) + RenderContext gl; @@ -53,6 +55,7 @@ Win32GLVideo::Win32GLVideo(int parm) : m_Modes(NULL), m_IsFullscreen(false) GetDisplayDeviceName(); MakeModesList(); GetContext(gl); + SetPixelFormat(); } @@ -314,11 +317,11 @@ bool Win32GLVideo::GoFullscreen(bool yes) if (yes) { - gl.SetFullscreen(m_DisplayDeviceName, m_DisplayWidth, m_trueHeight, m_DisplayBits, m_DisplayHz); + SetFullscreen(m_DisplayDeviceName, m_DisplayWidth, m_trueHeight, m_DisplayBits, m_DisplayHz); } else { - gl.SetFullscreen(m_DisplayDeviceName, 0,0,0,0); + SetFullscreen(m_DisplayDeviceName, 0,0,0,0); } return yes; } @@ -465,6 +468,429 @@ void Win32GLVideo::DumpAdapters() // //========================================================================== +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); + + wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); + wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB"); + // any extra stuff here? + + wglMakeCurrent(NULL, NULL); + wglDeleteContext(hRC); + ReleaseDC(dummy, hDC); + ShutdownDummy(dummy); + + return true; +} + +//========================================================================== +// +// +// +//========================================================================== + +bool Win32GLVideo::SetupPixelFormat(bool allowsoftware, bool nostencil, int multisample) +{ + int colorDepth; + HDC deskDC; + int attributes[26]; + int pixelFormat; + unsigned int numFormats; + float attribsFloat[] = {0.0f, 0.0f}; + int stencil; + + deskDC = GetDC(GetDesktopWindow()); + colorDepth = GetDeviceCaps(deskDC, BITSPIXEL); + ReleaseDC(GetDesktopWindow(), deskDC); + + /* + if (!nostencil && colorDepth < 32) + { + Printf("R_OPENGL: Desktop not in 32 bit mode!\n"); + return false; + } + */ + + if (!nostencil) + { + for (stencil=1;stencil>=0;stencil--) + { + if (wglChoosePixelFormatARB && stencil) + { + 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; + + attributes[18] = WGL_ACCELERATION_ARB; //required to be FULL_ACCELERATION_ARB + if (allowsoftware) + { + attributes[19] = WGL_NO_ACCELERATION_ARB; + } + else + { + attributes[19] = WGL_FULL_ACCELERATION_ARB; + } + + if (multisample > 0) + { + attributes[20] = WGL_SAMPLE_BUFFERS_ARB; + attributes[21] = true; + attributes[22] = WGL_SAMPLES_ARB; + attributes[23] = multisample; + } + else + { + attributes[20] = 0; + attributes[21] = 0; + attributes[22] = 0; + attributes[23] = 0; + } + + attributes[24] = 0; + attributes[25] = 0; + + if (!wglChoosePixelFormatARB(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) + { + Printf("R_OPENGL: No valid pixel formats found. Retrying in compatibility mode\n"); + goto oldmethod; + } + + break; + } + 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 + stencil*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) + { + if (!allowsoftware) + { + if (stencil==0) + { + // not accelerated! + Printf("R_OPENGL: OpenGL driver not accelerated! Falling back to software renderer.\n"); + return false; + } + else + { + Printf("R_OPENGL: OpenGL driver not accelerated! Retrying in compatibility mode\n"); + continue; + } + } + } + break; + } + } + } + else + { + // Use the cheapest mode available and let's hope the driver can handle this... + stencil=0; + + // 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, + 16, // 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 + }; + + pixelFormat = ChoosePixelFormat(m_hDC, &pfd); + DescribePixelFormat(m_hDC, pixelFormat, sizeof(pfd), &pfd); + + if (pfd.dwFlags & PFD_GENERIC_FORMAT) + { + if (!allowsoftware) + { + Printf("R_OPENGL: OpenGL driver not accelerated! Falling back to software renderer.\n"); + return false; + } + } + } + if (stencil==0) + { + gl.flags|=RFL_NOSTENCIL; + } + + if (!::SetPixelFormat(m_hDC, pixelFormat, NULL)) + { + Printf("R_OPENGL: Couldn't set pixel format.\n"); + return false; + } + return true; +} + +//========================================================================== +// +// +// +//========================================================================== + +bool Win32GLVideo::InitHardware (HWND Window, bool allowsoftware, bool nostencil, int multisample) +{ + m_Window=Window; + m_hDC = GetDC(Window); + + if (!SetupPixelFormat(allowsoftware, nostencil, multisample)) + { + Printf ("R_OPENGL: Reverting to software mode...\n"); + return false; + } + + m_hRC = 0; + if (wglCreateContextAttribsARB != NULL) + { + int ctxAttribs[] = { + WGL_CONTEXT_MAJOR_VERSION_ARB, 3, + WGL_CONTEXT_MINOR_VERSION_ARB, 3, + WGL_CONTEXT_FLAGS_ARB, gl_debug? WGL_CONTEXT_DEBUG_BIT_ARB : 0, + WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, + 0 + }; + + m_hRC = wglCreateContextAttribsARB(m_hDC, 0, ctxAttribs); + } + if (m_hRC == 0) + { + m_hRC = wglCreateContext(m_hDC); + } + + if (m_hRC == NULL) + { + Printf ("R_OPENGL: Couldn't create render context. Reverting to software mode...\n"); + return false; + } + + wglMakeCurrent(m_hDC, m_hRC); + return true; +} + +//========================================================================== +// +// +// +//========================================================================== + +void Win32GLVideo::Shutdown() +{ + if (m_hRC) + { + wglMakeCurrent(0, 0); + wglDeleteContext(m_hRC); + } + if (m_hDC) ReleaseDC(m_Window, m_hDC); +} + +//========================================================================== +// +// +// +//========================================================================== + +bool Win32GLVideo::SetFullscreen(const char *devicename, int w, int h, int bits, int hz) +{ + DEVMODE dm; + + if (w==0) + { + ChangeDisplaySettingsEx(devicename, 0, 0, 0, 0); + } + else + { + dm.dmSize = sizeof(DEVMODE); + dm.dmSpecVersion = DM_SPECVERSION;//Somebody owes me... + dm.dmDriverExtra = 0;//...1 hour of my life back + dm.dmPelsWidth = w; + dm.dmPelsHeight = h; + dm.dmBitsPerPel = bits; + dm.dmDisplayFrequency = hz; + dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY; + if (DISP_CHANGE_SUCCESSFUL != ChangeDisplaySettingsEx(devicename, &dm, 0, CDS_FULLSCREEN, 0)) + { + dm.dmFields &= ~DM_DISPLAYFREQUENCY; + return DISP_CHANGE_SUCCESSFUL == ChangeDisplaySettingsEx(devicename, &dm, 0, CDS_FULLSCREEN, 0); + } + } + return true; +} + +//========================================================================== +// +// +// +//========================================================================== + IMPLEMENT_ABSTRACT_CLASS(Win32GLFrameBuffer) //========================================================================== @@ -528,7 +954,7 @@ Win32GLFrameBuffer::Win32GLFrameBuffer(void *hMonitor, int width, int height, in if (fullscreen) { - MoveWindow(Window, monX, monY, width, static_cast(Video)->GetTrueHeight(), FALSE); + MoveWindow(Window, monX, monY, width, GetTrueHeight(), FALSE); // And now, seriously, it IS in the right place. Promise. } @@ -539,12 +965,14 @@ Win32GLFrameBuffer::Win32GLFrameBuffer(void *hMonitor, int width, int height, in I_RestoreWindowedPos(); } - if (!gl.InitHardware(Window, false, gl_vid_compatibility, localmultisample)) + if (!static_cast(Video)->InitHardware(Window, false, gl_vid_compatibility, localmultisample)) { vid_renderer = 0; return; } + vsyncfunc = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); + HDC hDC = GetDC(Window); m_supportsGamma = !!GetDeviceGammaRamp(hDC, (void *)m_origGamma); ReleaseDC(Window, hDC); @@ -566,7 +994,7 @@ Win32GLFrameBuffer::~Win32GLFrameBuffer() } I_SaveWindowedPos(); - gl.SetFullscreen(m_displayDeviceName, 0,0,0,0); + static_cast(Video)->SetFullscreen(m_displayDeviceName, 0,0,0,0); ShowWindow (Window, SW_SHOW); SetWindowLong(Window, GWL_STYLE, WS_VISIBLE | WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW); @@ -574,7 +1002,7 @@ Win32GLFrameBuffer::~Win32GLFrameBuffer() SetWindowPos(Window, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); I_GetEvent(); - gl.Shutdown(); + static_cast(Video)->Shutdown(); } @@ -692,7 +1120,12 @@ void Win32GLFrameBuffer::ReleaseResources () void Win32GLFrameBuffer::SetVSync (bool vsync) { - if (gl.SetVSync!=NULL) gl.SetVSync(vsync); + if (vsyncfunc != NULL) vsyncfunc(vsync); +} + +void Win32GLFrameBuffer::SwapBuffers() +{ + ::SwapBuffers(static_cast(Video)->m_hDC); } //========================================================================== @@ -712,3 +1145,8 @@ void Win32GLFrameBuffer::NewRefreshRate () } } + +IVideo *gl_CreateVideo() +{ + return new Win32GLVideo(0); +} \ No newline at end of file diff --git a/src/win32/win32gliface.h b/src/win32/win32gliface.h index ba4ea001d..e4d70ba43 100644 --- a/src/win32/win32gliface.h +++ b/src/win32/win32gliface.h @@ -1,17 +1,9 @@ #ifndef __WIN32GLIFACE_H__ #define __WIN32GLIFACE_H__ -/* -#define WIN32_LEAN_AND_MEAN -#include -#include - -#include "gl/glext.h" -#include "gl/wglext.h" -*/ - -#include "win32iface.h" +#include "gl/system/gl_system.h" #include "hardware.h" +#include "win32iface.h" #include "v_video.h" #include "tarray.h" @@ -50,6 +42,13 @@ public: DFrameBuffer *CreateFrameBuffer (int width, int height, bool fs, DFrameBuffer *old); virtual bool SetResolution (int width, int height, int bits); void DumpAdapters(); + bool InitHardware (HWND Window, bool allowsoftware, bool nostencil, int multisample); + void Shutdown(); + bool SetFullscreen(const char *devicename, int w, int h, int bits, int hz); + + PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB; // = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); + PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB; + HDC m_hDC; protected: struct ModeInfo @@ -78,6 +77,14 @@ protected: char *m_DisplayDeviceName; HMONITOR m_hMonitor; + HWND m_Window; + HGLRC m_hRC; + + HWND InitDummy(); + void ShutdownDummy(HWND dummy); + bool SetPixelFormat(); + bool SetupPixelFormat(bool allowsoftware, bool nostencil, int multisample); + void GetDisplayDeviceName(); void MakeModesList(); void AddMode(int x, int y, int bits, int baseHeight, int refreshHz); @@ -100,6 +107,8 @@ public: Win32GLFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen); virtual ~Win32GLFrameBuffer(); + PFNWGLSWAPINTERVALEXTPROC vsyncfunc; + // unused but must be defined virtual void Blank (); virtual bool PaintToWindow (); @@ -109,10 +118,11 @@ public: virtual void ReleaseResources (); void SetVSync (bool vsync); + void SwapBuffers(); void NewRefreshRate (); - int GetTrueHeight() { return static_cast(Video)->GetTrueHeight(); } + int GetTrueHeight() { return static_cast(Video)->GetTrueHeight(); } bool Lock(bool buffered); bool Lock ();