mirror of
https://github.com/holub/mame
synced 2025-06-07 05:13:46 +03:00

Revision: 58dc78b6eb
Author: Giuseppe Gorgoglione <gorgogsp@gmail.com>
Date: 28/05/2016 03:14:15
Message:
Introduce dynamic_module
This is a central cross-platform facility to dynamically bind functions from shared libraries.
Updated all OSD modules to use it.
185 lines
5.2 KiB
C++
185 lines
5.2 KiB
C++
// license:BSD-3-Clause
|
|
// copyright-holders:Olivier Galibert, R. Belmont
|
|
//============================================================
|
|
//
|
|
// winglcontext.h - Windows-specific GL context
|
|
//
|
|
// SDLMAME by Olivier Galibert and R. Belmont
|
|
//
|
|
//============================================================
|
|
|
|
#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);
|
|
|
|
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;
|
|
|
|
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 == nullptr || pfn_wglCreateContext == nullptr ||
|
|
pfn_wglDeleteContext == nullptr || pfn_wglMakeCurrent == nullptr)
|
|
{
|
|
return;
|
|
}
|
|
|
|
pfn_wglGetExtensionsStringEXT = (wglGetExtensionsStringEXT_fn)(*pfn_wglGetProcAddress)("wglGetExtensionsStringEXT");
|
|
|
|
if (WGLExtensionSupported("WGL_EXT_swap_control"))
|
|
{
|
|
pfn_wglSwapIntervalEXT = (BOOL (WINAPI *) (int)) getProcAddress("wglSwapIntervalEXT");
|
|
pfn_wglGetSwapIntervalEXT = (int (WINAPI *) (void)) getProcAddress("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);
|
|
}
|
|
|
|
virtual void MakeCurrent() override
|
|
{
|
|
(*pfn_wglMakeCurrent)(m_hdc, m_context);
|
|
}
|
|
|
|
virtual const char *LastErrorMsg() override
|
|
{
|
|
if (m_error[0] == 0)
|
|
return nullptr;
|
|
else
|
|
return m_error;
|
|
}
|
|
|
|
virtual void *getProcAddress(const char *proc) override
|
|
{
|
|
return (void *)(*pfn_wglGetProcAddress)(proc);
|
|
}
|
|
|
|
virtual int SetSwapInterval(const int swap) override
|
|
{
|
|
if (pfn_wglSwapIntervalEXT != nullptr)
|
|
{
|
|
pfn_wglSwapIntervalEXT(swap ? 1 : 0);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
virtual void SwapBuffer() override
|
|
{
|
|
SwapBuffers(m_hdc);
|
|
//wglSwapLayerBuffers(GetDC(window().m_hwnd), WGL_SWAP_MAIN_PLANE);
|
|
}
|
|
|
|
private:
|
|
|
|
int setupPixelFormat(HDC hDC)
|
|
{
|
|
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);
|
|
|
|
if (pixelFormat == 0)
|
|
{
|
|
strcpy(m_error, "ChoosePixelFormat failed.");
|
|
return 1;
|
|
}
|
|
|
|
if (SetPixelFormat(hDC, pixelFormat, &pfd) != TRUE)
|
|
{
|
|
strcpy(m_error, "SetPixelFormat failed.");
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
bool WGLExtensionSupported(const char *extension_name)
|
|
{
|
|
if (pfn_wglGetExtensionsStringEXT == nullptr)
|
|
return false;
|
|
|
|
// printf("%s\n", pfn_wglGetExtensionsStringEXT());
|
|
|
|
if (strstr(pfn_wglGetExtensionsStringEXT(), extension_name) != nullptr)
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
HGLRC m_context;
|
|
HWND m_window;
|
|
HDC m_hdc;
|
|
char m_error[256];
|
|
|
|
osd::dynamic_module::ptr opengl32_dll;
|
|
wglGetProcAddress_fn pfn_wglGetProcAddress;
|
|
wglCreateContext_fn pfn_wglCreateContext;
|
|
wglDeleteContext_fn pfn_wglDeleteContext;
|
|
wglMakeCurrent_fn pfn_wglMakeCurrent;
|
|
|
|
wglGetExtensionsStringEXT_fn pfn_wglGetExtensionsStringEXT;
|
|
wglSwapIntervalEXT_fn pfn_wglSwapIntervalEXT;
|
|
wglGetSwapIntervalEXT_fn pfn_wglGetSwapIntervalEXT;
|
|
};
|
|
|
|
#endif // __WIN_GL_CONTEXT__
|