From 811dfe1cf7dcbd57f2eaec89d5abd715106264b9 Mon Sep 17 00:00:00 2001 From: binary1248 Date: Mon, 20 Apr 2015 14:16:30 +0200 Subject: [PATCH] Added support for pbuffers on Windows and Unix. --- src/SFML/Window/Unix/GlxContext.cpp | 360 +++++++++++++++++------- src/SFML/Window/Unix/GlxContext.hpp | 42 ++- src/SFML/Window/Unix/GlxExtensions.cpp | 34 ++- src/SFML/Window/Unix/GlxExtensions.hpp | 41 +++ src/SFML/Window/Unix/GlxExtensions.txt | 7 +- src/SFML/Window/Win32/WglContext.cpp | 214 +++++++++++--- src/SFML/Window/Win32/WglContext.hpp | 57 +++- src/SFML/Window/Win32/WglExtensions.cpp | 34 ++- src/SFML/Window/Win32/WglExtensions.hpp | 24 ++ src/SFML/Window/Win32/WglExtensions.txt | 5 +- 10 files changed, 647 insertions(+), 171 deletions(-) diff --git a/src/SFML/Window/Unix/GlxContext.cpp b/src/SFML/Window/Unix/GlxContext.cpp index 7e24c3e95..5a28b1670 100644 --- a/src/SFML/Window/Unix/GlxContext.cpp +++ b/src/SFML/Window/Unix/GlxContext.cpp @@ -96,101 +96,73 @@ void ensureExtensionsInit(::Display* display, int screen) //////////////////////////////////////////////////////////// GlxContext::GlxContext(GlxContext* shared) : +m_display (NULL), m_window (0), m_context (NULL), -m_ownsWindow(true) +m_pbuffer (0), +m_ownsWindow(false) { - // Open a connection with the X server - m_display = OpenDisplay(); - m_connection = XGetXCBConnection(m_display); - xcb_screen_t* screen = XCBScreenOfDisplay(m_connection, DefaultScreen(m_display)); + // Save the creation settings + m_settings = ContextSettings(); - // Choose the visual according to the context settings - XVisualInfo visualInfo = selectBestVisual(m_display, VideoMode::getDesktopMode().bitsPerPixel, ContextSettings()); + // Make sure that extensions are initialized if this is not the shared context + // The shared context is the context used to initialize the extensions + if (shared && shared->m_display) + ensureExtensionsInit(shared->m_display, DefaultScreen(shared->m_display)); - // Define the window attributes - xcb_colormap_t colormap = xcb_generate_id(m_connection); - xcb_create_colormap(m_connection, XCB_COLORMAP_ALLOC_NONE, colormap, screen->root, visualInfo.visualid); - const uint32_t value_list[] = {colormap}; - - // Create a dummy window (disabled and hidden) - m_window = xcb_generate_id(m_connection); - xcb_create_window( - m_connection, - static_cast(visualInfo.depth), - m_window, - screen->root, - 0, 0, - 1, 1, - 0, - XCB_WINDOW_CLASS_INPUT_OUTPUT, - visualInfo.visualid, - XCB_CW_COLORMAP, - value_list - ); + // Create the rendering surface (window or pbuffer if supported) + createSurface(shared, 1, 1, VideoMode::getDesktopMode().bitsPerPixel); // Create the context - createContext(shared, VideoMode::getDesktopMode().bitsPerPixel, ContextSettings()); + createContext(shared); } //////////////////////////////////////////////////////////// GlxContext::GlxContext(GlxContext* shared, const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel) : +m_display (NULL), m_window (0), m_context (NULL), +m_pbuffer (0), m_ownsWindow(false) { - // Open a connection with the X server - // (important: must be the same display as the owner window) - m_display = OpenDisplay(); - m_connection = XGetXCBConnection(m_display); + // Save the creation settings + m_settings = settings; - // Get the owner window and its device context - m_window = static_cast< ::Window>(owner->getSystemHandle()); + // Make sure that extensions are initialized if this is not the shared context + // The shared context is the context used to initialize the extensions + if (shared && shared->m_display) + ensureExtensionsInit(shared->m_display, DefaultScreen(shared->m_display)); + + // Create the rendering surface from the owner window + createSurface(static_cast< ::Window>(owner->getSystemHandle())); // Create the context - if (m_window) - createContext(shared, bitsPerPixel, settings); + createContext(shared); } //////////////////////////////////////////////////////////// GlxContext::GlxContext(GlxContext* shared, const ContextSettings& settings, unsigned int width, unsigned int height) : +m_display (NULL), m_window (0), m_context (NULL), -m_ownsWindow(true) +m_pbuffer (0), +m_ownsWindow(false) { - // Open a connection with the X server - m_display = OpenDisplay(); - m_connection = XGetXCBConnection(m_display); - xcb_screen_t* screen = XCBScreenOfDisplay(m_connection, DefaultScreen(m_display)); + // Save the creation settings + m_settings = settings; - // Choose the visual according to the context settings - XVisualInfo visualInfo = selectBestVisual(m_display, VideoMode::getDesktopMode().bitsPerPixel, settings); + // Make sure that extensions are initialized if this is not the shared context + // The shared context is the context used to initialize the extensions + if (shared && shared->m_display) + ensureExtensionsInit(shared->m_display, DefaultScreen(shared->m_display)); - // Define the window attributes - xcb_colormap_t colormap = xcb_generate_id(m_connection); - xcb_create_colormap(m_connection, XCB_COLORMAP_ALLOC_NONE, colormap, screen->root, visualInfo.visualid); - const uint32_t value_list[] = {colormap}; - - // Create the hidden window - m_window = xcb_generate_id(m_connection); - xcb_create_window( - m_connection, - static_cast(visualInfo.depth), - m_window, - screen->root, - 0, 0, - width, height, - 0, - XCB_WINDOW_CLASS_INPUT_OUTPUT, - visualInfo.visualid, - XCB_CW_COLORMAP, - value_list - ); + // Create the rendering surface (window or pbuffer if supported) + createSurface(shared, width, height, VideoMode::getDesktopMode().bitsPerPixel); // Create the context - createContext(shared, VideoMode::getDesktopMode().bitsPerPixel, settings); + createContext(shared); } @@ -214,6 +186,11 @@ GlxContext::~GlxContext() #endif } + if (m_pbuffer) + { + glXDestroyPbuffer(m_display, m_pbuffer); + } + // Destroy the window if we own it if (m_window && m_ownsWindow) { @@ -243,7 +220,16 @@ bool GlxContext::makeCurrent() GlxErrorHandler handler(m_display); #endif - bool result = glXMakeCurrent(m_display, m_window, m_context); + bool result = false; + + if (m_pbuffer) + { + result = glXMakeContextCurrent(m_display, m_pbuffer, m_pbuffer, m_context); + } + else if (m_window) + { + result = glXMakeCurrent(m_display, m_window, m_context); + } #if defined(GLX_DEBUGGING) if (glxErrorOccurred) @@ -261,7 +247,9 @@ void GlxContext::display() GlxErrorHandler handler(m_display); #endif - if (m_window) + if (m_pbuffer) + glXSwapBuffers(m_display, m_pbuffer); + else if (m_window) glXSwapBuffers(m_display, m_window); #if defined(GLX_DEBUGGING) @@ -285,7 +273,7 @@ void GlxContext::setVerticalSyncEnabled(bool enabled) // which would require us to link in an additional library if (sfglx_ext_EXT_swap_control == sfglx_LOAD_SUCCEEDED) { - glXSwapIntervalEXT(m_display, glXGetCurrentDrawable(), enabled ? 1 : 0); + glXSwapIntervalEXT(m_display, m_pbuffer ? m_pbuffer : m_window, enabled ? 1 : 0); } else if (sfglx_ext_MESA_swap_control == sfglx_LOAD_SUCCEEDED) { @@ -380,12 +368,35 @@ XVisualInfo GlxContext::selectBestVisual(::Display* display, unsigned int bitsPe } } -//////////////////////////////////////////////////////////// -void GlxContext::createContext(GlxContext* shared, unsigned int bitsPerPixel, const ContextSettings& settings) -{ - // Save the creation settings - m_settings = settings; +//////////////////////////////////////////////////////////// +void GlxContext::updateSettingsFromVisualInfo(XVisualInfo* visualInfo) +{ + // Update the creation settings from the chosen format + int depth, stencil, multiSampling, samples; + glXGetConfig(m_display, visualInfo, GLX_DEPTH_SIZE, &depth); + glXGetConfig(m_display, visualInfo, GLX_STENCIL_SIZE, &stencil); + + if (sfglx_ext_ARB_multisample == sfglx_LOAD_SUCCEEDED) + { + glXGetConfig(m_display, visualInfo, GLX_SAMPLE_BUFFERS_ARB, &multiSampling); + glXGetConfig(m_display, visualInfo, GLX_SAMPLES_ARB, &samples); + } + else + { + multiSampling = 0; + samples = 0; + } + + m_settings.depthBits = static_cast(depth); + m_settings.stencilBits = static_cast(stencil); + m_settings.antialiasingLevel = multiSampling ? samples : 0; +} + + +//////////////////////////////////////////////////////////// +void GlxContext::updateSettingsFromWindow() +{ // Retrieve the attributes of the target window XWindowAttributes windowAttributes; if (XGetWindowAttributes(m_display, m_window, &windowAttributes) == 0) @@ -401,6 +412,180 @@ void GlxContext::createContext(GlxContext* shared, unsigned int bitsPerPixel, co int nbVisuals = 0; XVisualInfo* visualInfo = XGetVisualInfo(m_display, VisualIDMask | VisualScreenMask, &tpl, &nbVisuals); + if (!visualInfo) + return; + + updateSettingsFromVisualInfo(visualInfo); + + XFree(visualInfo); +} + + +//////////////////////////////////////////////////////////// +void GlxContext::createSurface(GlxContext* shared, unsigned int width, unsigned int height, unsigned int bitsPerPixel) +{ + m_display = OpenDisplay(); + m_connection = XGetXCBConnection(m_display); + + // Choose the visual according to the context settings + XVisualInfo visualInfo = selectBestVisual(m_display, bitsPerPixel, m_settings); + + // Check if the shared context already exists and pbuffers are supported + if (shared && (sfglx_ext_SGIX_pbuffer == sfglx_LOAD_SUCCEEDED)) + { + // There are no GLX versions prior to 1.0 + int major = 0; + int minor = 0; + + glXQueryVersion(m_display, &major, &minor); + + // Check if glXCreatePbuffer is available (requires GLX 1.3 or greater) + bool hasCreatePbuffer = ((major > 1) || (minor >= 3)); + + if (hasCreatePbuffer) + { + // Get a GLXFBConfig that matches the visual + GLXFBConfig* config = NULL; + + // We don't supply attributes to match against, since + // the visual we are matching against was already + // deemed suitable in selectBestVisual() + int nbConfigs = 0; + GLXFBConfig* configs = glXChooseFBConfig(m_display, DefaultScreen(m_display), NULL, &nbConfigs); + + for (int i = 0; configs && (i < nbConfigs); ++i) + { + XVisualInfo* visual = glXGetVisualFromFBConfig(m_display, configs[i]); + + if (!visual) + continue; + + if (visual->visualid == visualInfo.visualid) + { + config = &configs[i]; + break; + } + } + + if (config) + { + int attributes[] = + { + GLX_PBUFFER_WIDTH, static_cast(width), + GLX_PBUFFER_HEIGHT, static_cast(height), + 0, 0 + }; + + m_pbuffer = glXCreatePbuffer(m_display, *config, attributes); + + updateSettingsFromVisualInfo(&visualInfo); + + XFree(configs); + + return; + } + + if (configs) + XFree(configs); + } + } + + // If pbuffers are not available we use a hidden window as the off-screen surface to draw to + xcb_screen_t* screen = XCBScreenOfDisplay(m_connection, DefaultScreen(m_display)); + + // Define the window attributes + xcb_colormap_t colormap = xcb_generate_id(m_connection); + xcb_create_colormap(m_connection, XCB_COLORMAP_ALLOC_NONE, colormap, screen->root, visualInfo.visualid); + const uint32_t value_list[] = {colormap}; + + // Create a dummy window (disabled and hidden) + m_window = xcb_generate_id(m_connection); + xcb_create_window( + m_connection, + static_cast(visualInfo.depth), + m_window, + screen->root, + 0, 0, + width, height, + 0, + XCB_WINDOW_CLASS_INPUT_OUTPUT, + visualInfo.visualid, + XCB_CW_COLORMAP, + value_list + ); + + m_ownsWindow = true; + + updateSettingsFromWindow(); +} + + +//////////////////////////////////////////////////////////// +void GlxContext::createSurface(::Window window) +{ + m_display = OpenDisplay(); + m_connection = XGetXCBConnection(m_display); + + // A window already exists, so just use it + m_window = window; + + updateSettingsFromWindow(); +} + + +//////////////////////////////////////////////////////////// +void GlxContext::createContext(GlxContext* shared) +{ + // Get a working copy of the context settings + ContextSettings settings = m_settings; + + XVisualInfo* visualInfo = NULL; + + if (m_pbuffer) + { + unsigned int fbConfigId = 0; + + glXQueryDrawable(m_display, m_pbuffer, GLX_FBCONFIG_ID, &fbConfigId); + + int attributes[] = + { + GLX_FBCONFIG_ID, static_cast(fbConfigId), + 0, 0 + }; + + int count = 0; + GLXFBConfig* fbconfig = glXChooseFBConfig(m_display, DefaultScreen(m_display), attributes, &count); + + if (count == 1) + visualInfo = glXGetVisualFromFBConfig(m_display, *fbconfig); + + if (fbconfig) + XFree(fbconfig); + } + else + { + // Retrieve the attributes of the target window + XWindowAttributes windowAttributes; + if (XGetWindowAttributes(m_display, m_window, &windowAttributes) == 0) + { + err() << "Failed to get the window attributes" << std::endl; + return; + } + + // Get its visuals + XVisualInfo tpl; + tpl.screen = DefaultScreen(m_display); + tpl.visualid = XVisualIDFromVisual(windowAttributes.visual); + int nbVisuals = 0; + visualInfo = XGetVisualInfo(m_display, VisualIDMask | VisualScreenMask, &tpl, &nbVisuals); + } + + if (!visualInfo) + { + err() << "Failed to get visual info" << std::endl; + return; + } + // Get the context to share display lists with GLXContext toShare = shared ? shared->m_context : NULL; @@ -411,18 +596,13 @@ void GlxContext::createContext(GlxContext* shared, unsigned int bitsPerPixel, co if (!glXQueryVersion(m_display, &major, &minor)) err() << "Failed to query GLX version, limited to legacy context creation" << std::endl; - // Make sure that extensions are initialized if this is not the shared context - // The shared context is the context used to initialize the extensions - if (shared) - ensureExtensionsInit(m_display, DefaultScreen(m_display)); - // Check if glXCreateContextAttribsARB is available (requires GLX 1.3 or greater) bool hasCreateContextArb = (sfglx_ext_ARB_create_context == sfglx_LOAD_SUCCEEDED) && ((major > 1) || (minor >= 3)); // Create the OpenGL context -- first try using glXCreateContextAttribsARB if (hasCreateContextArb) { - // Get a GLXFBConfig that matches the the window's visual, for glXCreateContextAttribsARB + // Get a GLXFBConfig that matches the window's visual, for glXCreateContextAttribsARB GLXFBConfig* config = NULL; // We don't supply attributes to match against, since @@ -545,31 +725,7 @@ void GlxContext::createContext(GlxContext* shared, unsigned int bitsPerPixel, co } if (!m_context) - { err() << "Failed to create an OpenGL context for this window" << std::endl; - } - else - { - // Update the creation settings from the chosen format - int depth, stencil, multiSampling, samples; - glXGetConfig(m_display, visualInfo, GLX_DEPTH_SIZE, &depth); - glXGetConfig(m_display, visualInfo, GLX_STENCIL_SIZE, &stencil); - - if (sfglx_ext_ARB_multisample == sfglx_LOAD_SUCCEEDED) - { - glXGetConfig(m_display, visualInfo, GLX_SAMPLE_BUFFERS_ARB, &multiSampling); - glXGetConfig(m_display, visualInfo, GLX_SAMPLES_ARB, &samples); - } - else - { - multiSampling = 0; - samples = 0; - } - - m_settings.depthBits = static_cast(depth); - m_settings.stencilBits = static_cast(stencil); - m_settings.antialiasingLevel = multiSampling ? samples : 0; - } // Free the visual info XFree(visualInfo); diff --git a/src/SFML/Window/Unix/GlxContext.hpp b/src/SFML/Window/Unix/GlxContext.hpp index e1ad8998b..36ba98a60 100644 --- a/src/SFML/Window/Unix/GlxContext.hpp +++ b/src/SFML/Window/Unix/GlxContext.hpp @@ -133,14 +133,45 @@ public: private: //////////////////////////////////////////////////////////// - /// \brief Create the context + /// \brief Update the context visual settings from XVisualInfo /// - /// \param shared Context to share the new one with (can be NULL) - /// \param bitsPerPixel Pixel depth, in bits per pixel - /// \param settings Creation parameters + /// \param visualInfo XVisualInfo to update settings from /// //////////////////////////////////////////////////////////// - void createContext(GlxContext* shared, unsigned int bitsPerPixel, const ContextSettings& settings); + void updateSettingsFromVisualInfo(XVisualInfo* visualInfo); + + //////////////////////////////////////////////////////////// + /// \brief Update the context visual settings from the window + /// + //////////////////////////////////////////////////////////// + void updateSettingsFromWindow(); + + //////////////////////////////////////////////////////////// + /// \brief Create the context's drawing surface + /// + /// \param shared Context to share the new one with (can be NULL) + /// \param width Back buffer width, in pixels + /// \param height Back buffer height, in pixels + /// \param bitsPerPixel Pixel depth, in bits per pixel + /// + //////////////////////////////////////////////////////////// + void createSurface(GlxContext* shared, unsigned int width, unsigned int height, unsigned int bitsPerPixel); + + //////////////////////////////////////////////////////////// + /// \brief Create the context's drawing surface from an existing window + /// + /// \param window Window ID of the owning window + /// + //////////////////////////////////////////////////////////// + void createSurface(::Window window); + + //////////////////////////////////////////////////////////// + /// \brief Create the context + /// + /// \param shared Context to share the new one with (can be NULL) + /// + //////////////////////////////////////////////////////////// + void createContext(GlxContext* shared); //////////////////////////////////////////////////////////// // Member data @@ -149,6 +180,7 @@ private: ::Window m_window; ///< Window to which the context is attached xcb_connection_t* m_connection; ///< Pointer to the xcb connection GLXContext m_context; ///< OpenGL context + GLXPbuffer m_pbuffer; ///< GLX pbuffer ID if one was created bool m_ownsWindow; ///< Do we own the window associated to the context? }; diff --git a/src/SFML/Window/Unix/GlxExtensions.cpp b/src/SFML/Window/Unix/GlxExtensions.cpp index 3bacdff87..96ddbaf28 100644 --- a/src/SFML/Window/Unix/GlxExtensions.cpp +++ b/src/SFML/Window/Unix/GlxExtensions.cpp @@ -41,6 +41,7 @@ int sfglx_ext_EXT_swap_control = sfglx_LOAD_FAILED; int sfglx_ext_MESA_swap_control = sfglx_LOAD_FAILED; int sfglx_ext_SGI_swap_control = sfglx_LOAD_FAILED; int sfglx_ext_ARB_multisample = sfglx_LOAD_FAILED; +int sfglx_ext_SGIX_pbuffer = sfglx_LOAD_FAILED; int sfglx_ext_ARB_create_context = sfglx_LOAD_FAILED; int sfglx_ext_ARB_create_context_profile = sfglx_LOAD_FAILED; @@ -77,6 +78,33 @@ static int Load_SGI_swap_control(void) return numFailed; } +GLXPbufferSGIX (CODEGEN_FUNCPTR *sf_ptrc_glXCreateGLXPbufferSGIX)(Display*, GLXFBConfigSGIX, unsigned int, unsigned int, int*) = NULL; +void (CODEGEN_FUNCPTR *sf_ptrc_glXDestroyGLXPbufferSGIX)(Display*, GLXPbufferSGIX) = NULL; +void (CODEGEN_FUNCPTR *sf_ptrc_glXGetSelectedEventSGIX)(Display*, GLXDrawable, unsigned long*) = NULL; +int (CODEGEN_FUNCPTR *sf_ptrc_glXQueryGLXPbufferSGIX)(Display*, GLXPbufferSGIX, int, unsigned int*) = NULL; +void (CODEGEN_FUNCPTR *sf_ptrc_glXSelectEventSGIX)(Display*, GLXDrawable, unsigned long) = NULL; + +static int Load_SGIX_pbuffer(void) +{ + int numFailed = 0; + sf_ptrc_glXCreateGLXPbufferSGIX = reinterpret_cast(IntGetProcAddress("glXCreateGLXPbufferSGIX")); + if (!sf_ptrc_glXCreateGLXPbufferSGIX) + numFailed++; + sf_ptrc_glXDestroyGLXPbufferSGIX = reinterpret_cast(IntGetProcAddress("glXDestroyGLXPbufferSGIX")); + if (!sf_ptrc_glXDestroyGLXPbufferSGIX) + numFailed++; + sf_ptrc_glXGetSelectedEventSGIX = reinterpret_cast(IntGetProcAddress("glXGetSelectedEventSGIX")); + if (!sf_ptrc_glXGetSelectedEventSGIX) + numFailed++; + sf_ptrc_glXQueryGLXPbufferSGIX = reinterpret_cast(IntGetProcAddress("glXQueryGLXPbufferSGIX")); + if (!sf_ptrc_glXQueryGLXPbufferSGIX) + numFailed++; + sf_ptrc_glXSelectEventSGIX = reinterpret_cast(IntGetProcAddress("glXSelectEventSGIX")); + if (!sf_ptrc_glXSelectEventSGIX) + numFailed++; + return numFailed; +} + GLXContext (CODEGEN_FUNCPTR *sf_ptrc_glXCreateContextAttribsARB)(Display*, GLXFBConfig, GLXContext, Bool, const int*) = NULL; static int Load_ARB_create_context(void) @@ -96,16 +124,17 @@ typedef struct sfglx_StrToExtMap_s PFN_LOADFUNCPOINTERS LoadExtension; } sfglx_StrToExtMap; -static sfglx_StrToExtMap ExtensionMap[6] = { +static sfglx_StrToExtMap ExtensionMap[7] = { {"GLX_EXT_swap_control", &sfglx_ext_EXT_swap_control, Load_EXT_swap_control}, {"GLX_MESA_swap_control", &sfglx_ext_MESA_swap_control, Load_MESA_swap_control}, {"GLX_SGI_swap_control", &sfglx_ext_SGI_swap_control, Load_SGI_swap_control}, {"GLX_ARB_multisample", &sfglx_ext_ARB_multisample, NULL}, + {"GLX_SGIX_pbuffer", &sfglx_ext_SGIX_pbuffer, Load_SGIX_pbuffer}, {"GLX_ARB_create_context", &sfglx_ext_ARB_create_context, Load_ARB_create_context}, {"GLX_ARB_create_context_profile", &sfglx_ext_ARB_create_context_profile, NULL}, }; -static int g_extensionMapSize = 6; +static int g_extensionMapSize = 7; static sfglx_StrToExtMap* FindExtEntry(const char* extensionName) @@ -127,6 +156,7 @@ static void ClearExtensionVars(void) sfglx_ext_MESA_swap_control = sfglx_LOAD_FAILED; sfglx_ext_SGI_swap_control = sfglx_LOAD_FAILED; sfglx_ext_ARB_multisample = sfglx_LOAD_FAILED; + sfglx_ext_SGIX_pbuffer = sfglx_LOAD_FAILED; sfglx_ext_ARB_create_context = sfglx_LOAD_FAILED; sfglx_ext_ARB_create_context_profile = sfglx_LOAD_FAILED; } diff --git a/src/SFML/Window/Unix/GlxExtensions.hpp b/src/SFML/Window/Unix/GlxExtensions.hpp index c749de25c..cc68bb547 100644 --- a/src/SFML/Window/Unix/GlxExtensions.hpp +++ b/src/SFML/Window/Unix/GlxExtensions.hpp @@ -145,6 +145,7 @@ extern int sfglx_ext_EXT_swap_control; extern int sfglx_ext_MESA_swap_control; extern int sfglx_ext_SGI_swap_control; extern int sfglx_ext_ARB_multisample; +extern int sfglx_ext_SGIX_pbuffer; extern int sfglx_ext_ARB_create_context; extern int sfglx_ext_ARB_create_context_profile; @@ -154,6 +155,32 @@ extern int sfglx_ext_ARB_create_context_profile; #define GLX_SAMPLES_ARB 100001 #define GLX_SAMPLE_BUFFERS_ARB 100000 +#define GLX_ACCUM_BUFFER_BIT_SGIX 0x00000080 +#define GLX_AUX_BUFFERS_BIT_SGIX 0x00000010 +#define GLX_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT_SGIX 0x00000008 +#define GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000 +#define GLX_DAMAGED_SGIX 0x8020 +#define GLX_DEPTH_BUFFER_BIT_SGIX 0x00000020 +#define GLX_EVENT_MASK_SGIX 0x801F +#define GLX_FRONT_LEFT_BUFFER_BIT_SGIX 0x00000001 +#define GLX_FRONT_RIGHT_BUFFER_BIT_SGIX 0x00000002 +#define GLX_HEIGHT_SGIX 0x801E +#define GLX_LARGEST_PBUFFER_SGIX 0x801C +#define GLX_MAX_PBUFFER_HEIGHT_SGIX 0x8017 +#define GLX_MAX_PBUFFER_PIXELS_SGIX 0x8018 +#define GLX_MAX_PBUFFER_WIDTH_SGIX 0x8016 +#define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A +#define GLX_OPTIMAL_PBUFFER_WIDTH_SGIX 0x8019 +#define GLX_PBUFFER_BIT_SGIX 0x00000004 +#define GLX_PBUFFER_SGIX 0x8023 +#define GLX_PRESERVED_CONTENTS_SGIX 0x801B +#define GLX_SAMPLE_BUFFERS_BIT_SGIX 0x00000100 +#define GLX_SAVED_SGIX 0x8021 +#define GLX_STENCIL_BUFFER_BIT_SGIX 0x00000040 +#define GLX_WIDTH_SGIX 0x801D +#define GLX_WINDOW_SGIX 0x8022 + #define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001 #define GLX_CONTEXT_FLAGS_ARB 0x2094 #define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 @@ -180,6 +207,20 @@ extern int (CODEGEN_FUNCPTR *sf_ptrc_glXSwapIntervalSGI)(int); #define glXSwapIntervalSGI sf_ptrc_glXSwapIntervalSGI #endif // GLX_SGI_swap_control +#ifndef GLX_SGIX_pbuffer +#define GLX_SGIX_pbuffer 1 +extern GLXPbufferSGIX (CODEGEN_FUNCPTR *sf_ptrc_glXCreateGLXPbufferSGIX)(Display*, GLXFBConfigSGIX, unsigned int, unsigned int, int*); +#define glXCreateGLXPbufferSGIX sf_ptrc_glXCreateGLXPbufferSGIX +extern void (CODEGEN_FUNCPTR *sf_ptrc_glXDestroyGLXPbufferSGIX)(Display*, GLXPbufferSGIX); +#define glXDestroyGLXPbufferSGIX sf_ptrc_glXDestroyGLXPbufferSGIX +extern void (CODEGEN_FUNCPTR *sf_ptrc_glXGetSelectedEventSGIX)(Display*, GLXDrawable, unsigned long*); +#define glXGetSelectedEventSGIX sf_ptrc_glXGetSelectedEventSGIX +extern int (CODEGEN_FUNCPTR *sf_ptrc_glXQueryGLXPbufferSGIX)(Display*, GLXPbufferSGIX, int, unsigned int*); +#define glXQueryGLXPbufferSGIX sf_ptrc_glXQueryGLXPbufferSGIX +extern void (CODEGEN_FUNCPTR *sf_ptrc_glXSelectEventSGIX)(Display*, GLXDrawable, unsigned long); +#define glXSelectEventSGIX sf_ptrc_glXSelectEventSGIX +#endif // GLX_SGIX_pbuffer + #ifndef GLX_ARB_create_context #define GLX_ARB_create_context 1 extern GLXContext (CODEGEN_FUNCPTR *sf_ptrc_glXCreateContextAttribsARB)(Display*, GLXFBConfig, GLXContext, Bool, const int*); diff --git a/src/SFML/Window/Unix/GlxExtensions.txt b/src/SFML/Window/Unix/GlxExtensions.txt index b6b06fa90..4c54582d6 100644 --- a/src/SFML/Window/Unix/GlxExtensions.txt +++ b/src/SFML/Window/Unix/GlxExtensions.txt @@ -1,11 +1,12 @@ // Created with: -// https://bitbucket.org/Anteru/glloadgen-reloaded -// Commit 20f19482b7a844d20b9785c3e3fd1f16419f6e0a +// https://bitbucket.org/KhronosGroup/glloadgen +// Commit d143d66ac90d538ed06f806188714861b8e8e2f9 // lua LoadGen.lua -style=pointer_c -spec=glX -indent=space -prefix=sf -extfile=GlxExtensions.txt GlxExtensions EXT_swap_control // MESA_swap_control SGI_swap_control GLX_ARB_multisample +GLX_SGIX_pbuffer GLX_ARB_create_context -GLX_ARB_create_context_profile \ No newline at end of file +GLX_ARB_create_context_profile diff --git a/src/SFML/Window/Win32/WglContext.cpp b/src/SFML/Window/Win32/WglContext.cpp index b9bb8e61c..04182f0ca 100644 --- a/src/SFML/Window/Win32/WglContext.cpp +++ b/src/SFML/Window/Win32/WglContext.cpp @@ -26,8 +26,8 @@ // Headers //////////////////////////////////////////////////////////// #include // included first to avoid a warning about macro redefinition +#include // included second to avoid an error in WglExtensions.hpp #include -#include #include #include #include @@ -70,62 +70,75 @@ String getErrorString(DWORD errorCode) //////////////////////////////////////////////////////////// WglContext::WglContext(WglContext* shared) : m_window (NULL), +m_pbuffer (NULL), m_deviceContext(NULL), m_context (NULL), -m_ownsWindow (true) +m_ownsWindow (false) { - // Creating a dummy window is mandatory: we could create a memory DC but then - // its pixel format wouldn't match the regular contexts' format, and thus - // wglShareLists would always fail. Too bad... + // Save the creation settings + m_settings = ContextSettings(); - // Create a dummy window (disabled and hidden) - m_window = CreateWindowA("STATIC", "", WS_POPUP | WS_DISABLED, 0, 0, 1, 1, NULL, NULL, GetModuleHandle(NULL), NULL); - ShowWindow(m_window, SW_HIDE); - m_deviceContext = GetDC(m_window); + // Make sure that extensions are initialized if this is not the shared context + // The shared context is the context used to initialize the extensions + if (shared && shared->m_deviceContext) + ensureExtensionsInit(shared->m_deviceContext); + + // Create the rendering surface (window or pbuffer if supported) + createSurface(shared, 1, 1, VideoMode::getDesktopMode().bitsPerPixel); // Create the context if (m_deviceContext) - createContext(shared, VideoMode::getDesktopMode().bitsPerPixel, ContextSettings()); + createContext(shared); } //////////////////////////////////////////////////////////// WglContext::WglContext(WglContext* shared, const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel) : m_window (NULL), +m_pbuffer (NULL), m_deviceContext(NULL), m_context (NULL), m_ownsWindow (false) { - // Get the owner window and its device context - m_window = owner->getSystemHandle(); - m_deviceContext = GetDC(m_window); + // Save the creation settings + m_settings = settings; + + // Make sure that extensions are initialized if this is not the shared context + // The shared context is the context used to initialize the extensions + if (shared && shared->m_deviceContext) + ensureExtensionsInit(shared->m_deviceContext); + + // Create the rendering surface from the owner window + createSurface(owner->getSystemHandle(), bitsPerPixel); // Create the context if (m_deviceContext) - createContext(shared, bitsPerPixel, settings); + createContext(shared); } //////////////////////////////////////////////////////////// WglContext::WglContext(WglContext* shared, const ContextSettings& settings, unsigned int width, unsigned int height) : m_window (NULL), +m_pbuffer (NULL), m_deviceContext(NULL), m_context (NULL), -m_ownsWindow (true) +m_ownsWindow (false) { - // The target of the context is a hidden window. - // We can't create a memory DC (the resulting context wouldn't be compatible - // with other contexts), and we don't add the extra complexity of P-Buffers; - // we can still support them in the future if this solution is not good enough. + // Save the creation settings + m_settings = settings; - // Create the hidden window - m_window = CreateWindowA("STATIC", "", WS_POPUP | WS_DISABLED, 0, 0, width, height, NULL, NULL, GetModuleHandle(NULL), NULL); - ShowWindow(m_window, SW_HIDE); - m_deviceContext = GetDC(m_window); + // Make sure that extensions are initialized if this is not the shared context + // The shared context is the context used to initialize the extensions + if (shared && shared->m_deviceContext) + ensureExtensionsInit(shared->m_deviceContext); + + // Create the rendering surface (window or pbuffer if supported) + createSurface(shared, width, height, VideoMode::getDesktopMode().bitsPerPixel); // Create the context if (m_deviceContext) - createContext(shared, VideoMode::getDesktopMode().bitsPerPixel, settings); + createContext(shared); } @@ -142,7 +155,17 @@ WglContext::~WglContext() // Destroy the device context if (m_deviceContext) - ReleaseDC(m_window, m_deviceContext); + { + if (m_pbuffer) + { + wglReleasePbufferDCARB(m_pbuffer, m_deviceContext); + wglDestroyPbufferARB(m_pbuffer); + } + else + { + ReleaseDC(m_window, m_deviceContext); + } + } // Destroy the window if we own it if (m_window && m_ownsWindow) @@ -218,7 +241,7 @@ void WglContext::setVerticalSyncEnabled(bool enabled) //////////////////////////////////////////////////////////// -int WglContext::selectBestPixelFormat(HDC deviceContext, unsigned int bitsPerPixel, const ContextSettings& settings) +int WglContext::selectBestPixelFormat(HDC deviceContext, unsigned int bitsPerPixel, const ContextSettings& settings, bool pbuffer) { // Let's find a suitable pixel format -- first try with wglChoosePixelFormatARB int bestFormat = 0; @@ -280,6 +303,25 @@ int WglContext::selectBestPixelFormat(HDC deviceContext, unsigned int bitsPerPix } } + if (pbuffer) + { + const int pbufferAttributes[] = + { + WGL_DRAW_TO_PBUFFER_ARB + }; + + int pbufferValue = 0; + + if (!wglGetPixelFormatAttribivARB(deviceContext, formats[i], PFD_MAIN_PLANE, 1, pbufferAttributes, &pbufferValue)) + { + err() << "Failed to retrieve pixel format pbuffer information: " << getErrorString(GetLastError()).toAnsiString() << std::endl; + break; + } + + if (pbufferValue != GL_TRUE) + continue; + } + // Evaluate the current configuration int color = values[0] + values[1] + values[2] + values[3]; int score = evaluateFormat(bitsPerPixel, settings, color, values[4], values[5], sampleValues[0] ? sampleValues[1] : 0, values[6] == WGL_FULL_ACCELERATION_ARB); @@ -294,6 +336,10 @@ int WglContext::selectBestPixelFormat(HDC deviceContext, unsigned int bitsPerPix } } + // ChoosePixelFormat doesn't support pbuffers + if (pbuffer) + return bestFormat; + // Find a pixel format with ChoosePixelFormat, if wglChoosePixelFormatARB is not supported if (bestFormat == 0) { @@ -319,17 +365,9 @@ int WglContext::selectBestPixelFormat(HDC deviceContext, unsigned int bitsPerPix //////////////////////////////////////////////////////////// -void WglContext::createContext(WglContext* shared, unsigned int bitsPerPixel, const ContextSettings& settings) +void WglContext::setDevicePixelFormat(unsigned int bitsPerPixel) { - // Save the creation settings - m_settings = settings; - - // Make sure that extensions are initialized if this is not the shared context - // The shared context is the context used to initialize the extensions - if (shared) - ensureExtensionsInit(m_deviceContext); - - int bestFormat = selectBestPixelFormat(m_deviceContext, bitsPerPixel, settings); + int bestFormat = selectBestPixelFormat(m_deviceContext, bitsPerPixel, m_settings); if (bestFormat == 0) { @@ -344,12 +382,38 @@ void WglContext::createContext(WglContext* shared, unsigned int bitsPerPixel, co actualFormat.nVersion = 1; DescribePixelFormat(m_deviceContext, bestFormat, sizeof(actualFormat), &actualFormat); + // Set the chosen pixel format + if (!SetPixelFormat(m_deviceContext, bestFormat, &actualFormat)) + { + err() << "Failed to set pixel format for device context: " << getErrorString(GetLastError()).toAnsiString() << std::endl + << "Cannot create OpenGL context" << std::endl; + return; + } +} + + +//////////////////////////////////////////////////////////// +void WglContext::updateSettingsFromPixelFormat() +{ + int format = GetPixelFormat(m_deviceContext); + + PIXELFORMATDESCRIPTOR actualFormat; + actualFormat.nSize = sizeof(actualFormat); + actualFormat.nVersion = 1; + DescribePixelFormat(m_deviceContext, format, sizeof(actualFormat), &actualFormat); + + if (format == 0) + { + err() << "Failed to get selected pixel format" << std::endl; + return; + } + if (sfwgl_ext_ARB_pixel_format == sfwgl_LOAD_SUCCEEDED) { const int attributes[] = {WGL_DEPTH_BITS_ARB, WGL_STENCIL_BITS_ARB}; int values[2]; - if (wglGetPixelFormatAttribivARB(m_deviceContext, bestFormat, PFD_MAIN_PLANE, 2, attributes, values)) + if (wglGetPixelFormatAttribivARB(m_deviceContext, format, PFD_MAIN_PLANE, 2, attributes, values)) { m_settings.depthBits = values[0]; m_settings.stencilBits = values[1]; @@ -366,7 +430,7 @@ void WglContext::createContext(WglContext* shared, unsigned int bitsPerPixel, co const int sampleAttributes[] = {WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB}; int sampleValues[2]; - if (wglGetPixelFormatAttribivARB(m_deviceContext, bestFormat, PFD_MAIN_PLANE, 2, sampleAttributes, sampleValues)) + if (wglGetPixelFormatAttribivARB(m_deviceContext, format, PFD_MAIN_PLANE, 2, sampleAttributes, sampleValues)) { m_settings.antialiasingLevel = sampleValues[0] ? sampleValues[1] : 0; } @@ -387,15 +451,79 @@ void WglContext::createContext(WglContext* shared, unsigned int bitsPerPixel, co m_settings.stencilBits = actualFormat.cStencilBits; m_settings.antialiasingLevel = 0; } +} - // Set the chosen pixel format - if (!SetPixelFormat(m_deviceContext, bestFormat, &actualFormat)) + +//////////////////////////////////////////////////////////// +void WglContext::createSurface(WglContext* shared, unsigned int width, unsigned int height, unsigned int bitsPerPixel) +{ + // Check if the shared context already exists and pbuffers are supported + if (shared && shared->m_deviceContext && (sfwgl_ext_ARB_pbuffer == sfwgl_LOAD_SUCCEEDED)) { - err() << "Failed to set pixel format for device context: " << getErrorString(GetLastError()).toAnsiString() << std::endl - << "Cannot create OpenGL context" << std::endl; - return; + int bestFormat = selectBestPixelFormat(shared->m_deviceContext, bitsPerPixel, m_settings, true); + + if (bestFormat > 0) + { + int attributes[] = {0, 0}; + + m_pbuffer = wglCreatePbufferARB(shared->m_deviceContext, bestFormat, width, height, attributes); + + if (m_pbuffer) + { + m_window = shared->m_window; + m_deviceContext = wglGetPbufferDCARB(m_pbuffer); + + if (!m_deviceContext) + { + wglDestroyPbufferARB(m_pbuffer); + m_pbuffer = NULL; + } + } + } } + // If pbuffers are not available we use a hidden window as the off-screen surface to draw to + if (!m_deviceContext) + { + // We can't create a memory DC, the resulting context wouldn't be compatible + // with other contexts and thus wglShareLists would always fail + + // Create the hidden window + m_window = CreateWindowA("STATIC", "", WS_POPUP | WS_DISABLED, 0, 0, width, height, NULL, NULL, GetModuleHandle(NULL), NULL); + ShowWindow(m_window, SW_HIDE); + m_deviceContext = GetDC(m_window); + + m_ownsWindow = true; + + // Set the pixel format of the device context + setDevicePixelFormat(bitsPerPixel); + } + + // Update context settings from the selected pixel format + updateSettingsFromPixelFormat(); +} + + +//////////////////////////////////////////////////////////// +void WglContext::createSurface(HWND window, unsigned int bitsPerPixel) +{ + m_window = window; + m_deviceContext = GetDC(window); + + // Set the pixel format of the device context + setDevicePixelFormat(bitsPerPixel); + + // Update context settings from the selected pixel format + updateSettingsFromPixelFormat(); +} + + +//////////////////////////////////////////////////////////// +void WglContext::createContext(WglContext* shared) +{ + // Get a working copy of the context settings + ContextSettings settings = m_settings; + // Get the context to share display lists with HGLRC sharedContext = shared ? shared->m_context : NULL; diff --git a/src/SFML/Window/Win32/WglContext.hpp b/src/SFML/Window/Win32/WglContext.hpp index 45070f62b..acc529135 100644 --- a/src/SFML/Window/Win32/WglContext.hpp +++ b/src/SFML/Window/Win32/WglContext.hpp @@ -29,8 +29,7 @@ // Headers //////////////////////////////////////////////////////////// #include -#include -#include +#include namespace sf @@ -124,31 +123,65 @@ public: /// \param deviceContext Device context /// \param bitsPerPixel Pixel depth, in bits per pixel /// \param settings Requested context settings + /// \param pbuffer Whether the pixel format should support pbuffers /// /// \return The best pixel format /// //////////////////////////////////////////////////////////// - static int selectBestPixelFormat(HDC deviceContext, unsigned int bitsPerPixel, const ContextSettings& settings); + static int selectBestPixelFormat(HDC deviceContext, unsigned int bitsPerPixel, const ContextSettings& settings, bool pbuffer = false); private: //////////////////////////////////////////////////////////// - /// \brief Create the context + /// \brief Set the pixel format of the device context /// - /// \param shared Context to share the new one with (can be NULL) - /// \param bitsPerPixel Pixel depth, in bits per pixel - /// \param settings Creation parameters + /// \param bitsPerPixel Pixel depth, in bits per pixel /// //////////////////////////////////////////////////////////// - void createContext(WglContext* shared, unsigned int bitsPerPixel, const ContextSettings& settings); + void setDevicePixelFormat(unsigned int bitsPerPixel); + + //////////////////////////////////////////////////////////// + /// \brief Update the context settings from the selected pixel format + /// + //////////////////////////////////////////////////////////// + void updateSettingsFromPixelFormat(); + + //////////////////////////////////////////////////////////// + /// \brief Create the context's drawing surface + /// + /// \param shared Shared context (can be NULL) + /// \param width Back buffer width, in pixels + /// \param height Back buffer height, in pixels + /// \param bitsPerPixel Pixel depth, in bits per pixel + /// + //////////////////////////////////////////////////////////// + void createSurface(WglContext* shared, unsigned int width, unsigned int height, unsigned int bitsPerPixel); + + //////////////////////////////////////////////////////////// + /// \brief Create the context's drawing surface from an existing window + /// + /// \param window Window handle of the owning window + /// \param bitsPerPixel Pixel depth, in bits per pixel + /// + //////////////////////////////////////////////////////////// + void createSurface(HWND window, unsigned int bitsPerPixel); + + //////////////////////////////////////////////////////////// + /// \brief Create the context + /// + /// \param shared Context to share the new one with (can be NULL) + /// + //////////////////////////////////////////////////////////// + void createContext(WglContext* shared); //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - HWND m_window; ///< Window to which the context is attached - HDC m_deviceContext; ///< Device context associated to the context - HGLRC m_context; ///< OpenGL context - bool m_ownsWindow; ///< Do we own the target window? + HWND m_window; ///< Window to which the context is attached + HPBUFFERARB m_pbuffer; ///< Handle to a pbuffer if one was created + HDC m_deviceContext; ///< Device context associated to the context + HGLRC m_context; ///< OpenGL context + bool m_ownsWindow; ///< Do we own the target window? }; } // namespace priv diff --git a/src/SFML/Window/Win32/WglExtensions.cpp b/src/SFML/Window/Win32/WglExtensions.cpp index fc4eaa544..832cf357e 100644 --- a/src/SFML/Window/Win32/WglExtensions.cpp +++ b/src/SFML/Window/Win32/WglExtensions.cpp @@ -40,6 +40,7 @@ static sf::GlFunctionPointer IntGetProcAddress(const char* name) int sfwgl_ext_EXT_swap_control = sfwgl_LOAD_FAILED; int sfwgl_ext_ARB_multisample = sfwgl_LOAD_FAILED; int sfwgl_ext_ARB_pixel_format = sfwgl_LOAD_FAILED; +int sfwgl_ext_ARB_pbuffer = sfwgl_LOAD_FAILED; int sfwgl_ext_ARB_create_context = sfwgl_LOAD_FAILED; int sfwgl_ext_ARB_create_context_profile = sfwgl_LOAD_FAILED; @@ -77,6 +78,33 @@ static int Load_ARB_pixel_format(void) return numFailed; } +HPBUFFERARB (CODEGEN_FUNCPTR *sf_ptrc_wglCreatePbufferARB)(HDC, int, int, int, const int*) = NULL; +BOOL (CODEGEN_FUNCPTR *sf_ptrc_wglDestroyPbufferARB)(HPBUFFERARB) = NULL; +HDC (CODEGEN_FUNCPTR *sf_ptrc_wglGetPbufferDCARB)(HPBUFFERARB) = NULL; +BOOL (CODEGEN_FUNCPTR *sf_ptrc_wglQueryPbufferARB)(HPBUFFERARB, int, int*) = NULL; +int (CODEGEN_FUNCPTR *sf_ptrc_wglReleasePbufferDCARB)(HPBUFFERARB, HDC) = NULL; + +static int Load_ARB_pbuffer() +{ + int numFailed = 0; + sf_ptrc_wglCreatePbufferARB = reinterpret_cast(IntGetProcAddress("wglCreatePbufferARB")); + if (!sf_ptrc_wglCreatePbufferARB) + numFailed++; + sf_ptrc_wglDestroyPbufferARB = reinterpret_cast(IntGetProcAddress("wglDestroyPbufferARB")); + if (!sf_ptrc_wglDestroyPbufferARB) + numFailed++; + sf_ptrc_wglGetPbufferDCARB = reinterpret_cast(IntGetProcAddress("wglGetPbufferDCARB")); + if (!sf_ptrc_wglGetPbufferDCARB) + numFailed++; + sf_ptrc_wglQueryPbufferARB = reinterpret_cast(IntGetProcAddress("wglQueryPbufferARB")); + if (!sf_ptrc_wglQueryPbufferARB) + numFailed++; + sf_ptrc_wglReleasePbufferDCARB = reinterpret_cast(IntGetProcAddress("wglReleasePbufferDCARB")); + if (!sf_ptrc_wglReleasePbufferDCARB) + numFailed++; + return numFailed; +} + HGLRC (CODEGEN_FUNCPTR *sf_ptrc_wglCreateContextAttribsARB)(HDC, HGLRC, const int*) = NULL; static int Load_ARB_create_context(void) @@ -99,15 +127,16 @@ typedef struct sfwgl_StrToExtMap_s PFN_LOADFUNCPOINTERS LoadExtension; } sfwgl_StrToExtMap; -static sfwgl_StrToExtMap ExtensionMap[5] = { +static sfwgl_StrToExtMap ExtensionMap[6] = { {"WGL_EXT_swap_control", &sfwgl_ext_EXT_swap_control, Load_EXT_swap_control}, {"WGL_ARB_multisample", &sfwgl_ext_ARB_multisample, NULL}, {"WGL_ARB_pixel_format", &sfwgl_ext_ARB_pixel_format, Load_ARB_pixel_format}, + {"WGL_ARB_pbuffer", &sfwgl_ext_ARB_pbuffer, Load_ARB_pbuffer}, {"WGL_ARB_create_context", &sfwgl_ext_ARB_create_context, Load_ARB_create_context}, {"WGL_ARB_create_context_profile", &sfwgl_ext_ARB_create_context_profile, NULL}, }; -static int g_extensionMapSize = 5; +static int g_extensionMapSize = 6; static sfwgl_StrToExtMap* FindExtEntry(const char* extensionName) @@ -128,6 +157,7 @@ static void ClearExtensionVars(void) sfwgl_ext_EXT_swap_control = sfwgl_LOAD_FAILED; sfwgl_ext_ARB_multisample = sfwgl_LOAD_FAILED; sfwgl_ext_ARB_pixel_format = sfwgl_LOAD_FAILED; + sfwgl_ext_ARB_pbuffer = sfwgl_LOAD_FAILED; sfwgl_ext_ARB_create_context = sfwgl_LOAD_FAILED; sfwgl_ext_ARB_create_context_profile = sfwgl_LOAD_FAILED; } diff --git a/src/SFML/Window/Win32/WglExtensions.hpp b/src/SFML/Window/Win32/WglExtensions.hpp index b9b889f8e..4c08d8ca9 100644 --- a/src/SFML/Window/Win32/WglExtensions.hpp +++ b/src/SFML/Window/Win32/WglExtensions.hpp @@ -95,6 +95,7 @@ extern "C" { extern int sfwgl_ext_EXT_swap_control; extern int sfwgl_ext_ARB_multisample; extern int sfwgl_ext_ARB_pixel_format; +extern int sfwgl_ext_ARB_pbuffer; extern int sfwgl_ext_ARB_create_context; extern int sfwgl_ext_ARB_create_context_profile; @@ -151,6 +152,15 @@ extern int sfwgl_ext_ARB_create_context_profile; #define WGL_TYPE_COLORINDEX_ARB 0x202C #define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_DRAW_TO_PBUFFER_ARB 0x202D +#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 +#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E +#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F +#define WGL_PBUFFER_HEIGHT_ARB 0x2035 +#define WGL_PBUFFER_LARGEST_ARB 0x2033 +#define WGL_PBUFFER_LOST_ARB 0x2036 +#define WGL_PBUFFER_WIDTH_ARB 0x2034 + #define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001 #define WGL_CONTEXT_FLAGS_ARB 0x2094 #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 @@ -183,6 +193,20 @@ extern BOOL (CODEGEN_FUNCPTR *sf_ptrc_wglGetPixelFormatAttribivARB)(HDC, int, in #define wglGetPixelFormatAttribivARB sf_ptrc_wglGetPixelFormatAttribivARB #endif // WGL_ARB_pixel_format +#ifndef WGL_ARB_pbuffer +#define WGL_ARB_pbuffer 1 +extern HPBUFFERARB (CODEGEN_FUNCPTR *sf_ptrc_wglCreatePbufferARB)(HDC, int, int, int, const int*); +#define wglCreatePbufferARB sf_ptrc_wglCreatePbufferARB +extern BOOL (CODEGEN_FUNCPTR *sf_ptrc_wglDestroyPbufferARB)(HPBUFFERARB); +#define wglDestroyPbufferARB sf_ptrc_wglDestroyPbufferARB +extern HDC (CODEGEN_FUNCPTR *sf_ptrc_wglGetPbufferDCARB)(HPBUFFERARB); +#define wglGetPbufferDCARB sf_ptrc_wglGetPbufferDCARB +extern BOOL (CODEGEN_FUNCPTR *sf_ptrc_wglQueryPbufferARB)(HPBUFFERARB, int, int*); +#define wglQueryPbufferARB sf_ptrc_wglQueryPbufferARB +extern int (CODEGEN_FUNCPTR *sf_ptrc_wglReleasePbufferDCARB)(HPBUFFERARB, HDC); +#define wglReleasePbufferDCARB sf_ptrc_wglReleasePbufferDCARB +#endif // WGL_ARB_pbuffer + #ifndef WGL_ARB_create_context #define WGL_ARB_create_context 1 extern HGLRC (CODEGEN_FUNCPTR *sf_ptrc_wglCreateContextAttribsARB)(HDC, HGLRC, const int*); diff --git a/src/SFML/Window/Win32/WglExtensions.txt b/src/SFML/Window/Win32/WglExtensions.txt index 99610a674..0ac0ad03a 100644 --- a/src/SFML/Window/Win32/WglExtensions.txt +++ b/src/SFML/Window/Win32/WglExtensions.txt @@ -1,10 +1,11 @@ // Created with: -// https://bitbucket.org/Anteru/glloadgen-reloaded -// Commit 20f19482b7a844d20b9785c3e3fd1f16419f6e0a +// https://bitbucket.org/KhronosGroup/glloadgen +// Commit d143d66ac90d538ed06f806188714861b8e8e2f9 // lua LoadGen.lua -style=pointer_c -spec=wgl -indent=space -prefix=sf -extfile=WglExtensions.txt WglExtensions EXT_swap_control WGL_ARB_multisample WGL_ARB_pixel_format +WGL_ARB_pbuffer WGL_ARB_create_context WGL_ARB_create_context_profile \ No newline at end of file