Completed implementation of OpenGL context on Linux

git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1069 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
laurentgom 2009-03-28 20:39:38 +00:00
parent b194b9969a
commit 392eb219f2
6 changed files with 94 additions and 97 deletions

View File

@ -15,16 +15,16 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
int main() int main()
{ {
// Create main window
sf::RenderWindow App(sf::VideoMode(800, 600), "SFML OpenGL");
App.PreserveOpenGLStates(true);
// Create a sprite for the background // Create a sprite for the background
sf::Image BackgroundImage; sf::Image BackgroundImage;
if (!BackgroundImage.LoadFromFile("datas/opengl/background.jpg")) if (!BackgroundImage.LoadFromFile("datas/opengl/background.jpg"))
return EXIT_FAILURE; return EXIT_FAILURE;
sf::Sprite Background(BackgroundImage); sf::Sprite Background(BackgroundImage);
// Create main window
sf::RenderWindow App(sf::VideoMode(800, 600), "SFML OpenGL");
App.PreserveOpenGLStates(true);
// Load an OpenGL texture. // Load an OpenGL texture.
// We could directly use a sf::Image as an OpenGL texture (with its Bind() member function), // We could directly use a sf::Image as an OpenGL texture (with its Bind() member function),
// but here we want more control on it (generate mipmaps, ...) so we create a new one from the image pixels // but here we want more control on it (generate mipmaps, ...) so we create a new one from the image pixels

View File

@ -41,41 +41,34 @@ namespace priv
/// Create a new context, not associated to a window /// Create a new context, not associated to a window
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
ContextGLX::ContextGLX(ContextGLX* Shared) : ContextGLX::ContextGLX(ContextGLX* Shared) :
myWindow (NULL), myWindow (0),
myContext (NULL)/*, myContext (NULL),
myOwnsWindow(true)*/ myOwnsWindow(true)
{ {
// Create the rendering context
XVisualInfo Visual;
CreateContext(Shared, VideoMode::GetDesktopMode().BitsPerPixel, ContextSettings(0, 0, 0));
// Create a new color map with the chosen visual
/*Colormap ColMap = XCreateColormap(ourDisplay, RootWindow(ourDisplay, ourScreen), Visual.visual, AllocNone);
// Define the window attributes
XSetWindowAttributes Attributes;
Attributes.colormap = ColMap;
// Create a dummy window (disabled and hidden) // Create a dummy window (disabled and hidden)
myWindow = XCreateWindow(ourDisplay, int Screen = DefaultScreen(myDisplay.GetDisplay());
RootWindow(ourDisplay, ourScreen), myWindow = XCreateWindow(myDisplay.GetDisplay(),
RootWindow(myDisplay.GetDisplay(), Screen),
0, 0, 0, 0,
myWidth, myHeight, 1, 1,
0, 0,
Visual.depth, DefaultDepth(myDisplay.GetDisplay(), Screen),
InputOutput, InputOutput,
Visual.visual, DefaultVisual(myDisplay.GetDisplay(), Screen),
CWColormap, &Attributes);*/ 0, NULL);
// Create the context
CreateContext(Shared, VideoMode::GetDesktopMode().BitsPerPixel, ContextSettings(0, 0, 0));
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Create a new context attached to a window /// Create a new context attached to a window
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
ContextGLX::ContextGLX(ContextWGL* Shared, const WindowImpl* Owner, unsigned int BitsPerPixel, const ContextSettings& Settings) : ContextGLX::ContextGLX(ContextGLX* Shared, const WindowImpl* Owner, unsigned int BitsPerPixel, const ContextSettings& Settings) :
myWindow (NULL), myWindow (0),
myContext (NULL),/* myContext (NULL),
myOwnsWindow(false)*/ myOwnsWindow(false)
{ {
// Get the owner window and its device context // Get the owner window and its device context
myWindow = static_cast<Window>(Owner->GetHandle()); myWindow = static_cast<Window>(Owner->GetHandle());
@ -91,20 +84,20 @@ myOwnsWindow(false)*/
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
ContextGLX::~ContextGLX() ContextGLX::~ContextGLX()
{ {
// Destroy the OpenGL context // Destroy the context
if (myContext) if (myContext)
{ {
if (glXGetCurrentContext() == myContext) if (glXGetCurrentContext() == myContext)
glXMakeCurrent(myDisplay.GetDisplay(), None, NULL); glXMakeCurrent(myDisplay.GetDisplay(), None, NULL);
glXDestroyContext(myContext); glXDestroyContext(myDisplay.GetDisplay(), myContext);
} }
// Destroy the window if we own it // Destroy the window if we own it
/*if (myWindow && myOwnsWindow) if (myWindow && myOwnsWindow)
{ {
XDestroyWindow(myDisplay.GetDisplay(), myWindow); XDestroyWindow(myDisplay.GetDisplay(), myWindow);
XFlush(myDisplay.GetDisplay()); XFlush(myDisplay.GetDisplay());
}*/ }
} }
@ -115,7 +108,7 @@ bool ContextGLX::MakeCurrent(bool Active)
{ {
if (Active) if (Active)
{ {
if (myWindow && myContext) if (myContext)
{ {
if (glXGetCurrentContext() != myContext) if (glXGetCurrentContext() != myContext)
return glXMakeCurrent(myDisplay.GetDisplay(), myWindow, myContext) != 0; return glXMakeCurrent(myDisplay.GetDisplay(), myWindow, myContext) != 0;
@ -130,7 +123,7 @@ bool ContextGLX::MakeCurrent(bool Active)
else else
{ {
if (glXGetCurrentContext() == myContext) if (glXGetCurrentContext() == myContext)
return wglMakeCurrent(myDisplay.GetDisplay(), None, NULL) != 0; return glXMakeCurrent(myDisplay.GetDisplay(), None, NULL) != 0;
else else
return true; return true;
} }
@ -173,22 +166,22 @@ bool ContextGLX::IsContextActive()
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void ContextGLX::CreateContext(ContextGLX* Shared, unsigned int BitsPerPixel, const ContextSettings& Settings) void ContextGLX::CreateContext(ContextGLX* Shared, unsigned int BitsPerPixel, const ContextSettings& Settings)
{ {
XVisualInfo Template; // Save the creation settings
Template.screen = DefaultScreen(myDisplayRef.GetDisplay()); mySettings = Settings;
if (myWindow)
{
// Get the attributes of the target window // Get the attributes of the target window
XWindowAttributes WindowAttributes; XWindowAttributes WindowAttributes;
if (XGetWindowAttributes(myDisplayRef.GetDisplay(), myWindow, &WindowAttributes) == 0) if (XGetWindowAttributes(myDisplay.GetDisplay(), myWindow, &WindowAttributes) == 0)
{ {
std::cerr << "Failed to get the window attributes" << std::endl; std::cerr << "Failed to get the window attributes" << std::endl;
return; return;
} }
// Setup the visual infos to match // Setup the visual infos to match
XVisualInfo Template;
Template.depth = WindowAttributes.depth; Template.depth = WindowAttributes.depth;
Template.visualid = XVisualIDFromVisual(WindowAttributes.visual); Template.visualid = XVisualIDFromVisual(WindowAttributes.visual);
} Template.screen = DefaultScreen(myDisplay.GetDisplay());
// Get all the visuals matching the template // Get all the visuals matching the template
int NbVisuals = 0; int NbVisuals = 0;
@ -210,16 +203,16 @@ void ContextGLX::CreateContext(ContextGLX* Shared, unsigned int BitsPerPixel, co
{ {
// Get the current visual attributes // Get the current visual attributes
int RGBA, DoubleBuffer, Red, Green, Blue, Alpha, Depth, Stencil, MultiSampling, Samples; int RGBA, DoubleBuffer, Red, Green, Blue, Alpha, Depth, Stencil, MultiSampling, Samples;
glXGetConfig(ourDisplay, &Visuals[i], GLX_RGBA, &RGBA); glXGetConfig(myDisplay.GetDisplay(), &Visuals[i], GLX_RGBA, &RGBA);
glXGetConfig(ourDisplay, &Visuals[i], GLX_DOUBLEBUFFER, &DoubleBuffer); glXGetConfig(myDisplay.GetDisplay(), &Visuals[i], GLX_DOUBLEBUFFER, &DoubleBuffer);
glXGetConfig(ourDisplay, &Visuals[i], GLX_RED_SIZE, &Red); glXGetConfig(myDisplay.GetDisplay(), &Visuals[i], GLX_RED_SIZE, &Red);
glXGetConfig(ourDisplay, &Visuals[i], GLX_GREEN_SIZE, &Green); glXGetConfig(myDisplay.GetDisplay(), &Visuals[i], GLX_GREEN_SIZE, &Green);
glXGetConfig(ourDisplay, &Visuals[i], GLX_BLUE_SIZE, &Blue); glXGetConfig(myDisplay.GetDisplay(), &Visuals[i], GLX_BLUE_SIZE, &Blue);
glXGetConfig(ourDisplay, &Visuals[i], GLX_ALPHA_SIZE, &Alpha); glXGetConfig(myDisplay.GetDisplay(), &Visuals[i], GLX_ALPHA_SIZE, &Alpha);
glXGetConfig(ourDisplay, &Visuals[i], GLX_DEPTH_SIZE, &Depth); glXGetConfig(myDisplay.GetDisplay(), &Visuals[i], GLX_DEPTH_SIZE, &Depth);
glXGetConfig(ourDisplay, &Visuals[i], GLX_STENCIL_SIZE, &Stencil); glXGetConfig(myDisplay.GetDisplay(), &Visuals[i], GLX_STENCIL_SIZE, &Stencil);
glXGetConfig(ourDisplay, &Visuals[i], GLX_SAMPLE_BUFFERS_ARB, &MultiSampling); glXGetConfig(myDisplay.GetDisplay(), &Visuals[i], GLX_SAMPLE_BUFFERS_ARB, &MultiSampling);
glXGetConfig(ourDisplay, &Visuals[i], GLX_SAMPLES_ARB, &Samples); glXGetConfig(myDisplay.GetDisplay(), &Visuals[i], GLX_SAMPLES_ARB, &Samples);
// First check the mandatory parameters // First check the mandatory parameters
if ((RGBA == 0) || (DoubleBuffer == 0)) if ((RGBA == 0) || (DoubleBuffer == 0))
@ -240,16 +233,16 @@ void ContextGLX::CreateContext(ContextGLX* Shared, unsigned int BitsPerPixel, co
// If no visual has been found, try a lower level of antialiasing // If no visual has been found, try a lower level of antialiasing
if (!BestVisual) if (!BestVisual)
{ {
if (Params.AntialiasingLevel > 2) if (mySettings.AntialiasingLevel > 2)
{ {
std::cerr << "Failed to find a pixel format supporting " std::cerr << "Failed to find a pixel format supporting "
<< Params.AntialiasingLevel << " antialiasing levels ; trying with 2 levels" << std::endl; << mySettings.AntialiasingLevel << " antialiasing levels ; trying with 2 levels" << std::endl;
Params.AntialiasingLevel = 2; mySettings.AntialiasingLevel = 2;
} }
else if (Params.AntialiasingLevel > 0) else if (mySettings.AntialiasingLevel > 0)
{ {
std::cerr << "Failed to find a pixel format supporting antialiasing ; antialiasing will be disabled" << std::endl; std::cerr << "Failed to find a pixel format supporting antialiasing ; antialiasing will be disabled" << std::endl;
Params.AntialiasingLevel = 0; mySettings.AntialiasingLevel = 0;
} }
else else
{ {
@ -278,12 +271,9 @@ void ContextGLX::CreateContext(ContextGLX* Shared, unsigned int BitsPerPixel, co
mySettings.StencilBits = static_cast<unsigned int>(Stencil); mySettings.StencilBits = static_cast<unsigned int>(Stencil);
// Change the target window's colormap so that it matches the context's one // Change the target window's colormap so that it matches the context's one
if (myWindow) ::Window Root = RootWindow(myDisplay.GetDisplay(), DefaultScreen(myDisplay.GetDisplay()));
{
::Window Root = RootWindow(myDisplay.GetDisplay(), DefaultScreen(myDisplay.GetDisplay()))
Colormap ColMap = XCreateColormap(myDisplay.GetDisplay(), Root, BestVisual->visual, AllocNone); Colormap ColMap = XCreateColormap(myDisplay.GetDisplay(), Root, BestVisual->visual, AllocNone);
XSetWindowColormap(myDisplay.GetDisplay(), myWindow, ColMap); XSetWindowColormap(myDisplay.GetDisplay(), myWindow, ColMap);
}
// Free the temporary visuals array // Free the temporary visuals array
XFree(Visuals); XFree(Visuals);

View File

@ -108,27 +108,13 @@ private :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void CreateContext(ContextGLX* Shared, unsigned int BitsPerPixel, const ContextSettings& Settings); void CreateContext(ContextGLX* Shared, unsigned int BitsPerPixel, const ContextSettings& Settings);
////////////////////////////////////////////////////////////
/// Create the OpenGL rendering context
///
/// \param Mode : Video mode to use
/// \param ChosenVisual : Visual that has been chosen for creating the contexte
/// \param Params : Creation parameters
/// \param Template : Visual infos to match
/// \param Mask : Visual attributes to check in Template
///
/// \return True on success, false on error
///
////////////////////////////////////////////////////////////
//bool CreateContext(XVisualInfo& ChosenVisual, WindowSettings& Params, XVisualInfo Template = XVisualInfo(), unsigned long Mask = 0);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Member data // Member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
DisplayRef myDisplay; ///< Connection to the X server DisplayRef myDisplay; ///< Connection to the X server
::Window myWindow; ///< Window to which the context is attached ::Window myWindow; ///< Window to which the context is attached
GLXContext myContext; ///< OpenGL context GLXContext myContext; ///< OpenGL context
//bool myOwnsWindow; ///< Did we create the host window? bool myOwnsWindow; ///< Do we own the window associated to the context?
}; };
} // namespace priv } // namespace priv

View File

@ -47,13 +47,14 @@ void VideoModeSupport::GetSupportedVideoModes(std::vector<VideoMode>& Modes)
// Get an access to the display // Get an access to the display
DisplayRef Disp; DisplayRef Disp;
int Screen = DefaultScreen(Disp.GetDisplay());
// Check if the XRandR extension is present // Check if the XRandR extension is present
int Version; int Version;
if (XQueryExtension(Disp.GetDisplay(), "RANDR", &Version, &Version, &Version)) if (XQueryExtension(Disp.GetDisplay(), "RANDR", &Version, &Version, &Version))
{ {
// Get the current configuration // Get the current configuration
XRRScreenConfiguration* Config = XRRGetScreenInfo(Disp.GetDisplay(), RootWindow(Disp.GetDisplay(), DefaultScreen(Disp.GetDisplay()))); XRRScreenConfiguration* Config = XRRGetScreenInfo(Disp.GetDisplay(), RootWindow(Disp.GetDisplay(), Screen));
if (Config) if (Config)
{ {
// Get the available screen sizes // Get the available screen sizes
@ -63,7 +64,7 @@ void VideoModeSupport::GetSupportedVideoModes(std::vector<VideoMode>& Modes)
{ {
// Get the list of supported depths // Get the list of supported depths
int NbDepths = 0; int NbDepths = 0;
int* Depths = XListDepths(Disp, Screen, &NbDepths); int* Depths = XListDepths(Disp.GetDisplay(), Screen, &NbDepths);
if (Depths && (NbDepths > 0)) if (Depths && (NbDepths > 0))
{ {
// Combine depths and sizes to fill the array of supported modes // Combine depths and sizes to fill the array of supported modes
@ -108,13 +109,14 @@ VideoMode VideoModeSupport::GetDesktopVideoMode()
// Get an access to the display // Get an access to the display
DisplayRef Disp; DisplayRef Disp;
int Screen = DefaultScreen(Disp.GetDisplay());
// Check if the XRandR extension is present // Check if the XRandR extension is present
int Version; int Version;
if (XQueryExtension(Disp.GetDisplay(), "RANDR", &Version, &Version, &Version)) if (XQueryExtension(Disp.GetDisplay(), "RANDR", &Version, &Version, &Version))
{ {
// Get the current configuration // Get the current configuration
XRRScreenConfiguration* Config = XRRGetScreenInfo(Disp.GetDisplay(), RootWindow(Disp.GetDisplay(), DefaultScreen(Disp.GetDisplay()))); XRRScreenConfiguration* Config = XRRGetScreenInfo(Disp.GetDisplay(), RootWindow(Disp.GetDisplay(), Screen));
if (Config) if (Config)
{ {
// Get the current video mode // Get the current video mode
@ -125,7 +127,7 @@ VideoMode VideoModeSupport::GetDesktopVideoMode()
int NbSizes; int NbSizes;
XRRScreenSize* Sizes = XRRConfigSizes(Config, &NbSizes); XRRScreenSize* Sizes = XRRConfigSizes(Config, &NbSizes);
if (Sizes && (NbSizes > 0)) if (Sizes && (NbSizes > 0))
DesktopMode = VideoMode(Sizes[CurrentMode].width, Sizes[CurrentMode].height, DefaultDepth(Disp, Screen)); DesktopMode = VideoMode(Sizes[CurrentMode].width, Sizes[CurrentMode].height, DefaultDepth(Disp.GetDisplay(), Screen));
// Free the configuration instance // Free the configuration instance
XRRFreeScreenConfigInfo(Config); XRRFreeScreenConfigInfo(Config);

View File

@ -28,6 +28,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/System/Unicode.hpp> #include <SFML/System/Unicode.hpp>
#include <X11/Xutil.h>
#include <X11/keysym.h> #include <X11/keysym.h>
#include <X11/extensions/Xrandr.h> #include <X11/extensions/Xrandr.h>
#include <iostream> #include <iostream>
@ -40,7 +41,7 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
namespace namespace
{ {
WindowImplX11* FullscreenWindow = NULL; sf::priv::WindowImplX11* FullscreenWindow = NULL;
unsigned long EventMask = FocusChangeMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | unsigned long EventMask = FocusChangeMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
PointerMotionMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask | PointerMotionMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask |
EnterWindowMask | LeaveWindowMask; EnterWindowMask | LeaveWindowMask;
@ -107,13 +108,16 @@ myKeyRepeat (true)
WindowImplX11::WindowImplX11(VideoMode Mode, const std::string& Title, unsigned long WindowStyle) : WindowImplX11::WindowImplX11(VideoMode Mode, const std::string& Title, unsigned long WindowStyle) :
myWindow (0), myWindow (0),
myIsExternal (false), myIsExternal (false),
myGLContext (NULL),
myAtomClose (0), myAtomClose (0),
myOldVideoMode(-1), myOldVideoMode(-1),
myHiddenCursor(0), myHiddenCursor(0),
myInputContext(NULL), myInputContext(NULL),
myKeyRepeat (true) myKeyRepeat (true)
{ {
// Get the display and screen
myDisplay = myDisplayRef.GetDisplay();
myScreen = DefaultScreen(myDisplay);
// Compute position and size // Compute position and size
int Left, Top; int Left, Top;
bool Fullscreen = (WindowStyle & Style::Fullscreen) != 0; bool Fullscreen = (WindowStyle & Style::Fullscreen) != 0;
@ -145,10 +149,10 @@ myKeyRepeat (true)
Left, Top, Left, Top,
Width, Height, Width, Height,
0, 0,
Visual.depth, DefaultDepth(myDisplay, myScreen),
InputOutput, InputOutput,
Visual.visual, DefaultVisual(myDisplay, myScreen),
CWEventMask | CWColormap | CWOverrideRedirect, &Attributes); CWEventMask | CWOverrideRedirect, &Attributes);
if (!myWindow) if (!myWindow)
{ {
std::cerr << "Failed to create window" << std::endl; std::cerr << "Failed to create window" << std::endl;
@ -260,6 +264,15 @@ WindowImplX11::~WindowImplX11()
} }
////////////////////////////////////////////////////////////
/// /see WindowImpl::GetHandle
////////////////////////////////////////////////////////////
WindowHandle WindowImplX11::GetHandle() const
{
return myWindow;
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// /see WindowImpl::ProcessEvents /// /see WindowImpl::ProcessEvents
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@ -81,6 +81,12 @@ public :
private : private :
////////////////////////////////////////////////////////////
/// /see WindowImpl::GetHandle
///
////////////////////////////////////////////////////////////
virtual WindowHandle GetHandle() const;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// /see WindowImpl::ProcessEvents /// /see WindowImpl::ProcessEvents
/// ///