diff --git a/include/SDL_hints.h b/include/SDL_hints.h index 9aad2e32e..ab65c2ade 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -328,6 +328,25 @@ extern "C" { */ #define SDL_HINT_VIDEO_WIN_D3DCOMPILER "SDL_VIDEO_WIN_D3DCOMPILER" +/** +* \brief A variable that is the address of another SDL_Window* (as a hex string formatted with "%p"). +* +* If this hint is set before SDL_CreateWindowFrom() and the SDL_Window* it is set to has +* SDL_WINDOW_OPENGL set (and running on WGL only, currently), then two things will occur on the newly +* created SDL_Window: + +* 1. Its pixel format will be set to the same pixel format as this SDL_Window. This is +* needed for example when sharing an OpenGL context across multiple windows. +* +* 2. The flag SDL_WINDOW_OPENGL will be set on the new window so it can be used for +* OpenGL rendering. +* +* This variable can be set to the following values: +* The address (as a string "%p") of the SDL_Window* that new windows created with SDL_CreateWindowFrom() should +* share a pixel format with. +*/ +#define SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT "SDL_VIDEO_WINDOW_SHARE_PIXEL_FORMAT" + /** * \brief An enumeration of hint priorities */ diff --git a/src/video/windows/SDL_windowsopengl.c b/src/video/windows/SDL_windowsopengl.c index 247976b8d..53cf555e4 100644 --- a/src/video/windows/SDL_windowsopengl.c +++ b/src/video/windows/SDL_windowsopengl.c @@ -759,6 +759,26 @@ WIN_GL_DeleteContext(_THIS, SDL_GLContext context) _this->gl_data->wglDeleteContext((HGLRC) context); } + +SDL_bool +WIN_GL_SetPixelFormatFrom(_THIS, SDL_Window * fromWindow, SDL_Window * toWindow) +{ + HDC hfromdc = ((SDL_WindowData *) fromWindow->driverdata)->hdc; + HDC htodc = ((SDL_WindowData *) toWindow->driverdata)->hdc; + BOOL result; + + /* get the pixel format of the fromWindow */ + int pixel_format = GetPixelFormat(hfromdc); + PIXELFORMATDESCRIPTOR pfd; + SDL_memset(&pfd, 0, sizeof(pfd)); + DescribePixelFormat(hfromdc, pixel_format, sizeof(pfd), &pfd); + + /* set the pixel format of the toWindow */ + result = SetPixelFormat(htodc, pixel_format, &pfd); + + return result ? SDL_TRUE : SDL_FALSE; +} + #endif /* SDL_VIDEO_OPENGL_WGL */ #endif /* SDL_VIDEO_DRIVER_WINDOWS */ diff --git a/src/video/windows/SDL_windowsopengl.h b/src/video/windows/SDL_windowsopengl.h index f8934b065..a331098d2 100644 --- a/src/video/windows/SDL_windowsopengl.h +++ b/src/video/windows/SDL_windowsopengl.h @@ -64,6 +64,7 @@ extern int WIN_GL_GetSwapInterval(_THIS); extern void WIN_GL_SwapWindow(_THIS, SDL_Window * window); extern void WIN_GL_DeleteContext(_THIS, SDL_GLContext context); extern void WIN_GL_InitExtensions(_THIS); +extern SDL_bool WIN_GL_SetPixelFormatFrom(_THIS, SDL_Window * fromWindow, SDL_Window * toWindow); #ifndef WGL_ARB_pixel_format #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c index 5cba9ff2c..9617dc009 100644 --- a/src/video/windows/SDL_windowswindow.c +++ b/src/video/windows/SDL_windowswindow.c @@ -32,6 +32,7 @@ #include "SDL_windowsvideo.h" #include "SDL_windowswindow.h" +#include "SDL_hints.h" /* Dropfile support */ #include @@ -337,6 +338,31 @@ WIN_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) if (SetupWindowData(_this, window, hwnd, SDL_FALSE) < 0) { return -1; } + +#if SDL_VIDEO_OPENGL_WGL + { + const char *hint = SDL_GetHint(SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT); + if (hint) { + // This hint is a pointer (in string form) of the address of + // the window to share a pixel format with + SDL_Window *otherWindow = NULL; + SDL_sscanf(hint, "%p", (void**)&otherWindow); + + // Do some error checking on the pointer + if (otherWindow != NULL && otherWindow->magic == &_this->window_magic) + { + // If the otherWindow has SDL_WINDOW_OPENGL set, set it for the new window as well + if (otherWindow->flags & SDL_WINDOW_OPENGL) + { + window->flags |= SDL_WINDOW_OPENGL; + if(!WIN_GL_SetPixelFormatFrom(_this, otherWindow, window)) { + return -1; + } + } + } + } + } +#endif return 0; }