mirror of
https://github.com/SFML/SFML.git
synced 2025-02-19 06:39:59 +08:00
Fixed ContextSettings ignored on Linux when creating a window (#35)
This commit is contained in:
parent
6b50691551
commit
68748d2de1
@ -158,12 +158,69 @@ void GlxContext::setVerticalSyncEnabled(bool enabled)
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void GlxContext::createContext(GlxContext* shared, unsigned int bitsPerPixel, const ContextSettings& settings)
|
XVisualInfo GlxContext::selectBestVisual(::Display* display, unsigned int bitsPerPixel, const ContextSettings& settings)
|
||||||
|
{
|
||||||
|
// Retrieve all the visuals
|
||||||
|
int count;
|
||||||
|
XVisualInfo* visuals = XGetVisualInfo(display, 0, NULL, &count);
|
||||||
|
if (visuals)
|
||||||
|
{
|
||||||
|
// Evaluate all the returned visuals, and pick the best one1
|
||||||
|
int bestScore = 0xFFFF;
|
||||||
|
XVisualInfo bestVisual;
|
||||||
|
for (int i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
// Check mandatory attributes
|
||||||
|
int doubleBuffer;
|
||||||
|
glXGetConfig(display, &visuals[i], GLX_DOUBLEBUFFER, &doubleBuffer);
|
||||||
|
if (!doubleBuffer)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Extract the components of the current visual
|
||||||
|
int red, green, blue, alpha, depth, stencil, multiSampling, samples;
|
||||||
|
glXGetConfig(display, &visuals[i], GLX_RED_SIZE, &red);
|
||||||
|
glXGetConfig(display, &visuals[i], GLX_GREEN_SIZE, &green);
|
||||||
|
glXGetConfig(display, &visuals[i], GLX_BLUE_SIZE, &blue);
|
||||||
|
glXGetConfig(display, &visuals[i], GLX_ALPHA_SIZE, &alpha);
|
||||||
|
glXGetConfig(display, &visuals[i], GLX_DEPTH_SIZE, &depth);
|
||||||
|
glXGetConfig(display, &visuals[i], GLX_STENCIL_SIZE, &stencil);
|
||||||
|
glXGetConfig(display, &visuals[i], GLX_SAMPLE_BUFFERS_ARB, &multiSampling);
|
||||||
|
glXGetConfig(display, &visuals[i], GLX_SAMPLES_ARB, &samples);
|
||||||
|
|
||||||
|
// Evaluate the visual
|
||||||
|
int color = red + green + blue + alpha;
|
||||||
|
int score = evaluateFormat(bitsPerPixel, settings, color, depth, stencil, multiSampling ? samples : 0);
|
||||||
|
|
||||||
|
// If it's better than the current best, make it the new best
|
||||||
|
if (score < bestScore)
|
||||||
|
{
|
||||||
|
bestScore = score;
|
||||||
|
bestVisual = visuals[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free the array of visuals
|
||||||
|
XFree(visuals);
|
||||||
|
|
||||||
|
return bestVisual;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Should never happen...
|
||||||
|
err() << "No GLX visual found. You should check your graphics driver" << std::endl;
|
||||||
|
|
||||||
|
return XVisualInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void GlxContext::createContext(GlxContext* shared, unsigned int /*bitsPerPixel*/, const ContextSettings& settings)
|
||||||
{
|
{
|
||||||
// Save the creation settings
|
// Save the creation settings
|
||||||
m_settings = settings;
|
m_settings = settings;
|
||||||
|
|
||||||
// Get the attributes of the target window
|
// Retrieve the attributes of the target window
|
||||||
XWindowAttributes windowAttributes;
|
XWindowAttributes windowAttributes;
|
||||||
if (XGetWindowAttributes(m_display, m_window, &windowAttributes) == 0)
|
if (XGetWindowAttributes(m_display, m_window, &windowAttributes) == 0)
|
||||||
{
|
{
|
||||||
@ -171,63 +228,12 @@ void GlxContext::createContext(GlxContext* shared, unsigned int bitsPerPixel, co
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup the visual infos to match
|
// Get its visual
|
||||||
XVisualInfo tpl;
|
XVisualInfo tpl;
|
||||||
tpl.depth = windowAttributes.depth;
|
|
||||||
tpl.visualid = XVisualIDFromVisual(windowAttributes.visual);
|
|
||||||
tpl.screen = DefaultScreen(m_display);
|
tpl.screen = DefaultScreen(m_display);
|
||||||
|
tpl.visualid = XVisualIDFromVisual(windowAttributes.visual);
|
||||||
// Get all the visuals matching the template
|
|
||||||
int nbVisuals = 0;
|
int nbVisuals = 0;
|
||||||
XVisualInfo* visuals = XGetVisualInfo(m_display, VisualDepthMask | VisualIDMask | VisualScreenMask, &tpl, &nbVisuals);
|
XVisualInfo* visualInfo = XGetVisualInfo(m_display, VisualIDMask | VisualScreenMask, &tpl, &nbVisuals);
|
||||||
if (!visuals || (nbVisuals == 0))
|
|
||||||
{
|
|
||||||
if (visuals)
|
|
||||||
XFree(visuals);
|
|
||||||
err() << "There is no valid visual for the selected screen" << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the best visual
|
|
||||||
int bestScore = 0xFFFF;
|
|
||||||
XVisualInfo* bestVisual = NULL;
|
|
||||||
for (int i = 0; i < nbVisuals; ++i)
|
|
||||||
{
|
|
||||||
// Get the current visual attributes
|
|
||||||
int RGBA, doubleBuffer, red, green, blue, alpha, depth, stencil, multiSampling, samples;
|
|
||||||
glXGetConfig(m_display, &visuals[i], GLX_RGBA, &RGBA);
|
|
||||||
glXGetConfig(m_display, &visuals[i], GLX_DOUBLEBUFFER, &doubleBuffer);
|
|
||||||
glXGetConfig(m_display, &visuals[i], GLX_RED_SIZE, &red);
|
|
||||||
glXGetConfig(m_display, &visuals[i], GLX_GREEN_SIZE, &green);
|
|
||||||
glXGetConfig(m_display, &visuals[i], GLX_BLUE_SIZE, &blue);
|
|
||||||
glXGetConfig(m_display, &visuals[i], GLX_ALPHA_SIZE, &alpha);
|
|
||||||
glXGetConfig(m_display, &visuals[i], GLX_DEPTH_SIZE, &depth);
|
|
||||||
glXGetConfig(m_display, &visuals[i], GLX_STENCIL_SIZE, &stencil);
|
|
||||||
glXGetConfig(m_display, &visuals[i], GLX_SAMPLE_BUFFERS_ARB, &multiSampling);
|
|
||||||
glXGetConfig(m_display, &visuals[i], GLX_SAMPLES_ARB, &samples);
|
|
||||||
|
|
||||||
// First check the mandatory parameters
|
|
||||||
if ((RGBA == 0) || (doubleBuffer == 0))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Evaluate the current configuration
|
|
||||||
int color = red + green + blue + alpha;
|
|
||||||
int score = evaluateFormat(bitsPerPixel, m_settings, color, depth, stencil, multiSampling ? samples : 0);
|
|
||||||
|
|
||||||
// Keep it if it's better than the current best
|
|
||||||
if (score < bestScore)
|
|
||||||
{
|
|
||||||
bestScore = score;
|
|
||||||
bestVisual = &visuals[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure that we have found a visual
|
|
||||||
if (!bestVisual)
|
|
||||||
{
|
|
||||||
err() << "Failed to find a suitable pixel format for the window -- cannot create OpenGL context" << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the context to share display lists with
|
// Get the context to share display lists with
|
||||||
GLXContext toShare = shared ? shared->m_context : NULL;
|
GLXContext toShare = shared ? shared->m_context : NULL;
|
||||||
@ -283,7 +289,7 @@ void GlxContext::createContext(GlxContext* shared, unsigned int bitsPerPixel, co
|
|||||||
m_settings.majorVersion = 2;
|
m_settings.majorVersion = 2;
|
||||||
m_settings.minorVersion = 0;
|
m_settings.minorVersion = 0;
|
||||||
|
|
||||||
m_context = glXCreateContext(m_display, bestVisual, toShare, true);
|
m_context = glXCreateContext(m_display, visualInfo, toShare, true);
|
||||||
if (!m_context)
|
if (!m_context)
|
||||||
{
|
{
|
||||||
err() << "Failed to create an OpenGL context for this window" << std::endl;
|
err() << "Failed to create an OpenGL context for this window" << std::endl;
|
||||||
@ -293,21 +299,16 @@ void GlxContext::createContext(GlxContext* shared, unsigned int bitsPerPixel, co
|
|||||||
|
|
||||||
// Update the creation settings from the chosen format
|
// Update the creation settings from the chosen format
|
||||||
int depth, stencil, multiSampling, samples;
|
int depth, stencil, multiSampling, samples;
|
||||||
glXGetConfig(m_display, bestVisual, GLX_DEPTH_SIZE, &depth);
|
glXGetConfig(m_display, visualInfo, GLX_DEPTH_SIZE, &depth);
|
||||||
glXGetConfig(m_display, bestVisual, GLX_STENCIL_SIZE, &stencil);
|
glXGetConfig(m_display, visualInfo, GLX_STENCIL_SIZE, &stencil);
|
||||||
glXGetConfig(m_display, bestVisual, GLX_SAMPLE_BUFFERS_ARB, &multiSampling);
|
glXGetConfig(m_display, visualInfo, GLX_SAMPLE_BUFFERS_ARB, &multiSampling);
|
||||||
glXGetConfig(m_display, bestVisual, GLX_SAMPLES_ARB, &samples);
|
glXGetConfig(m_display, visualInfo, GLX_SAMPLES_ARB, &samples);
|
||||||
m_settings.depthBits = static_cast<unsigned int>(depth);
|
m_settings.depthBits = static_cast<unsigned int>(depth);
|
||||||
m_settings.stencilBits = static_cast<unsigned int>(stencil);
|
m_settings.stencilBits = static_cast<unsigned int>(stencil);
|
||||||
m_settings.antialiasingLevel = multiSampling ? samples : 0;
|
m_settings.antialiasingLevel = multiSampling ? samples : 0;
|
||||||
|
|
||||||
// Change the target window's colormap so that it matches the context's one
|
// Free the visual info
|
||||||
::Window root = RootWindow(m_display, DefaultScreen(m_display));
|
XFree(visualInfo);
|
||||||
Colormap colorMap = XCreateColormap(m_display, root, bestVisual->visual, AllocNone);
|
|
||||||
XSetWindowColormap(m_display, m_window, colorMap);
|
|
||||||
|
|
||||||
// Free the temporary visuals array
|
|
||||||
XFree(visuals);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace priv
|
} // namespace priv
|
||||||
|
@ -108,6 +108,18 @@ public :
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
virtual void setVerticalSyncEnabled(bool enabled);
|
virtual void setVerticalSyncEnabled(bool enabled);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Select the best GLX visual for a given set of settings
|
||||||
|
///
|
||||||
|
/// \param display X display
|
||||||
|
/// \param bitsPerPixel Pixel depth, in bits per pixel
|
||||||
|
/// \param settings Requested context settings
|
||||||
|
///
|
||||||
|
/// \return The best visual
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
static XVisualInfo selectBestVisual(::Display* display, unsigned int bitsPerPixel, const ContextSettings& settings);
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/Window/WindowStyle.hpp> // important to be included first (conflict with None)
|
#include <SFML/Window/WindowStyle.hpp> // important to be included first (conflict with None)
|
||||||
#include <SFML/Window/Linux/WindowImplX11.hpp>
|
#include <SFML/Window/Linux/WindowImplX11.hpp>
|
||||||
|
#include <SFML/Window/Linux/GlxContext.hpp>
|
||||||
#include <SFML/Window/Linux/Display.hpp>
|
#include <SFML/Window/Linux/Display.hpp>
|
||||||
#include <SFML/System/Utf.hpp>
|
#include <SFML/System/Utf.hpp>
|
||||||
#include <SFML/System/Err.hpp>
|
#include <SFML/System/Err.hpp>
|
||||||
@ -96,7 +97,7 @@ m_previousSize(-1, -1)
|
|||||||
{
|
{
|
||||||
// Open a connection with the X server
|
// Open a connection with the X server
|
||||||
m_display = OpenDisplay();
|
m_display = OpenDisplay();
|
||||||
m_screen = DefaultScreen(m_display);
|
m_screen = DefaultScreen(m_display);
|
||||||
|
|
||||||
// Save the window handle
|
// Save the window handle
|
||||||
m_window = handle;
|
m_window = handle;
|
||||||
@ -113,7 +114,7 @@ m_previousSize(-1, -1)
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
WindowImplX11::WindowImplX11(VideoMode mode, const String& title, unsigned long style) :
|
WindowImplX11::WindowImplX11(VideoMode mode, const String& title, unsigned long style, const ContextSettings& settings) :
|
||||||
m_window (0),
|
m_window (0),
|
||||||
m_inputMethod (NULL),
|
m_inputMethod (NULL),
|
||||||
m_inputContext(NULL),
|
m_inputContext(NULL),
|
||||||
@ -126,7 +127,8 @@ m_previousSize(-1, -1)
|
|||||||
{
|
{
|
||||||
// Open a connection with the X server
|
// Open a connection with the X server
|
||||||
m_display = OpenDisplay();
|
m_display = OpenDisplay();
|
||||||
m_screen = DefaultScreen(m_display);
|
m_screen = DefaultScreen(m_display);
|
||||||
|
::Window root = RootWindow(m_display, m_screen);
|
||||||
|
|
||||||
// Compute position and size
|
// Compute position and size
|
||||||
int left, top;
|
int left, top;
|
||||||
@ -148,21 +150,25 @@ m_previousSize(-1, -1)
|
|||||||
if (fullscreen)
|
if (fullscreen)
|
||||||
switchToFullscreen(mode);
|
switchToFullscreen(mode);
|
||||||
|
|
||||||
|
// Choose the visual according to the context settings
|
||||||
|
XVisualInfo visualInfo = GlxContext::selectBestVisual(m_display, mode.bitsPerPixel, settings);
|
||||||
|
|
||||||
// Define the window attributes
|
// Define the window attributes
|
||||||
XSetWindowAttributes attributes;
|
XSetWindowAttributes attributes;
|
||||||
attributes.event_mask = eventMask;
|
|
||||||
attributes.override_redirect = fullscreen;
|
attributes.override_redirect = fullscreen;
|
||||||
|
attributes.event_mask = eventMask;
|
||||||
|
attributes.colormap = XCreateColormap(m_display, root, visualInfo.visual, AllocNone);
|
||||||
|
|
||||||
// Create the window
|
// Create the window
|
||||||
m_window = XCreateWindow(m_display,
|
m_window = XCreateWindow(m_display,
|
||||||
RootWindow(m_display, m_screen),
|
root,
|
||||||
left, top,
|
left, top,
|
||||||
width, height,
|
width, height,
|
||||||
0,
|
0,
|
||||||
DefaultDepth(m_display, m_screen),
|
visualInfo.depth,
|
||||||
InputOutput,
|
InputOutput,
|
||||||
DefaultVisual(m_display, m_screen),
|
visualInfo.visual,
|
||||||
CWEventMask | CWOverrideRedirect, &attributes);
|
CWEventMask | CWOverrideRedirect | CWColormap, &attributes);
|
||||||
if (!m_window)
|
if (!m_window)
|
||||||
{
|
{
|
||||||
err() << "Failed to create window" << std::endl;
|
err() << "Failed to create window" << std::endl;
|
||||||
|
@ -61,9 +61,10 @@ public :
|
|||||||
/// \param mode Video mode to use
|
/// \param mode Video mode to use
|
||||||
/// \param title Title of the window
|
/// \param title Title of the window
|
||||||
/// \param style Window style (resizable, fixed, or fullscren)
|
/// \param style Window style (resizable, fixed, or fullscren)
|
||||||
|
/// \param settings Additional settings for the underlying OpenGL context
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
WindowImplX11(VideoMode mode, const String& title, unsigned long style);
|
WindowImplX11(VideoMode mode, const String& title, unsigned long style, const ContextSettings& settings);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Destructor
|
/// \brief Destructor
|
||||||
|
@ -78,9 +78,10 @@ public :
|
|||||||
/// \param mode Video mode to use
|
/// \param mode Video mode to use
|
||||||
/// \param title Title of the window
|
/// \param title Title of the window
|
||||||
/// \param style Window style (resizable, fixed, or fullscren)
|
/// \param style Window style (resizable, fixed, or fullscren)
|
||||||
|
/// \param settings Additional settings for the underlying OpenGL context
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
WindowImplCocoa(VideoMode mode, const String& title, unsigned long style);
|
WindowImplCocoa(VideoMode mode, const String& title, unsigned long style, const ContextSettings& settings);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Destructor
|
/// \brief Destructor
|
||||||
|
@ -81,9 +81,10 @@ WindowImplCocoa::WindowImplCocoa(WindowHandle handle)
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
WindowImplCocoa::WindowImplCocoa(VideoMode mode,
|
WindowImplCocoa::WindowImplCocoa(VideoMode mode,
|
||||||
const String& title,
|
const String& title,
|
||||||
unsigned long style)
|
unsigned long style,
|
||||||
|
const ContextSettings& /*settings*/)
|
||||||
: m_showCursor(true)
|
: m_showCursor(true)
|
||||||
{
|
{
|
||||||
// Transform the app process.
|
// Transform the app process.
|
||||||
|
@ -86,7 +86,7 @@ m_surrogate (0)
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
WindowImplWin32::WindowImplWin32(VideoMode mode, const String& title, Uint32 style) :
|
WindowImplWin32::WindowImplWin32(VideoMode mode, const String& title, Uint32 style, const ContextSettings& /*settings*/) :
|
||||||
m_handle (NULL),
|
m_handle (NULL),
|
||||||
m_callback (0),
|
m_callback (0),
|
||||||
m_cursor (NULL),
|
m_cursor (NULL),
|
||||||
|
@ -60,9 +60,10 @@ public :
|
|||||||
/// \param mode Video mode to use
|
/// \param mode Video mode to use
|
||||||
/// \param title Title of the window
|
/// \param title Title of the window
|
||||||
/// \param style Window style
|
/// \param style Window style
|
||||||
|
/// \param settings Additional settings for the underlying OpenGL context
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
WindowImplWin32(VideoMode mode, const String& title, Uint32 style);
|
WindowImplWin32(VideoMode mode, const String& title, Uint32 style, const ContextSettings& settings);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Destructor
|
/// \brief Destructor
|
||||||
|
@ -114,7 +114,7 @@ void Window::create(VideoMode mode, const String& title, Uint32 style, const Con
|
|||||||
style |= Style::Titlebar;
|
style |= Style::Titlebar;
|
||||||
|
|
||||||
// Recreate the window implementation
|
// Recreate the window implementation
|
||||||
m_impl = priv::WindowImpl::create(mode, title, style);
|
m_impl = priv::WindowImpl::create(mode, title, style, settings);
|
||||||
|
|
||||||
// Recreate the context
|
// Recreate the context
|
||||||
m_context = priv::GlContext::create(settings, m_impl, mode.bitsPerPixel);
|
m_context = priv::GlContext::create(settings, m_impl, mode.bitsPerPixel);
|
||||||
|
@ -55,9 +55,9 @@ namespace sf
|
|||||||
namespace priv
|
namespace priv
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
WindowImpl* WindowImpl::create(VideoMode mode, const String& title, Uint32 style)
|
WindowImpl* WindowImpl::create(VideoMode mode, const String& title, Uint32 style, const ContextSettings& settings)
|
||||||
{
|
{
|
||||||
return new WindowImplType(mode, title, style);
|
return new WindowImplType(mode, title, style, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include <SFML/Window/JoystickImpl.hpp>
|
#include <SFML/Window/JoystickImpl.hpp>
|
||||||
#include <SFML/Window/VideoMode.hpp>
|
#include <SFML/Window/VideoMode.hpp>
|
||||||
#include <SFML/Window/WindowHandle.hpp>
|
#include <SFML/Window/WindowHandle.hpp>
|
||||||
|
#include <SFML/Window/ContextSettings.hpp>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
@ -59,11 +60,12 @@ public :
|
|||||||
/// \param mode Video mode to use
|
/// \param mode Video mode to use
|
||||||
/// \param title Title of the window
|
/// \param title Title of the window
|
||||||
/// \param style Window style
|
/// \param style Window style
|
||||||
|
/// \param settings Additional settings for the underlying OpenGL context
|
||||||
///
|
///
|
||||||
/// \return Pointer to the created window (don't forget to delete it)
|
/// \return Pointer to the created window (don't forget to delete it)
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
static WindowImpl* create(VideoMode mode, const String& title, Uint32 style);
|
static WindowImpl* create(VideoMode mode, const String& title, Uint32 style, const ContextSettings& settings);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Create a new window depending on to the current OS
|
/// \brief Create a new window depending on to the current OS
|
||||||
|
Loading…
x
Reference in New Issue
Block a user