diff options
Diffstat (limited to 'src/osd/modules/render/winglcontext.h')
-rw-r--r-- | src/osd/modules/render/winglcontext.h | 201 |
1 files changed, 115 insertions, 86 deletions
diff --git a/src/osd/modules/render/winglcontext.h b/src/osd/modules/render/winglcontext.h index f0cb1b6af77..48d1462d2f6 100644 --- a/src/osd/modules/render/winglcontext.h +++ b/src/osd/modules/render/winglcontext.h @@ -7,168 +7,197 @@ // SDLMAME by Olivier Galibert and R. Belmont // //============================================================ +#ifndef MAME_RENDER_WINGLCONTEXT_H +#define MAME_RENDER_WINGLCONTEXT_H #pragma once -#ifndef __WIN_GL_CONTEXT__ -#define __WIN_GL_CONTEXT__ - #include "modules/opengl/osd_opengl.h" #include "modules/lib/osdlib.h" -// Typedefs for dynamically loaded functions -typedef PROC (WINAPI *wglGetProcAddress_fn)(LPCSTR); -typedef HGLRC (WINAPI *wglCreateContext_fn)(HDC); -typedef BOOL (WINAPI *wglDeleteContext_fn)(HGLRC); -typedef BOOL (WINAPI *wglMakeCurrent_fn)(HDC, HGLRC); +#include "strconv.h" + +#include <cstring> +#include <string> -typedef const char * (WINAPI *wglGetExtensionsStringEXT_fn)(void); -typedef BOOL (WINAPI *wglSwapIntervalEXT_fn)(int); -typedef int (WINAPI *wglGetSwapIntervalEXT_fn)(void); class win_gl_context : public osd_gl_context { public: - win_gl_context(HWND window) : osd_gl_context(), m_context(0), m_window(nullptr), m_hdc(0) - { - m_error[0] = 0; + using osd_gl_context::get_proc_address; + win_gl_context(HWND window) : m_context(nullptr), m_window(window), m_hdc(nullptr) + { + // open DLL and bind required functions opengl32_dll = osd::dynamic_module::open({ "opengl32.dll" }); - pfn_wglGetProcAddress = opengl32_dll->bind<wglGetProcAddress_fn>("wglGetProcAddress"); pfn_wglCreateContext = opengl32_dll->bind<wglCreateContext_fn>("wglCreateContext"); pfn_wglDeleteContext = opengl32_dll->bind<wglDeleteContext_fn>("wglDeleteContext"); pfn_wglMakeCurrent = opengl32_dll->bind<wglMakeCurrent_fn>("wglMakeCurrent"); + if (!pfn_wglGetProcAddress || !pfn_wglCreateContext || !pfn_wglDeleteContext || !pfn_wglMakeCurrent) + return; - if (pfn_wglGetProcAddress == nullptr || pfn_wglCreateContext == nullptr || - pfn_wglDeleteContext == nullptr || pfn_wglMakeCurrent == nullptr) + m_hdc = GetDC(window); + if (!m_hdc) { + get_last_error_string(); return; } - pfn_wglGetExtensionsStringEXT = (wglGetExtensionsStringEXT_fn)(*pfn_wglGetProcAddress)("wglGetExtensionsStringEXT"); + if (setupPixelFormat()) + { + m_context = (*pfn_wglCreateContext)(m_hdc); + if (!m_context) + get_last_error_string(); + } + if (!m_context) + return; + + (*pfn_wglMakeCurrent)(m_hdc, m_context); + get_proc_address(pfn_wglGetExtensionsStringEXT, "wglGetExtensionsStringEXT"); if (WGLExtensionSupported("WGL_EXT_swap_control")) { - pfn_wglSwapIntervalEXT = (BOOL (WINAPI *) (int)) getProcAddress("wglSwapIntervalEXT"); - pfn_wglGetSwapIntervalEXT = (int (WINAPI *) (void)) getProcAddress("wglGetSwapIntervalEXT"); + get_proc_address(pfn_wglSwapIntervalEXT, "wglSwapIntervalEXT"); + get_proc_address(pfn_wglGetSwapIntervalEXT, "wglGetSwapIntervalEXT"); } else { pfn_wglSwapIntervalEXT = nullptr; pfn_wglGetSwapIntervalEXT = nullptr; } - - m_hdc = GetDC(window); - if (!setupPixelFormat(m_hdc)) - { - m_context = (*pfn_wglCreateContext)(m_hdc); - if (!m_context) - { - FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, GetLastError(), 0, m_error, 255, nullptr); - return; - } - (*pfn_wglMakeCurrent)(m_hdc, m_context); - } } virtual ~win_gl_context() { - (*pfn_wglDeleteContext)(m_context); - ReleaseDC(m_window, m_hdc); + if (m_context) + (*pfn_wglDeleteContext)(m_context); + + if (m_hdc) + ReleaseDC(m_window, m_hdc); + } + + virtual explicit operator bool() const override + { + return bool(m_context); } - virtual void MakeCurrent() override + virtual void make_current() override { (*pfn_wglMakeCurrent)(m_hdc, m_context); } - virtual const char *LastErrorMsg() override + virtual const char *last_error_message() override { - if (m_error[0] == 0) - return nullptr; + if (!m_error.empty()) + return m_error.c_str(); else - return m_error; + return nullptr; } - virtual void *getProcAddress(const char *proc) override + virtual void *get_proc_address(const char *proc) override { - return (void *)(*pfn_wglGetProcAddress)(proc); + return reinterpret_cast<void *>(uintptr_t((*pfn_wglGetProcAddress)(proc))); } - virtual int SetSwapInterval(const int swap) override + virtual bool set_swap_interval(const int swap) override { - if (pfn_wglSwapIntervalEXT != nullptr) - { - pfn_wglSwapIntervalEXT(swap ? 1 : 0); - } - return 0; + if (!pfn_wglSwapIntervalEXT) + return false; + + pfn_wglSwapIntervalEXT(swap ? 1 : 0); + return true; } - virtual void SwapBuffer() override + virtual void swap_buffer() override { SwapBuffers(m_hdc); //wglSwapLayerBuffers(GetDC(window().m_hwnd), WGL_SWAP_MAIN_PLANE); } private: + // Typedefs for dynamically loaded functions + typedef PROC (WINAPI *wglGetProcAddress_fn)(LPCSTR); + typedef HGLRC (WINAPI *wglCreateContext_fn)(HDC); + typedef BOOL (WINAPI *wglDeleteContext_fn)(HGLRC); + typedef BOOL (WINAPI *wglMakeCurrent_fn)(HDC, HGLRC); - int setupPixelFormat(HDC hDC) + typedef const char * (WINAPI *wglGetExtensionsStringEXT_fn)(); + typedef BOOL (WINAPI *wglSwapIntervalEXT_fn)(int); + typedef int (WINAPI *wglGetSwapIntervalEXT_fn)(); + + bool setupPixelFormat() { PIXELFORMATDESCRIPTOR pfd = { - sizeof(PIXELFORMATDESCRIPTOR), /* size */ - 1, /* version */ - PFD_SUPPORT_OPENGL | - PFD_DRAW_TO_WINDOW | - PFD_DOUBLEBUFFER, /* support double-buffering */ - PFD_TYPE_RGBA, /* color type */ - 32, /* prefered color depth */ - 0, 0, 0, 0, 0, 0, /* color bits (ignored) */ - 0, /* no alpha buffer */ - 0, /* alpha bits (ignored) */ - 0, /* no accumulation buffer */ - 0, 0, 0, 0, /* accum bits (ignored) */ - 16, /* depth buffer */ - 0, /* no stencil buffer */ - 0, /* no auxiliary buffers */ - PFD_MAIN_PLANE, /* main layer */ - 0, /* reserved */ - 0, 0, 0, /* no layer, visible, damage masks */ - }; - - int pixelFormat = ChoosePixelFormat(hDC, &pfd); - + sizeof(PIXELFORMATDESCRIPTOR), // size + 1, // version + PFD_SUPPORT_OPENGL | + PFD_DRAW_TO_WINDOW | + PFD_DOUBLEBUFFER, // support double-buffering + PFD_TYPE_RGBA, // color type + 32, // prefered color depth + 0, 0, 0, 0, 0, 0, // color bits (ignored) + 0, // no alpha buffer + 0, // alpha bits (ignored) + 0, // no accumulation buffer + 0, 0, 0, 0, // accum bits (ignored) + 16, // depth buffer + 0, // no stencil buffer + 0, // no auxiliary buffers + PFD_MAIN_PLANE, // main layer + 0, // reserved + 0, 0, 0, // no layer, visible, damage masks + }; + + const int pixelFormat = ChoosePixelFormat(m_hdc, &pfd); if (pixelFormat == 0) { - strcpy(m_error, "ChoosePixelFormat failed."); - return 1; + get_last_error_string(); + return false; } - if (SetPixelFormat(hDC, pixelFormat, &pfd) != TRUE) + if (SetPixelFormat(m_hdc, pixelFormat, &pfd) != TRUE) { - strcpy(m_error, "SetPixelFormat failed."); - return 1; + get_last_error_string(); + return false; } - return 0; + + return true; } bool WGLExtensionSupported(const char *extension_name) { - if (pfn_wglGetExtensionsStringEXT == nullptr) + if (!pfn_wglGetExtensionsStringEXT) return false; - // printf("%s\n", pfn_wglGetExtensionsStringEXT()); + return strstr(pfn_wglGetExtensionsStringEXT(), extension_name) != nullptr; + } - if (strstr(pfn_wglGetExtensionsStringEXT(), extension_name) != nullptr) - return true; - else - return false; + void get_last_error_string() + { + LPTSTR buffer = nullptr; + const auto result = FormatMessage( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER, + nullptr, + GetLastError(), + 0, + LPTSTR(&buffer), + 0, + nullptr); + if (!result || !buffer) + { + m_error.clear(); + return; + } + try { m_error = osd::text::from_tstring(buffer); } + catch (...) { m_error.clear(); } + LocalFree(buffer); } HGLRC m_context; - HWND m_window; + HWND const m_window; HDC m_hdc; - char m_error[256]; + std::string m_error; osd::dynamic_module::ptr opengl32_dll; wglGetProcAddress_fn pfn_wglGetProcAddress; @@ -181,4 +210,4 @@ private: wglGetSwapIntervalEXT_fn pfn_wglGetSwapIntervalEXT; }; -#endif // __WIN_GL_CONTEXT__ +#endif // MAME_RENDER_WINGLCONTEXT_H |