21 #include "../../SDL_internal.h" 23 #if SDL_VIDEO_DRIVER_WINDOWS 33 #if SDL_VIDEO_OPENGL_WGL 36 #define DEFAULT_OPENGL "OPENGL32.DLL" 38 #ifndef WGL_ARB_create_context 39 #define WGL_ARB_create_context 40 #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 41 #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 42 #define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 43 #define WGL_CONTEXT_FLAGS_ARB 0x2094 44 #define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 45 #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 47 #ifndef WGL_ARB_create_context_profile 48 #define WGL_ARB_create_context_profile 49 #define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 50 #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 51 #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 54 #ifndef WGL_ARB_create_context_robustness 55 #define WGL_ARB_create_context_robustness 56 #define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 57 #define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 58 #define WGL_NO_RESET_NOTIFICATION_ARB 0x8261 59 #define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 63 #ifndef WGL_EXT_create_context_es2_profile 64 #define WGL_EXT_create_context_es2_profile 65 #define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 68 #ifndef WGL_EXT_create_context_es_profile 69 #define WGL_EXT_create_context_es_profile 70 #define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004 73 #ifndef WGL_ARB_framebuffer_sRGB 74 #define WGL_ARB_framebuffer_sRGB 75 #define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9 78 #ifndef WGL_ARB_context_flush_control 79 #define WGL_ARB_context_flush_control 80 #define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097 81 #define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0x0000 82 #define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098 85 #ifndef WGL_ARB_create_context_no_error 86 #define WGL_ARB_create_context_no_error 87 #define WGL_CONTEXT_OPENGL_NO_ERROR_ARB 0x31B3 90 typedef HGLRC(
APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC,
97 WIN_GL_LoadLibrary(
_THIS,
const char *
path)
105 path = DEFAULT_OPENGL;
122 _this->
gl_data->wglGetProcAddress = (
void *(WINAPI *) (
const char *))
124 _this->
gl_data->wglCreateContext = (HGLRC(WINAPI *) (HDC))
126 _this->
gl_data->wglDeleteContext = (BOOL(WINAPI *) (HGLRC))
128 _this->
gl_data->wglMakeCurrent = (BOOL(WINAPI *) (HDC, HGLRC))
130 _this->
gl_data->wglShareLists = (BOOL(WINAPI *) (HGLRC, HGLRC))
137 return SDL_SetError(
"Could not retrieve OpenGL functions");
175 WIN_GL_InitExtensions(
_this);
182 WIN_GL_GetProcAddress(
_THIS,
const char *proc)
196 WIN_GL_UnloadLibrary(
_THIS)
207 WIN_GL_SetupPixelFormat(
_THIS, PIXELFORMATDESCRIPTOR * pfd)
210 pfd->nSize =
sizeof(*pfd);
212 pfd->dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL);
214 pfd->dwFlags |= PFD_DOUBLEBUFFER;
217 pfd->dwFlags |= PFD_STEREO;
219 pfd->iLayerType = PFD_MAIN_PLANE;
220 pfd->iPixelType = PFD_TYPE_RGBA;
229 pfd->cColorBits = (pfd->cRedBits + pfd->cGreenBits + pfd->cBlueBits);
236 (pfd->cAccumRedBits + pfd->cAccumGreenBits + pfd->cAccumBlueBits +
237 pfd->cAccumAlphaBits);
246 WIN_GL_ChoosePixelFormat(HDC hdc, PIXELFORMATDESCRIPTOR *
target)
248 PIXELFORMATDESCRIPTOR pfd;
250 unsigned int dist, best_dist = ~0U;
252 count = DescribePixelFormat(hdc, 1,
sizeof(pfd),
NULL);
254 for (index = 1; index <=
count; index++) {
256 if (!DescribePixelFormat(hdc, index,
sizeof(pfd), &pfd)) {
260 if ((pfd.dwFlags & target->dwFlags) != target->dwFlags) {
264 if (pfd.iLayerType != target->iLayerType) {
267 if (pfd.iPixelType != target->iPixelType) {
273 if (pfd.cColorBits < target->cColorBits) {
276 dist += (pfd.cColorBits - target->cColorBits);
278 if (pfd.cRedBits < target->cRedBits) {
281 dist += (pfd.cRedBits - target->cRedBits);
283 if (pfd.cGreenBits < target->cGreenBits) {
286 dist += (pfd.cGreenBits - target->cGreenBits);
288 if (pfd.cBlueBits < target->cBlueBits) {
291 dist += (pfd.cBlueBits - target->cBlueBits);
293 if (pfd.cAlphaBits < target->cAlphaBits) {
296 dist += (pfd.cAlphaBits - target->cAlphaBits);
298 if (pfd.cAccumBits < target->cAccumBits) {
301 dist += (pfd.cAccumBits - target->cAccumBits);
303 if (pfd.cAccumRedBits < target->cAccumRedBits) {
306 dist += (pfd.cAccumRedBits - target->cAccumRedBits);
308 if (pfd.cAccumGreenBits < target->cAccumGreenBits) {
311 dist += (pfd.cAccumGreenBits - target->cAccumGreenBits);
313 if (pfd.cAccumBlueBits < target->cAccumBlueBits) {
316 dist += (pfd.cAccumBlueBits - target->cAccumBlueBits);
318 if (pfd.cAccumAlphaBits < target->cAccumAlphaBits) {
321 dist += (pfd.cAccumAlphaBits - target->cAccumAlphaBits);
323 if (pfd.cDepthBits < target->cDepthBits) {
326 dist += (pfd.cDepthBits - target->cDepthBits);
328 if (pfd.cStencilBits < target->cStencilBits) {
331 dist += (pfd.cStencilBits - target->cStencilBits);
334 if (dist < best_dist) {
344 HasExtension(
const char *extension,
const char *extensions)
347 const char *where, *terminator;
351 if (where || *extension ==
'\0')
369 if (where == start || *(where - 1) ==
' ')
370 if (*terminator ==
' ' || *terminator ==
'\0')
379 WIN_GL_InitExtensions(
_THIS)
381 const char *(WINAPI * wglGetExtensionsStringARB) (HDC) = 0;
382 const char *extensions;
386 PIXELFORMATDESCRIPTOR pfd;
402 WIN_GL_SetupPixelFormat(
_this, &pfd);
404 SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd);
412 wglGetExtensionsStringARB = (
const char *(WINAPI *) (HDC))
413 _this->
gl_data->wglGetProcAddress(
"wglGetExtensionsStringARB");
414 if (wglGetExtensionsStringARB) {
415 extensions = wglGetExtensionsStringARB(hdc);
422 if (HasExtension(
"WGL_ARB_pixel_format", extensions)) {
423 _this->
gl_data->wglChoosePixelFormatARB = (BOOL(WINAPI *)
427 WIN_GL_GetProcAddress(
_this,
"wglChoosePixelFormatARB");
429 (BOOL(WINAPI *) (HDC, int, int, UINT,
const int *,
int *))
430 WIN_GL_GetProcAddress(
_this,
"wglGetPixelFormatAttribivARB");
440 if (HasExtension(
"WGL_EXT_swap_control", extensions)) {
442 WIN_GL_GetProcAddress(
_this,
"wglSwapIntervalEXT");
444 WIN_GL_GetProcAddress(
_this,
"wglGetSwapIntervalEXT");
445 if (HasExtension(
"WGL_EXT_swap_control_tear", extensions)) {
454 if (HasExtension(
"WGL_EXT_create_context_es2_profile", extensions)) {
456 &
_this->
gl_data->es_profile_max_supported_version.major,
462 if (HasExtension(
"WGL_ARB_context_flush_control", extensions)) {
467 if (HasExtension(
"WGL_ARB_create_context_robustness", extensions)) {
472 if (HasExtension(
"WGL_ARB_create_context_no_error", extensions)) {
478 ReleaseDC(hwnd, hdc);
484 WIN_GL_ChoosePixelFormatARB(
_THIS,
int *iAttribs,
float *fAttribs)
488 PIXELFORMATDESCRIPTOR pfd;
490 int pixel_format = 0;
491 unsigned int matching;
500 WIN_GL_SetupPixelFormat(
_this, &pfd);
502 SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd);
509 _this->
gl_data->wglChoosePixelFormatARB(hdc, iAttribs, fAttribs,
517 ReleaseDC(hwnd, hdc);
529 PIXELFORMATDESCRIPTOR pfd;
530 int pixel_format = 0;
534 float fAttribs[1] = { 0 };
536 WIN_GL_SetupPixelFormat(
_this, &pfd);
539 iAttr = &iAttribs[0];
541 *iAttr++ = WGL_DRAW_TO_WINDOW_ARB;
543 *iAttr++ = WGL_RED_BITS_ARB;
545 *iAttr++ = WGL_GREEN_BITS_ARB;
547 *iAttr++ = WGL_BLUE_BITS_ARB;
551 *iAttr++ = WGL_ALPHA_BITS_ARB;
555 *iAttr++ = WGL_DOUBLE_BUFFER_ARB;
558 *iAttr++ = WGL_DEPTH_BITS_ARB;
562 *iAttr++ = WGL_STENCIL_BITS_ARB;
567 *iAttr++ = WGL_ACCUM_RED_BITS_ARB;
572 *iAttr++ = WGL_ACCUM_GREEN_BITS_ARB;
577 *iAttr++ = WGL_ACCUM_BLUE_BITS_ARB;
582 *iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB;
587 *iAttr++ = WGL_STEREO_ARB;
592 *iAttr++ = WGL_SAMPLE_BUFFERS_ARB;
597 *iAttr++ = WGL_SAMPLES_ARB;
602 *iAttr++ = WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB;
610 *iAttr++ = WGL_ACCELERATION_ARB;
613 *iAttr++ = WGL_FULL_ACCELERATION_ARB;
615 *iAttr++ = WGL_NO_ACCELERATION_ARB;
621 pixel_format = WIN_GL_ChoosePixelFormatARB(
_this, iAttribs, fAttribs);
625 *iAccelAttr = WGL_NO_ACCELERATION_ARB;
626 pixel_format = WIN_GL_ChoosePixelFormatARB(
_this, iAttribs, fAttribs);
627 *iAccelAttr = WGL_FULL_ACCELERATION_ARB;
630 pixel_format = WIN_GL_ChoosePixelFormat(hdc, &pfd);
633 return SDL_SetError(
"No matching GL pixel format available");
635 if (!SetPixelFormat(hdc, pixel_format, &pfd)) {
647 const int retval = WIN_GL_SetupWindowInternal(
_this, window);
648 WIN_GL_MakeCurrent(
_this, current_win, current_ctx);
672 #if SDL_VIDEO_OPENGL_EGL 674 WIN_GL_UnloadLibrary(
_this);
685 if (WIN_GLES_LoadLibrary(
_this,
NULL) != 0) {
689 return WIN_GLES_CreateContext(
_this, window);
707 if( share_context != 0 ) {
711 PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
712 HGLRC temp_context =
_this->
gl_data->wglCreateContext(hdc);
719 if (WIN_GL_MakeCurrent(
_this, window, temp_context) < 0) {
720 WIN_GL_DeleteContext(
_this, temp_context);
724 wglCreateContextAttribsARB =
726 wglGetProcAddress(
"wglCreateContextAttribsARB");
727 if (!wglCreateContextAttribsARB) {
729 context = temp_context;
734 attribs[iattr++] = WGL_CONTEXT_MAJOR_VERSION_ARB;
736 attribs[iattr++] = WGL_CONTEXT_MINOR_VERSION_ARB;
741 attribs[iattr++] = WGL_CONTEXT_PROFILE_MASK_ARB;
747 attribs[iattr++] = WGL_CONTEXT_FLAGS_ARB;
752 if (
_this->
gl_data->HAS_WGL_ARB_context_flush_control) {
753 attribs[iattr++] = WGL_CONTEXT_RELEASE_BEHAVIOR_ARB;
755 WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB :
756 WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB;
760 if (
_this->
gl_data->HAS_WGL_ARB_create_context_robustness) {
761 attribs[iattr++] = WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB;
763 WGL_LOSE_CONTEXT_ON_RESET_ARB :
764 WGL_NO_RESET_NOTIFICATION_ARB;
768 if (
_this->
gl_data->HAS_WGL_ARB_create_context_no_error) {
769 attribs[iattr++] = WGL_CONTEXT_OPENGL_NO_ERROR_ARB;
773 attribs[iattr++] = 0;
776 context = wglCreateContextAttribsARB(hdc, share_context, attribs);
787 if (WIN_GL_MakeCurrent(
_this, window, context) < 0) {
788 WIN_GL_DeleteContext(
_this, context);
820 if (!
_this->
gl_data->wglMakeCurrent(hdc, (HGLRC) context)) {
827 WIN_GL_SetSwapInterval(
_THIS,
int interval)
829 if ((interval < 0) && (!
_this->
gl_data->HAS_WGL_EXT_swap_control_tear)) {
830 return SDL_SetError(
"Negative swap interval unsupported in this GL");
842 WIN_GL_GetSwapInterval(
_THIS)
856 if (!SwapBuffers(hdc)) {
880 int pixel_format = GetPixelFormat(hfromdc);
881 PIXELFORMATDESCRIPTOR pfd;
883 DescribePixelFormat(hfromdc, pixel_format,
sizeof(pfd), &pfd);
886 result = SetPixelFormat(htodc, pixel_format, &pfd);
GLuint GLuint GLsizei count
int(* GL_SetSwapInterval)(_THIS, int interval)
static screen_context_t context
int(* GL_LoadLibrary)(_THIS, const char *path)
struct SDL_GLDriverData * gl_data
#define SDL_GetHintBoolean
#define SDL_HINT_OPENGL_ES_DRIVER
A variable controlling what driver to use for OpenGL ES contexts.
static SDL_VideoDevice * _this
void * SDL_GLContext
An opaque handle to an OpenGL context.
SDL_GLContext(* GL_CreateContext)(_THIS, SDL_Window *window)
EGLImageKHR EGLint EGLint * handle
int(* GL_MakeCurrent)(_THIS, SDL_Window *window, SDL_GLContext context)
void SDL_GL_DeduceMaxSupportedESProfile(int *major, int *minor)
int framebuffer_srgb_capable
void(* GL_UnloadLibrary)(_THIS)
int share_with_current_context
#define SDL_assert(condition)
#define SDL_OutOfMemory()
#define SDL_GL_GetCurrentContext
int WIN_SetError(const char *prefix)
#define SDL_GL_GetCurrentWindow
void WIN_PumpEvents(_THIS)
EGLSurface EGLNativeWindowType * window
int(* GL_SwapWindow)(_THIS, SDL_Window *window)
The type used to identify a window.
#define SDL_arraysize(array)
GLsizei const GLchar *const * path
struct SDL_VideoDevice::@34 gl_config
void * SDL_LoadFunction(void *handle, const char *name)
void(* GL_DeleteContext)(_THIS, SDL_GLContext context)
int(* GL_GetSwapInterval)(_THIS)
#define SDL_Unsupported()
void *(* GL_GetProcAddress)(_THIS, const char *proc)