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 typedef HGLRC(
APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC,
91 WIN_GL_LoadLibrary(
_THIS,
const char *
path)
99 path = DEFAULT_OPENGL;
116 _this->
gl_data->wglGetProcAddress = (
void *(WINAPI *) (
const char *))
118 _this->
gl_data->wglCreateContext = (HGLRC(WINAPI *) (HDC))
120 _this->
gl_data->wglDeleteContext = (BOOL(WINAPI *) (HGLRC))
122 _this->
gl_data->wglMakeCurrent = (BOOL(WINAPI *) (HDC, HGLRC))
124 _this->
gl_data->wglShareLists = (BOOL(WINAPI *) (HGLRC, HGLRC))
131 return SDL_SetError(
"Could not retrieve OpenGL functions");
138 WIN_GL_GetProcAddress(
_THIS,
const char *proc)
152 WIN_GL_UnloadLibrary(
_THIS)
163 WIN_GL_SetupPixelFormat(
_THIS, PIXELFORMATDESCRIPTOR * pfd)
166 pfd->nSize =
sizeof(*pfd);
168 pfd->dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL);
170 pfd->dwFlags |= PFD_DOUBLEBUFFER;
173 pfd->dwFlags |= PFD_STEREO;
175 pfd->iLayerType = PFD_MAIN_PLANE;
176 pfd->iPixelType = PFD_TYPE_RGBA;
185 pfd->cColorBits = (pfd->cRedBits + pfd->cGreenBits + pfd->cBlueBits);
192 (pfd->cAccumRedBits + pfd->cAccumGreenBits + pfd->cAccumBlueBits +
193 pfd->cAccumAlphaBits);
202 WIN_GL_ChoosePixelFormat(HDC hdc, PIXELFORMATDESCRIPTOR *
target)
204 PIXELFORMATDESCRIPTOR pfd;
206 unsigned int dist, best_dist = ~0U;
208 count = DescribePixelFormat(hdc, 1,
sizeof(pfd),
NULL);
210 for (index = 1; index <=
count; index++) {
212 if (!DescribePixelFormat(hdc, index,
sizeof(pfd), &pfd)) {
216 if ((pfd.dwFlags & target->dwFlags) != target->dwFlags) {
220 if (pfd.iLayerType != target->iLayerType) {
223 if (pfd.iPixelType != target->iPixelType) {
229 if (pfd.cColorBits < target->cColorBits) {
232 dist += (pfd.cColorBits - target->cColorBits);
234 if (pfd.cRedBits < target->cRedBits) {
237 dist += (pfd.cRedBits - target->cRedBits);
239 if (pfd.cGreenBits < target->cGreenBits) {
242 dist += (pfd.cGreenBits - target->cGreenBits);
244 if (pfd.cBlueBits < target->cBlueBits) {
247 dist += (pfd.cBlueBits - target->cBlueBits);
249 if (pfd.cAlphaBits < target->cAlphaBits) {
252 dist += (pfd.cAlphaBits - target->cAlphaBits);
254 if (pfd.cAccumBits < target->cAccumBits) {
257 dist += (pfd.cAccumBits - target->cAccumBits);
259 if (pfd.cAccumRedBits < target->cAccumRedBits) {
262 dist += (pfd.cAccumRedBits - target->cAccumRedBits);
264 if (pfd.cAccumGreenBits < target->cAccumGreenBits) {
267 dist += (pfd.cAccumGreenBits - target->cAccumGreenBits);
269 if (pfd.cAccumBlueBits < target->cAccumBlueBits) {
272 dist += (pfd.cAccumBlueBits - target->cAccumBlueBits);
274 if (pfd.cAccumAlphaBits < target->cAccumAlphaBits) {
277 dist += (pfd.cAccumAlphaBits - target->cAccumAlphaBits);
279 if (pfd.cDepthBits < target->cDepthBits) {
282 dist += (pfd.cDepthBits - target->cDepthBits);
284 if (pfd.cStencilBits < target->cStencilBits) {
287 dist += (pfd.cStencilBits - target->cStencilBits);
290 if (dist < best_dist) {
300 HasExtension(
const char *extension,
const char *extensions)
303 const char *where, *terminator;
307 if (where || *extension ==
'\0')
325 if (where == start || *(where - 1) ==
' ')
326 if (*terminator ==
' ' || *terminator ==
'\0')
335 WIN_GL_InitExtensions(
_THIS)
337 const char *(WINAPI * wglGetExtensionsStringARB) (HDC) = 0;
338 const char *extensions;
342 PIXELFORMATDESCRIPTOR pfd;
358 WIN_GL_SetupPixelFormat(
_this, &pfd);
360 SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd);
368 wglGetExtensionsStringARB = (
const char *(WINAPI *) (HDC))
369 _this->
gl_data->wglGetProcAddress(
"wglGetExtensionsStringARB");
370 if (wglGetExtensionsStringARB) {
371 extensions = wglGetExtensionsStringARB(hdc);
378 if (HasExtension(
"WGL_ARB_pixel_format", extensions)) {
379 _this->
gl_data->wglChoosePixelFormatARB = (BOOL(WINAPI *)
383 WIN_GL_GetProcAddress(
_this,
"wglChoosePixelFormatARB");
385 (BOOL(WINAPI *) (HDC, int, int, UINT,
const int *,
int *))
386 WIN_GL_GetProcAddress(
_this,
"wglGetPixelFormatAttribivARB");
396 if (HasExtension(
"WGL_EXT_swap_control", extensions)) {
398 WIN_GL_GetProcAddress(
_this,
"wglSwapIntervalEXT");
400 WIN_GL_GetProcAddress(
_this,
"wglGetSwapIntervalEXT");
401 if (HasExtension(
"WGL_EXT_swap_control_tear", extensions)) {
411 if (HasExtension(
"WGL_EXT_create_context_es2_profile", extensions)) {
416 if (HasExtension(
"WGL_ARB_context_flush_control", extensions)) {
422 ReleaseDC(hwnd, hdc);
428 WIN_GL_ChoosePixelFormatARB(
_THIS,
int *iAttribs,
float *fAttribs)
432 PIXELFORMATDESCRIPTOR pfd;
435 unsigned int matching;
444 WIN_GL_SetupPixelFormat(
_this, &pfd);
446 SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd);
453 _this->
gl_data->wglChoosePixelFormatARB(hdc, iAttribs, fAttribs,
461 ReleaseDC(hwnd, hdc);
473 PIXELFORMATDESCRIPTOR pfd;
474 int pixel_format = 0;
478 float fAttribs[1] = { 0 };
480 WIN_GL_SetupPixelFormat(
_this, &pfd);
483 iAttr = &iAttribs[0];
485 *iAttr++ = WGL_DRAW_TO_WINDOW_ARB;
487 *iAttr++ = WGL_RED_BITS_ARB;
489 *iAttr++ = WGL_GREEN_BITS_ARB;
491 *iAttr++ = WGL_BLUE_BITS_ARB;
495 *iAttr++ = WGL_ALPHA_BITS_ARB;
499 *iAttr++ = WGL_DOUBLE_BUFFER_ARB;
502 *iAttr++ = WGL_DEPTH_BITS_ARB;
506 *iAttr++ = WGL_STENCIL_BITS_ARB;
511 *iAttr++ = WGL_ACCUM_RED_BITS_ARB;
516 *iAttr++ = WGL_ACCUM_GREEN_BITS_ARB;
521 *iAttr++ = WGL_ACCUM_BLUE_BITS_ARB;
526 *iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB;
531 *iAttr++ = WGL_STEREO_ARB;
536 *iAttr++ = WGL_SAMPLE_BUFFERS_ARB;
541 *iAttr++ = WGL_SAMPLES_ARB;
546 *iAttr++ = WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB;
554 *iAttr++ = WGL_ACCELERATION_ARB;
557 *iAttr++ = WGL_FULL_ACCELERATION_ARB;
559 *iAttr++ = WGL_NO_ACCELERATION_ARB;
565 pixel_format = WIN_GL_ChoosePixelFormatARB(
_this, iAttribs, fAttribs);
569 *iAccelAttr = WGL_NO_ACCELERATION_ARB;
570 pixel_format = WIN_GL_ChoosePixelFormatARB(
_this, iAttribs, fAttribs);
571 *iAccelAttr = WGL_FULL_ACCELERATION_ARB;
574 pixel_format = WIN_GL_ChoosePixelFormat(hdc, &pfd);
577 return SDL_SetError(
"No matching GL pixel format available");
579 if (!SetPixelFormat(hdc, pixel_format, &pfd)) {
591 const int retval = WIN_GL_SetupWindowInternal(
_this, window);
592 WIN_GL_MakeCurrent(
_this, current_win, current_ctx);
603 !
_this->
gl_data->HAS_WGL_EXT_create_context_es2_profile) {
604 #if SDL_VIDEO_OPENGL_EGL 606 WIN_GL_UnloadLibrary(
_this);
617 if (WIN_GLES_LoadLibrary(
_this,
NULL) != 0) {
621 return WIN_GLES_CreateContext(
_this, window);
639 if( share_context != 0 ) {
643 PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
644 HGLRC temp_context =
_this->
gl_data->wglCreateContext(hdc);
651 if (WIN_GL_MakeCurrent(
_this, window, temp_context) < 0) {
652 WIN_GL_DeleteContext(
_this, temp_context);
656 wglCreateContextAttribsARB =
658 wglGetProcAddress(
"wglCreateContextAttribsARB");
659 if (!wglCreateContextAttribsARB) {
661 context = temp_context;
673 attribs[iattr++] = WGL_CONTEXT_PROFILE_MASK_ARB;
679 attribs[iattr++] = WGL_CONTEXT_FLAGS_ARB;
684 if (
_this->
gl_data->HAS_WGL_ARB_context_flush_control) {
685 attribs[iattr++] = WGL_CONTEXT_RELEASE_BEHAVIOR_ARB;
687 WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB :
688 WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB;
691 attribs[iattr++] = 0;
694 context = wglCreateContextAttribsARB(hdc, share_context, attribs);
705 if (WIN_GL_MakeCurrent(
_this, window, context) < 0) {
706 WIN_GL_DeleteContext(
_this, context);
738 if (!
_this->
gl_data->wglMakeCurrent(hdc, (HGLRC) context)) {
745 WIN_GL_SetSwapInterval(
_THIS,
int interval)
747 if ((interval < 0) && (!
_this->
gl_data->HAS_WGL_EXT_swap_control_tear)) {
748 return SDL_SetError(
"Negative swap interval unsupported in this GL");
760 WIN_GL_GetSwapInterval(
_THIS)
795 int pixel_format = GetPixelFormat(hfromdc);
796 PIXELFORMATDESCRIPTOR pfd;
798 DescribePixelFormat(hfromdc, pixel_format,
sizeof(pfd), &pfd);
801 result = SetPixelFormat(htodc, pixel_format, &pfd);
GLuint GLuint GLsizei count
int(* GL_SetSwapInterval)(_THIS, int interval)
void(* GL_SwapWindow)(_THIS, SDL_Window *window)
int(* GL_LoadLibrary)(_THIS, const char *path)
struct SDL_GLDriverData * gl_data
static SDL_VideoDevice * _this
void * SDL_calloc(size_t nmemb, size_t size)
void * SDL_GLContext
An opaque handle to an OpenGL context.
SDL_GLContext(* GL_CreateContext)(_THIS, SDL_Window *window)
int(* GL_MakeCurrent)(_THIS, SDL_Window *window, SDL_GLContext context)
int framebuffer_srgb_capable
void(* GL_UnloadLibrary)(_THIS)
struct SDL_VideoDevice::@27 gl_config
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)
The type used to identify a window.
#define SDL_arraysize(array)
GLsizei const GLchar *const * path
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)