diff --git a/inc/render_ogl.h b/inc/render_ogl.h index 8dbb9a4..969c41a 100644 --- a/inc/render_ogl.h +++ b/inc/render_ogl.h @@ -9,6 +9,8 @@ typedef struct OGLRENDERER { + HWND hwnd; + HDC hdc; HGLRC context; GLuint main_program; GLuint shader1_program; @@ -42,5 +44,7 @@ typedef struct OGLRENDERER } OGLRENDERER; DWORD WINAPI ogl_render_main(void); +BOOL ogl_create(); +BOOL ogl_release(); #endif diff --git a/src/dd.c b/src/dd.c index c0ddbd4..6491f62 100644 --- a/src/dd.c +++ b/src/dd.c @@ -1013,6 +1013,15 @@ HRESULT dd_SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwFl g_ddraw.renderer = gdi_render_main; } } + else if (g_ddraw.renderer == ogl_render_main) + { + if (!ogl_create()) + { + ogl_release(); + g_ddraw.show_driver_warning = TRUE; + g_ddraw.renderer = gdi_render_main; + } + } if (lock_mouse || (g_config.fullscreen && real_GetForegroundWindow() == g_ddraw.hwnd)) mouse_lock(); @@ -1093,6 +1102,15 @@ HRESULT dd_SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwFl g_ddraw.renderer = gdi_render_main; } } + else if (g_ddraw.renderer == ogl_render_main) + { + if (!ogl_create()) + { + ogl_release(); + g_ddraw.show_driver_warning = TRUE; + g_ddraw.renderer = gdi_render_main; + } + } if (!d3d9_active || g_config.nonexclusive) { @@ -1485,6 +1503,11 @@ ULONG dd_Release() } } + if (g_ddraw.renderer == ogl_render_main) + { + ogl_release(); + } + if (g_ddraw.render.hdc) { ReleaseDC(g_ddraw.hwnd, g_ddraw.render.hdc); diff --git a/src/render_ogl.c b/src/render_ogl.c index 2242ca3..a56b295 100644 --- a/src/render_ogl.c +++ b/src/render_ogl.c @@ -13,26 +13,48 @@ static HGLRC ogl_create_core_context(HDC hdc); -static HGLRC ogl_create_context(HDC hdc); static void ogl_build_programs(); static void ogl_create_textures(int width, int height); static void ogl_init_main_program(); static void ogl_init_shader1_program(); static void ogl_init_shader2_program(); static void ogl_render(); -static void ogl_delete_context(HGLRC context); +static BOOL ogl_release_resources(); static BOOL ogl_texture_upload_test(); static BOOL ogl_shader_test(); static OGLRENDERER g_ogl; +BOOL ogl_create() +{ + if (g_ogl.hwnd == g_ddraw.hwnd && g_ogl.hdc == g_ddraw.render.hdc && g_ogl.context) + { + return TRUE; + } + + ogl_release(); + + g_ogl.context = xwglCreateContext(g_ddraw.render.hdc); + if (g_ogl.context) + { + g_ogl.hwnd = g_ddraw.hwnd; + g_ogl.hdc = g_ddraw.render.hdc; + + return TRUE; + } + + g_ogl.hwnd = NULL; + g_ogl.hdc = NULL; + + return FALSE; +} + DWORD WINAPI ogl_render_main(void) { Sleep(250); g_ogl.got_error = g_ogl.use_opengl = FALSE; - g_ogl.context = ogl_create_context(g_ddraw.render.hdc); - if (g_ogl.context) + if (xwglMakeCurrent(g_ogl.hdc, g_ogl.context) && glGetError() == GL_NO_ERROR) { oglu_init(); @@ -43,9 +65,9 @@ DWORD WINAPI ogl_render_main(void) TRACE("| GL_SHADING_LANGUAGE_VERSION: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); TRACE("+------------------------------------------------\n"); - g_ogl.context = ogl_create_core_context(g_ddraw.render.hdc); + g_ogl.context = ogl_create_core_context(g_ogl.hdc); - if (oglu_ext_exists("WGL_EXT_swap_control", g_ddraw.render.hdc) && wglSwapIntervalEXT) + if (oglu_ext_exists("WGL_EXT_swap_control", g_ogl.hdc) && wglSwapIntervalEXT) wglSwapIntervalEXT(g_config.vsync ? 1 : 0); fpsl_init(); @@ -62,9 +84,11 @@ DWORD WINAPI ogl_render_main(void) ogl_render(); - ogl_delete_context(g_ogl.context); + ogl_release_resources(); } + xwglMakeCurrent(NULL, NULL); + if (!g_ogl.use_opengl) { g_ddraw.show_driver_warning = TRUE; @@ -112,25 +136,6 @@ static HGLRC ogl_create_core_context(HDC hdc) return g_ogl.context; } -static HGLRC ogl_create_context(HDC hdc) -{ - HGLRC context = xwglCreateContext(hdc); - BOOL made_current = context && xwglMakeCurrent(hdc, context); - - if (!made_current || glGetError() != GL_NO_ERROR) - { - if (made_current) - { - xwglMakeCurrent(NULL, NULL); - xwglDeleteContext(context); - } - - context = 0; - } - - return context; -} - static void ogl_build_programs() { g_ogl.main_program = g_ogl.shader1_program = g_ogl.shader2_program = 0; @@ -1200,7 +1205,7 @@ static void ogl_render() if (g_ddraw.bnet_active) glClear(GL_COLOR_BUFFER_BIT); - SwapBuffers(g_ddraw.render.hdc); + SwapBuffers(g_ogl.hdc); if (!g_ddraw.render.run) break; @@ -1216,7 +1221,7 @@ static void ogl_render() InterlockedExchange(&g_ddraw.upscale_hack_active, FALSE); } -static void ogl_delete_context(HGLRC context) +static BOOL ogl_release_resources() { glDeleteTextures(TEXTURE_COUNT, g_ogl.surface_tex_ids); @@ -1273,8 +1278,22 @@ static void ogl_delete_context(HGLRC context) } } - xwglMakeCurrent(NULL, NULL); - xwglDeleteContext(context); + return TRUE; +} + +BOOL ogl_release() +{ + if (g_ddraw.render.thread) + return FALSE; + + if (g_ogl.context) + { + xwglMakeCurrent(NULL, NULL); + xwglDeleteContext(g_ogl.context); + g_ogl.context = NULL; + } + + return TRUE; } static BOOL ogl_texture_upload_test() diff --git a/src/winapi_hooks.c b/src/winapi_hooks.c index d260b22..b856f0e 100644 --- a/src/winapi_hooks.c +++ b/src/winapi_hooks.c @@ -12,6 +12,7 @@ #include "wndproc.h" #include "render_gdi.h" #include "render_d3d9.h" +#include "render_ogl.h" #include "directinput.h" #include "ddsurface.h" #include "ddclipper.h" @@ -1479,6 +1480,10 @@ BOOL WINAPI fake_DestroyWindow(HWND hWnd) { d3d9_release(); } + else if (g_ddraw.renderer == ogl_render_main) + { + ogl_release(); + } } BOOL result = real_DestroyWindow(hWnd);