mirror of
https://github.com/mpv-player/mpv
synced 2024-11-07 01:47:00 +01:00
gl_common: OpenGL 3.x context support on windows
Also include GL/glext.h on windows: Mingw's (and cygwin's) GL/gl.h has GL/glext.h's inclusion commented out for some reason. Their glext.h is also ancient, so do yourself a favor and replace your GL/glext.h with the one from http://www.opengl.org/registry/api/glext.h . A workaround is needed for NVidia's broken wglCreateContextAtrribsARB: It'll return an error if the requested OpenGL version is previous to 3.2 *and* you request a profile... which is exactly *not* what the wgl_create_context spec says should happen. Handle it by removing the profile request from attribs[] and retrying the context creation once more if the first try fails. And after my first foray into OpenGL I already find a driver quirk. Oh well.
This commit is contained in:
parent
666915a6f0
commit
59125ce71e
@ -487,6 +487,11 @@ static const extfunc_desc_t extfuncs[] = {
|
||||
DEF_GL3_DESC(UniformMatrix3fv),
|
||||
DEF_GL3_DESC(UniformMatrix4x3fv),
|
||||
|
||||
#ifdef CONFIG_GL_WIN32
|
||||
DEF_EXT_DESC(wglCreateContextAttribsARB, NULL,
|
||||
("wglCreateContextAttribsARB")),
|
||||
#endif
|
||||
|
||||
{-1}
|
||||
};
|
||||
|
||||
@ -1812,6 +1817,7 @@ static void cocoa_fullscreen(struct vo *vo)
|
||||
#ifdef CONFIG_GL_WIN32
|
||||
#include "w32_common.h"
|
||||
|
||||
|
||||
static int create_window_w32(struct MPGLContext *ctx, uint32_t d_width,
|
||||
uint32_t d_height, uint32_t flags)
|
||||
{
|
||||
@ -1836,6 +1842,83 @@ static void *w32gpa(const GLubyte *procName)
|
||||
return GetProcAddress(oglmod, procName);
|
||||
}
|
||||
|
||||
static int create_window_w32_gl3(struct MPGLContext *ctx, int gl_flags,
|
||||
int gl_version, uint32_t d_width,
|
||||
uint32_t d_height, uint32_t flags) {
|
||||
if (!vo_w32_config(d_width, d_height, flags))
|
||||
return -1;
|
||||
|
||||
HGLRC *context = &ctx->context.w32;
|
||||
|
||||
if (*context) // reuse existing context
|
||||
return 0; // not reusing it breaks gl3!
|
||||
|
||||
HWND win = vo_w32_window;
|
||||
HDC windc = vo_w32_get_dc(win);
|
||||
HGLRC new_context = 0;
|
||||
GL *gl = ctx->gl;
|
||||
|
||||
new_context = wglCreateContext(windc);
|
||||
if (!new_context) {
|
||||
mp_msg(MSGT_VO, MSGL_FATAL, "[gl] Could not create GL context!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// set context
|
||||
if (!wglMakeCurrent(windc, new_context)) {
|
||||
mp_msg(MSGT_VO, MSGL_FATAL, "[gl] Could not set GL context!\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
getFunctions(ctx->gl, w32gpa, NULL, true);
|
||||
|
||||
if (!gl->wglCreateContextAttribsARB) {
|
||||
mp_msg(MSGT_VO, MSGL_ERR, "[gl] The current OpenGL implementation does"
|
||||
" not support OpenGL 3.x \n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
int attribs[] = {
|
||||
WGL_CONTEXT_MAJOR_VERSION_ARB, MPGL_VER_GET_MAJOR(gl_version),
|
||||
WGL_CONTEXT_MINOR_VERSION_ARB, MPGL_VER_GET_MINOR(gl_version),
|
||||
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
|
||||
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
|
||||
0
|
||||
};
|
||||
|
||||
*context = gl->wglCreateContextAttribsARB(windc, 0, attribs);
|
||||
if (! *context) {
|
||||
// NVidia, instead of ignoring WGL_CONTEXT_FLAGS_ARB, will error out if
|
||||
// it's present on pre-3.2 contexts.
|
||||
// Remove it from attribs and retry the context creation.
|
||||
attribs[6] = attribs[7] = 0;
|
||||
*context = gl->wglCreateContextAttribsARB(windc, 0, attribs);
|
||||
}
|
||||
if (! *context) {
|
||||
int err = GetLastError();
|
||||
mp_msg(MSGT_VO, MSGL_FATAL, "[gl] Could not create an OpenGL 3.x"
|
||||
" context: error 0x%x\n", err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
wglDeleteContext(new_context);
|
||||
|
||||
if (!wglMakeCurrent(windc, *context)) {
|
||||
mp_msg(MSGT_VO, MSGL_FATAL, "[gl] Could not set GL3 context!\n");
|
||||
wglDeleteContext(*context);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* update function pointers */
|
||||
getFunctions(ctx->gl, w32gpa, NULL, true);
|
||||
|
||||
return 0;
|
||||
out:
|
||||
wglDeleteContext(new_context);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int setGlWindow_w32(MPGLContext *ctx)
|
||||
{
|
||||
HWND win = vo_w32_window;
|
||||
@ -1887,6 +1970,7 @@ static int setGlWindow_w32(MPGLContext *ctx)
|
||||
wglDeleteContext(*context);
|
||||
*context = new_context;
|
||||
*vinfo = new_vinfo;
|
||||
|
||||
getFunctions(ctx->gl, w32gpa, NULL, false);
|
||||
|
||||
// and inform that reinit is neccessary
|
||||
@ -2379,6 +2463,7 @@ MPGLContext *init_mpglcontext(enum MPGLType type, struct vo *vo)
|
||||
#ifdef CONFIG_GL_WIN32
|
||||
case GLTYPE_W32:
|
||||
ctx->create_window = create_window_w32;
|
||||
ctx->create_window_gl3 = create_window_w32_gl3;
|
||||
ctx->setGlWindow = setGlWindow_w32;
|
||||
ctx->releaseGlContext = releaseGlContext_w32;
|
||||
ctx->swapGlBuffers = swapGlBuffers_w32;
|
||||
|
@ -46,6 +46,10 @@
|
||||
#endif
|
||||
#include <GL/gl.h>
|
||||
|
||||
#ifdef CONFIG_GL_WIN32
|
||||
#include <GL/glext.h>
|
||||
#endif
|
||||
|
||||
// workaround for some gl.h headers
|
||||
#ifndef GLAPIENTRY
|
||||
#ifdef APIENTRY
|
||||
@ -563,7 +567,24 @@ struct GL {
|
||||
const GLfloat *);
|
||||
void (GLAPIENTRY *UniformMatrix4x3fv)(GLint, GLsizei, GLboolean,
|
||||
const GLfloat *);
|
||||
|
||||
#ifdef CONFIG_GL_WIN32
|
||||
HGLRC (GLAPIENTRY *wglCreateContextAttribsARB)(HDC hDC, HGLRC hShareContext,
|
||||
const int *attribList);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#if defined(CONFIG_GL_WIN32) && !defined(WGL_CONTEXT_MAJOR_VERSION_ARB)
|
||||
/* these are supposed to be defined in wingdi.h but mingw's is too old */
|
||||
/* only the bits actually used by mplayer are defined */
|
||||
/* reference: http://www.opengl.org/registry/specs/ARB/wgl_create_context.txt */
|
||||
|
||||
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
|
||||
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
|
||||
#define WGL_CONTEXT_FLAGS_ARB 0x2094
|
||||
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
|
||||
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
|
||||
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
|
||||
#endif
|
||||
|
||||
#endif /* MPLAYER_GL_COMMON_H */
|
||||
|
Loading…
Reference in New Issue
Block a user