21 #include "../../SDL_internal.h"
23 #if SDL_VIDEO_DRIVER_WINDOWS
32 #if SDL_VIDEO_OPENGL_WGL
35 #define DEFAULT_OPENGL "OPENGL32.DLL"
37 #ifndef WGL_ARB_create_context
38 #define WGL_ARB_create_context
39 #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
40 #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
41 #define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
42 #define WGL_CONTEXT_FLAGS_ARB 0x2094
43 #define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
44 #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
46 #ifndef WGL_ARB_create_context_profile
47 #define WGL_ARB_create_context_profile
48 #define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
49 #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
50 #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
53 #ifndef WGL_ARB_create_context_robustness
54 #define WGL_ARB_create_context_robustness
55 #define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
56 #define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
57 #define WGL_NO_RESET_NOTIFICATION_ARB 0x8261
58 #define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
62 #ifndef WGL_EXT_create_context_es2_profile
63 #define WGL_EXT_create_context_es2_profile
64 #define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
67 #ifndef WGL_EXT_create_context_es_profile
68 #define WGL_EXT_create_context_es_profile
69 #define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004
72 #ifndef WGL_ARB_framebuffer_sRGB
73 #define WGL_ARB_framebuffer_sRGB
74 #define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9
77 #ifndef WGL_ARB_context_flush_control
78 #define WGL_ARB_context_flush_control
79 #define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
80 #define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0x0000
81 #define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
84 #ifndef WGL_ARB_create_context_no_error
85 #define WGL_ARB_create_context_no_error
86 #define WGL_CONTEXT_OPENGL_NO_ERROR_ARB 0x31B3
89 typedef HGLRC(
APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC,
96 WIN_GL_LoadLibrary(
_THIS,
const char *
path)
104 path = DEFAULT_OPENGL;
121 _this->
gl_data->wglGetProcAddress = (
void *(WINAPI *) (
const char *))
123 _this->
gl_data->wglCreateContext = (HGLRC(WINAPI *) (HDC))
125 _this->
gl_data->wglDeleteContext = (BOOL(WINAPI *) (HGLRC))
127 _this->
gl_data->wglMakeCurrent = (BOOL(WINAPI *) (HDC, HGLRC))
129 _this->
gl_data->wglShareLists = (BOOL(WINAPI *) (HGLRC, HGLRC))
136 return SDL_SetError(
"Could not retrieve OpenGL functions");
174 WIN_GL_InitExtensions(
_this);
181 WIN_GL_GetProcAddress(
_THIS,
const char *proc)
195 WIN_GL_UnloadLibrary(
_THIS)
206 WIN_GL_SetupPixelFormat(
_THIS, PIXELFORMATDESCRIPTOR * pfd)
209 pfd->nSize =
sizeof(*pfd);
211 pfd->dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL);
213 pfd->dwFlags |= PFD_DOUBLEBUFFER;
216 pfd->dwFlags |= PFD_STEREO;
218 pfd->iLayerType = PFD_MAIN_PLANE;
219 pfd->iPixelType = PFD_TYPE_RGBA;
228 pfd->cColorBits = (pfd->cRedBits + pfd->cGreenBits + pfd->cBlueBits);
235 (pfd->cAccumRedBits + pfd->cAccumGreenBits + pfd->cAccumBlueBits +
236 pfd->cAccumAlphaBits);
245 WIN_GL_ChoosePixelFormat(HDC hdc, PIXELFORMATDESCRIPTOR *
target)
247 PIXELFORMATDESCRIPTOR pfd;
249 unsigned int dist, best_dist = ~0U;
251 count = DescribePixelFormat(hdc, 1,
sizeof(pfd),
NULL);
255 if (!DescribePixelFormat(hdc,
index,
sizeof(pfd), &pfd)) {
259 if ((pfd.dwFlags &
target->dwFlags) !=
target->dwFlags) {
263 if (pfd.iLayerType !=
target->iLayerType) {
266 if (pfd.iPixelType !=
target->iPixelType) {
272 if (pfd.cColorBits <
target->cColorBits) {
275 dist += (pfd.cColorBits -
target->cColorBits);
277 if (pfd.cRedBits <
target->cRedBits) {
280 dist += (pfd.cRedBits -
target->cRedBits);
282 if (pfd.cGreenBits <
target->cGreenBits) {
285 dist += (pfd.cGreenBits -
target->cGreenBits);
287 if (pfd.cBlueBits <
target->cBlueBits) {
290 dist += (pfd.cBlueBits -
target->cBlueBits);
292 if (pfd.cAlphaBits <
target->cAlphaBits) {
295 dist += (pfd.cAlphaBits -
target->cAlphaBits);
297 if (pfd.cAccumBits <
target->cAccumBits) {
300 dist += (pfd.cAccumBits -
target->cAccumBits);
302 if (pfd.cAccumRedBits <
target->cAccumRedBits) {
305 dist += (pfd.cAccumRedBits -
target->cAccumRedBits);
307 if (pfd.cAccumGreenBits <
target->cAccumGreenBits) {
310 dist += (pfd.cAccumGreenBits -
target->cAccumGreenBits);
312 if (pfd.cAccumBlueBits <
target->cAccumBlueBits) {
315 dist += (pfd.cAccumBlueBits -
target->cAccumBlueBits);
317 if (pfd.cAccumAlphaBits <
target->cAccumAlphaBits) {
320 dist += (pfd.cAccumAlphaBits -
target->cAccumAlphaBits);
322 if (pfd.cDepthBits <
target->cDepthBits) {
325 dist += (pfd.cDepthBits -
target->cDepthBits);
327 if (pfd.cStencilBits <
target->cStencilBits) {
330 dist += (pfd.cStencilBits -
target->cStencilBits);
333 if (dist < best_dist) {
343 HasExtension(
const char *extension,
const char *extensions)
346 const char *where, *terminator;
350 if (where || *extension ==
'\0')
368 if (where ==
start || *(where - 1) ==
' ')
369 if (*terminator ==
' ' || *terminator ==
'\0')
378 WIN_GL_InitExtensions(
_THIS)
380 const char *(WINAPI * wglGetExtensionsStringARB) (HDC) = 0;
381 const char *extensions;
385 PIXELFORMATDESCRIPTOR pfd;
401 WIN_GL_SetupPixelFormat(
_this, &pfd);
403 SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd);
411 wglGetExtensionsStringARB = (
const char *(WINAPI *) (HDC))
412 _this->
gl_data->wglGetProcAddress(
"wglGetExtensionsStringARB");
413 if (wglGetExtensionsStringARB) {
414 extensions = wglGetExtensionsStringARB(hdc);
421 if (HasExtension(
"WGL_ARB_pixel_format", extensions)) {
422 _this->
gl_data->wglChoosePixelFormatARB = (BOOL(WINAPI *)
426 WIN_GL_GetProcAddress(
_this,
"wglChoosePixelFormatARB");
428 (BOOL(WINAPI *) (HDC,
int,
int, UINT,
const int *,
int *))
429 WIN_GL_GetProcAddress(
_this,
"wglGetPixelFormatAttribivARB");
439 if (HasExtension(
"WGL_EXT_swap_control", extensions)) {
441 WIN_GL_GetProcAddress(
_this,
"wglSwapIntervalEXT");
443 WIN_GL_GetProcAddress(
_this,
"wglGetSwapIntervalEXT");
444 if (HasExtension(
"WGL_EXT_swap_control_tear", extensions)) {
453 if (HasExtension(
"WGL_EXT_create_context_es2_profile", extensions)) {
455 &
_this->
gl_data->es_profile_max_supported_version.major,
461 if (HasExtension(
"WGL_ARB_context_flush_control", extensions)) {
466 if (HasExtension(
"WGL_ARB_create_context_robustness", extensions)) {
471 if (HasExtension(
"WGL_ARB_create_context_no_error", extensions)) {
477 ReleaseDC(hwnd, hdc);
483 WIN_GL_ChoosePixelFormatARB(
_THIS,
int *iAttribs,
float *fAttribs)
487 PIXELFORMATDESCRIPTOR pfd;
490 unsigned int matching;
499 WIN_GL_SetupPixelFormat(
_this, &pfd);
501 SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd);
508 _this->
gl_data->wglChoosePixelFormatARB(hdc, iAttribs, fAttribs,
516 ReleaseDC(hwnd, hdc);
528 PIXELFORMATDESCRIPTOR pfd;
533 float fAttribs[1] = { 0 };
535 WIN_GL_SetupPixelFormat(
_this, &pfd);
538 iAttr = &iAttribs[0];
540 *iAttr++ = WGL_DRAW_TO_WINDOW_ARB;
542 *iAttr++ = WGL_RED_BITS_ARB;
544 *iAttr++ = WGL_GREEN_BITS_ARB;
546 *iAttr++ = WGL_BLUE_BITS_ARB;
550 *iAttr++ = WGL_ALPHA_BITS_ARB;
554 *iAttr++ = WGL_DOUBLE_BUFFER_ARB;
557 *iAttr++ = WGL_DEPTH_BITS_ARB;
561 *iAttr++ = WGL_STENCIL_BITS_ARB;
566 *iAttr++ = WGL_ACCUM_RED_BITS_ARB;
571 *iAttr++ = WGL_ACCUM_GREEN_BITS_ARB;
576 *iAttr++ = WGL_ACCUM_BLUE_BITS_ARB;
581 *iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB;
586 *iAttr++ = WGL_STEREO_ARB;
591 *iAttr++ = WGL_SAMPLE_BUFFERS_ARB;
596 *iAttr++ = WGL_SAMPLES_ARB;
601 *iAttr++ = WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB;
609 *iAttr++ = WGL_ACCELERATION_ARB;
612 *iAttr++ = WGL_FULL_ACCELERATION_ARB;
614 *iAttr++ = WGL_NO_ACCELERATION_ARB;
624 *iAccelAttr = WGL_NO_ACCELERATION_ARB;
626 *iAccelAttr = WGL_FULL_ACCELERATION_ARB;
632 return SDL_SetError(
"No matching GL pixel format available");
647 WIN_GL_MakeCurrent(
_this, current_win, current_ctx);
671 #if SDL_VIDEO_OPENGL_EGL
673 WIN_GL_UnloadLibrary(
_this);
684 if (WIN_GLES_LoadLibrary(
_this,
NULL) != 0) {
706 if( share_context != 0 ) {
710 PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
711 HGLRC temp_context =
_this->
gl_data->wglCreateContext(hdc);
718 if (WIN_GL_MakeCurrent(
_this,
window, temp_context) < 0) {
719 WIN_GL_DeleteContext(
_this, temp_context);
723 wglCreateContextAttribsARB =
725 wglGetProcAddress(
"wglCreateContextAttribsARB");
726 if (!wglCreateContextAttribsARB) {
733 attribs[iattr++] = WGL_CONTEXT_MAJOR_VERSION_ARB;
735 attribs[iattr++] = WGL_CONTEXT_MINOR_VERSION_ARB;
740 attribs[iattr++] = WGL_CONTEXT_PROFILE_MASK_ARB;
746 attribs[iattr++] = WGL_CONTEXT_FLAGS_ARB;
751 if (
_this->
gl_data->HAS_WGL_ARB_context_flush_control) {
752 attribs[iattr++] = WGL_CONTEXT_RELEASE_BEHAVIOR_ARB;
754 WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB :
755 WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB;
759 if (
_this->
gl_data->HAS_WGL_ARB_create_context_robustness) {
760 attribs[iattr++] = WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB;
762 WGL_LOSE_CONTEXT_ON_RESET_ARB :
763 WGL_NO_RESET_NOTIFICATION_ARB;
767 if (
_this->
gl_data->HAS_WGL_ARB_create_context_no_error) {
768 attribs[iattr++] = WGL_CONTEXT_OPENGL_NO_ERROR_ARB;
775 context = wglCreateContextAttribsARB(hdc, share_context,
attribs);
826 WIN_GL_SetSwapInterval(
_THIS,
int interval)
828 if ((interval < 0) && (!
_this->
gl_data->HAS_WGL_EXT_swap_control_tear)) {
829 return SDL_SetError(
"Negative swap interval unsupported in this GL");
841 WIN_GL_GetSwapInterval(
_THIS)
855 if (!SwapBuffers(hdc)) {
880 PIXELFORMATDESCRIPTOR pfd;
882 DescribePixelFormat(hfromdc,
pixel_format,
sizeof(pfd), &pfd);
#define SDL_assert(condition)
#define SDL_GL_GetCurrentWindow
#define SDL_GetHintBoolean
#define SDL_GL_GetCurrentContext
#define SDL_OutOfMemory()
#define SDL_Unsupported()
#define SDL_HINT_OPENGL_ES_DRIVER
A variable controlling what driver to use for OpenGL ES contexts.
int uint32_t uint32_t uint32_t pixel_format
void * SDL_LoadFunction(void *handle, const char *name)
GLuint GLuint GLsizei count
GLsizei const GLchar *const * path
#define SDL_arraysize(array)
void SDL_GL_DeduceMaxSupportedESProfile(int *major, int *minor)
static SDL_VideoDevice * _this
void * SDL_GLContext
An opaque handle to an OpenGL context.
@ SDL_GL_CONTEXT_PROFILE_ES
int WIN_SetError(const char *prefix)
void WIN_PumpEvents(_THIS)
EGLImageKHR EGLint EGLint * handle
EGLSurface EGLNativeWindowType * window
int framebuffer_srgb_capable
void(* GL_DeleteContext)(_THIS, SDL_GLContext context)
int(* GL_MakeCurrent)(_THIS, SDL_Window *window, SDL_GLContext context)
struct SDL_VideoDevice::@440 gl_config
SDL_GLContext(* GL_CreateContext)(_THIS, SDL_Window *window)
int(* GL_SetSwapInterval)(_THIS, int interval)
void(* GL_UnloadLibrary)(_THIS)
void *(* GL_GetProcAddress)(_THIS, const char *proc)
int(* GL_GetSwapInterval)(_THIS)
int(* GL_LoadLibrary)(_THIS, const char *path)
int(* GL_SwapWindow)(_THIS, SDL_Window *window)
struct SDL_GLDriverData * gl_data
int share_with_current_context
The type used to identify a window.
static screen_context_t context
typedef int(__stdcall *FARPROC)()