Added support for pbuffers on Windows and Unix.

This commit is contained in:
binary1248 2015-04-20 14:16:30 +02:00 committed by Lukas Dürrenberger
parent 2d1fab374f
commit 811dfe1cf7
10 changed files with 647 additions and 171 deletions

View File

@ -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<uint8_t>(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<uint8_t>(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<unsigned int>(depth);
m_settings.stencilBits = static_cast<unsigned int>(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<int>(width),
GLX_PBUFFER_HEIGHT, static_cast<int>(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<uint8_t>(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<int>(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<unsigned int>(depth);
m_settings.stencilBits = static_cast<unsigned int>(stencil);
m_settings.antialiasingLevel = multiSampling ? samples : 0;
}
// Free the visual info
XFree(visualInfo);

View File

@ -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?
};

View File

@ -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<GLXPbufferSGIX (CODEGEN_FUNCPTR*)(Display*, GLXFBConfigSGIX, unsigned int, unsigned int, int*)>(IntGetProcAddress("glXCreateGLXPbufferSGIX"));
if (!sf_ptrc_glXCreateGLXPbufferSGIX)
numFailed++;
sf_ptrc_glXDestroyGLXPbufferSGIX = reinterpret_cast<void (CODEGEN_FUNCPTR*)(Display*, GLXPbufferSGIX)>(IntGetProcAddress("glXDestroyGLXPbufferSGIX"));
if (!sf_ptrc_glXDestroyGLXPbufferSGIX)
numFailed++;
sf_ptrc_glXGetSelectedEventSGIX = reinterpret_cast<void (CODEGEN_FUNCPTR*)(Display*, GLXDrawable, unsigned long*)>(IntGetProcAddress("glXGetSelectedEventSGIX"));
if (!sf_ptrc_glXGetSelectedEventSGIX)
numFailed++;
sf_ptrc_glXQueryGLXPbufferSGIX = reinterpret_cast<int (CODEGEN_FUNCPTR*)(Display*, GLXPbufferSGIX, int, unsigned int*)>(IntGetProcAddress("glXQueryGLXPbufferSGIX"));
if (!sf_ptrc_glXQueryGLXPbufferSGIX)
numFailed++;
sf_ptrc_glXSelectEventSGIX = reinterpret_cast<void (CODEGEN_FUNCPTR*)(Display*, GLXDrawable, unsigned long)>(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;
}

View File

@ -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*);

View File

@ -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
GLX_ARB_create_context_profile

View File

@ -26,8 +26,8 @@
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/WindowImpl.hpp> // included first to avoid a warning about macro redefinition
#include <SFML/OpenGL.hpp> // included second to avoid an error in WglExtensions.hpp
#include <SFML/Window/Win32/WglContext.hpp>
#include <SFML/Window/Win32/WglExtensions.hpp>
#include <SFML/System/Lock.hpp>
#include <SFML/System/Mutex.hpp>
#include <SFML/System/Err.hpp>
@ -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;

View File

@ -29,8 +29,7 @@
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/GlContext.hpp>
#include <SFML/OpenGL.hpp>
#include <windows.h>
#include <SFML/Window/Win32/WglExtensions.hpp>
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

View File

@ -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<HPBUFFERARB (CODEGEN_FUNCPTR*)(HDC, int, int, int, const int*)>(IntGetProcAddress("wglCreatePbufferARB"));
if (!sf_ptrc_wglCreatePbufferARB)
numFailed++;
sf_ptrc_wglDestroyPbufferARB = reinterpret_cast<BOOL (CODEGEN_FUNCPTR*)(HPBUFFERARB)>(IntGetProcAddress("wglDestroyPbufferARB"));
if (!sf_ptrc_wglDestroyPbufferARB)
numFailed++;
sf_ptrc_wglGetPbufferDCARB = reinterpret_cast<HDC (CODEGEN_FUNCPTR*)(HPBUFFERARB)>(IntGetProcAddress("wglGetPbufferDCARB"));
if (!sf_ptrc_wglGetPbufferDCARB)
numFailed++;
sf_ptrc_wglQueryPbufferARB = reinterpret_cast<BOOL (CODEGEN_FUNCPTR*)(HPBUFFERARB, int, int*)>(IntGetProcAddress("wglQueryPbufferARB"));
if (!sf_ptrc_wglQueryPbufferARB)
numFailed++;
sf_ptrc_wglReleasePbufferDCARB = reinterpret_cast<int (CODEGEN_FUNCPTR*)(HPBUFFERARB, HDC)>(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;
}

View File

@ -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*);

View File

@ -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