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:
parent
b194b9969a
commit
392eb219f2
@ -15,16 +15,16 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
int main()
|
||||
{
|
||||
// Create main window
|
||||
sf::RenderWindow App(sf::VideoMode(800, 600), "SFML OpenGL");
|
||||
App.PreserveOpenGLStates(true);
|
||||
|
||||
// Create a sprite for the background
|
||||
sf::Image BackgroundImage;
|
||||
if (!BackgroundImage.LoadFromFile("datas/opengl/background.jpg"))
|
||||
return EXIT_FAILURE;
|
||||
sf::Sprite Background(BackgroundImage);
|
||||
|
||||
// Create main window
|
||||
sf::RenderWindow App(sf::VideoMode(800, 600), "SFML OpenGL");
|
||||
App.PreserveOpenGLStates(true);
|
||||
|
||||
// Load an OpenGL texture.
|
||||
// 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
|
||||
|
@ -41,41 +41,34 @@ namespace priv
|
||||
/// Create a new context, not associated to a window
|
||||
////////////////////////////////////////////////////////////
|
||||
ContextGLX::ContextGLX(ContextGLX* Shared) :
|
||||
myWindow (NULL),
|
||||
myContext (NULL)/*,
|
||||
myOwnsWindow(true)*/
|
||||
myWindow (0),
|
||||
myContext (NULL),
|
||||
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)
|
||||
myWindow = XCreateWindow(ourDisplay,
|
||||
RootWindow(ourDisplay, ourScreen),
|
||||
int Screen = DefaultScreen(myDisplay.GetDisplay());
|
||||
myWindow = XCreateWindow(myDisplay.GetDisplay(),
|
||||
RootWindow(myDisplay.GetDisplay(), Screen),
|
||||
0, 0,
|
||||
myWidth, myHeight,
|
||||
1, 1,
|
||||
0,
|
||||
Visual.depth,
|
||||
DefaultDepth(myDisplay.GetDisplay(), Screen),
|
||||
InputOutput,
|
||||
Visual.visual,
|
||||
CWColormap, &Attributes);*/
|
||||
DefaultVisual(myDisplay.GetDisplay(), Screen),
|
||||
0, NULL);
|
||||
|
||||
// Create the context
|
||||
CreateContext(Shared, VideoMode::GetDesktopMode().BitsPerPixel, ContextSettings(0, 0, 0));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Create a new context attached to a window
|
||||
////////////////////////////////////////////////////////////
|
||||
ContextGLX::ContextGLX(ContextWGL* Shared, const WindowImpl* Owner, unsigned int BitsPerPixel, const ContextSettings& Settings) :
|
||||
myWindow (NULL),
|
||||
myContext (NULL),/*
|
||||
myOwnsWindow(false)*/
|
||||
ContextGLX::ContextGLX(ContextGLX* Shared, const WindowImpl* Owner, unsigned int BitsPerPixel, const ContextSettings& Settings) :
|
||||
myWindow (0),
|
||||
myContext (NULL),
|
||||
myOwnsWindow(false)
|
||||
{
|
||||
// Get the owner window and its device context
|
||||
myWindow = static_cast<Window>(Owner->GetHandle());
|
||||
@ -91,20 +84,20 @@ myOwnsWindow(false)*/
|
||||
////////////////////////////////////////////////////////////
|
||||
ContextGLX::~ContextGLX()
|
||||
{
|
||||
// Destroy the OpenGL context
|
||||
// Destroy the context
|
||||
if (myContext)
|
||||
{
|
||||
if (glXGetCurrentContext() == myContext)
|
||||
glXMakeCurrent(myDisplay.GetDisplay(), None, NULL);
|
||||
glXDestroyContext(myContext);
|
||||
glXDestroyContext(myDisplay.GetDisplay(), myContext);
|
||||
}
|
||||
|
||||
|
||||
// Destroy the window if we own it
|
||||
/*if (myWindow && myOwnsWindow)
|
||||
if (myWindow && myOwnsWindow)
|
||||
{
|
||||
XDestroyWindow(myDisplay.GetDisplay(), myWindow);
|
||||
XFlush(myDisplay.GetDisplay());
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -115,7 +108,7 @@ bool ContextGLX::MakeCurrent(bool Active)
|
||||
{
|
||||
if (Active)
|
||||
{
|
||||
if (myWindow && myContext)
|
||||
if (myContext)
|
||||
{
|
||||
if (glXGetCurrentContext() != myContext)
|
||||
return glXMakeCurrent(myDisplay.GetDisplay(), myWindow, myContext) != 0;
|
||||
@ -130,7 +123,7 @@ bool ContextGLX::MakeCurrent(bool Active)
|
||||
else
|
||||
{
|
||||
if (glXGetCurrentContext() == myContext)
|
||||
return wglMakeCurrent(myDisplay.GetDisplay(), None, NULL) != 0;
|
||||
return glXMakeCurrent(myDisplay.GetDisplay(), None, NULL) != 0;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
@ -173,23 +166,23 @@ bool ContextGLX::IsContextActive()
|
||||
////////////////////////////////////////////////////////////
|
||||
void ContextGLX::CreateContext(ContextGLX* Shared, unsigned int BitsPerPixel, const ContextSettings& Settings)
|
||||
{
|
||||
XVisualInfo Template;
|
||||
Template.screen = DefaultScreen(myDisplayRef.GetDisplay());
|
||||
if (myWindow)
|
||||
{
|
||||
// Get the attributes of the target window
|
||||
XWindowAttributes WindowAttributes;
|
||||
if (XGetWindowAttributes(myDisplayRef.GetDisplay(), myWindow, &WindowAttributes) == 0)
|
||||
{
|
||||
std::cerr << "Failed to get the window attributes" << std::endl;
|
||||
return;
|
||||
}
|
||||
// Save the creation settings
|
||||
mySettings = Settings;
|
||||
|
||||
// Setup the visual infos to match
|
||||
Template.depth = WindowAttributes.depth;
|
||||
Template.visualid = XVisualIDFromVisual(WindowAttributes.visual);
|
||||
// Get the attributes of the target window
|
||||
XWindowAttributes WindowAttributes;
|
||||
if (XGetWindowAttributes(myDisplay.GetDisplay(), myWindow, &WindowAttributes) == 0)
|
||||
{
|
||||
std::cerr << "Failed to get the window attributes" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup the visual infos to match
|
||||
XVisualInfo Template;
|
||||
Template.depth = WindowAttributes.depth;
|
||||
Template.visualid = XVisualIDFromVisual(WindowAttributes.visual);
|
||||
Template.screen = DefaultScreen(myDisplay.GetDisplay());
|
||||
|
||||
// Get all the visuals matching the template
|
||||
int NbVisuals = 0;
|
||||
XVisualInfo* Visuals = XGetVisualInfo(myDisplay.GetDisplay(), VisualDepthMask | VisualIDMask | VisualScreenMask, &Template, &NbVisuals);
|
||||
@ -210,16 +203,16 @@ void ContextGLX::CreateContext(ContextGLX* Shared, unsigned int BitsPerPixel, co
|
||||
{
|
||||
// Get the current visual attributes
|
||||
int RGBA, DoubleBuffer, Red, Green, Blue, Alpha, Depth, Stencil, MultiSampling, Samples;
|
||||
glXGetConfig(ourDisplay, &Visuals[i], GLX_RGBA, &RGBA);
|
||||
glXGetConfig(ourDisplay, &Visuals[i], GLX_DOUBLEBUFFER, &DoubleBuffer);
|
||||
glXGetConfig(ourDisplay, &Visuals[i], GLX_RED_SIZE, &Red);
|
||||
glXGetConfig(ourDisplay, &Visuals[i], GLX_GREEN_SIZE, &Green);
|
||||
glXGetConfig(ourDisplay, &Visuals[i], GLX_BLUE_SIZE, &Blue);
|
||||
glXGetConfig(ourDisplay, &Visuals[i], GLX_ALPHA_SIZE, &Alpha);
|
||||
glXGetConfig(ourDisplay, &Visuals[i], GLX_DEPTH_SIZE, &Depth);
|
||||
glXGetConfig(ourDisplay, &Visuals[i], GLX_STENCIL_SIZE, &Stencil);
|
||||
glXGetConfig(ourDisplay, &Visuals[i], GLX_SAMPLE_BUFFERS_ARB, &MultiSampling);
|
||||
glXGetConfig(ourDisplay, &Visuals[i], GLX_SAMPLES_ARB, &Samples);
|
||||
glXGetConfig(myDisplay.GetDisplay(), &Visuals[i], GLX_RGBA, &RGBA);
|
||||
glXGetConfig(myDisplay.GetDisplay(), &Visuals[i], GLX_DOUBLEBUFFER, &DoubleBuffer);
|
||||
glXGetConfig(myDisplay.GetDisplay(), &Visuals[i], GLX_RED_SIZE, &Red);
|
||||
glXGetConfig(myDisplay.GetDisplay(), &Visuals[i], GLX_GREEN_SIZE, &Green);
|
||||
glXGetConfig(myDisplay.GetDisplay(), &Visuals[i], GLX_BLUE_SIZE, &Blue);
|
||||
glXGetConfig(myDisplay.GetDisplay(), &Visuals[i], GLX_ALPHA_SIZE, &Alpha);
|
||||
glXGetConfig(myDisplay.GetDisplay(), &Visuals[i], GLX_DEPTH_SIZE, &Depth);
|
||||
glXGetConfig(myDisplay.GetDisplay(), &Visuals[i], GLX_STENCIL_SIZE, &Stencil);
|
||||
glXGetConfig(myDisplay.GetDisplay(), &Visuals[i], GLX_SAMPLE_BUFFERS_ARB, &MultiSampling);
|
||||
glXGetConfig(myDisplay.GetDisplay(), &Visuals[i], GLX_SAMPLES_ARB, &Samples);
|
||||
|
||||
// First check the mandatory parameters
|
||||
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 (!BestVisual)
|
||||
{
|
||||
if (Params.AntialiasingLevel > 2)
|
||||
if (mySettings.AntialiasingLevel > 2)
|
||||
{
|
||||
std::cerr << "Failed to find a pixel format supporting "
|
||||
<< Params.AntialiasingLevel << " antialiasing levels ; trying with 2 levels" << std::endl;
|
||||
Params.AntialiasingLevel = 2;
|
||||
<< mySettings.AntialiasingLevel << " antialiasing levels ; trying with 2 levels" << std::endl;
|
||||
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;
|
||||
Params.AntialiasingLevel = 0;
|
||||
mySettings.AntialiasingLevel = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -278,12 +271,9 @@ void ContextGLX::CreateContext(ContextGLX* Shared, unsigned int BitsPerPixel, co
|
||||
mySettings.StencilBits = static_cast<unsigned int>(Stencil);
|
||||
|
||||
// Change the target window's colormap so that it matches the context's one
|
||||
if (myWindow)
|
||||
{
|
||||
::Window Root = RootWindow(myDisplay.GetDisplay(), DefaultScreen(myDisplay.GetDisplay()))
|
||||
Colormap ColMap = XCreateColormap(myDisplay.GetDisplay(), Root, BestVisual->visual, AllocNone);
|
||||
XSetWindowColormap(myDisplay.GetDisplay(), myWindow, ColMap);
|
||||
}
|
||||
::Window Root = RootWindow(myDisplay.GetDisplay(), DefaultScreen(myDisplay.GetDisplay()));
|
||||
Colormap ColMap = XCreateColormap(myDisplay.GetDisplay(), Root, BestVisual->visual, AllocNone);
|
||||
XSetWindowColormap(myDisplay.GetDisplay(), myWindow, ColMap);
|
||||
|
||||
// Free the temporary visuals array
|
||||
XFree(Visuals);
|
||||
|
@ -108,27 +108,13 @@ private :
|
||||
////////////////////////////////////////////////////////////
|
||||
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
|
||||
////////////////////////////////////////////////////////////
|
||||
DisplayRef myDisplay; ///< Connection to the X server
|
||||
::Window myWindow; ///< Window to which the context is attached
|
||||
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
|
||||
|
@ -47,13 +47,14 @@ void VideoModeSupport::GetSupportedVideoModes(std::vector<VideoMode>& Modes)
|
||||
|
||||
// Get an access to the display
|
||||
DisplayRef Disp;
|
||||
int Screen = DefaultScreen(Disp.GetDisplay());
|
||||
|
||||
// Check if the XRandR extension is present
|
||||
int Version;
|
||||
if (XQueryExtension(Disp.GetDisplay(), "RANDR", &Version, &Version, &Version))
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
// Get the available screen sizes
|
||||
@ -63,7 +64,7 @@ void VideoModeSupport::GetSupportedVideoModes(std::vector<VideoMode>& Modes)
|
||||
{
|
||||
// Get the list of supported depths
|
||||
int NbDepths = 0;
|
||||
int* Depths = XListDepths(Disp, Screen, &NbDepths);
|
||||
int* Depths = XListDepths(Disp.GetDisplay(), Screen, &NbDepths);
|
||||
if (Depths && (NbDepths > 0))
|
||||
{
|
||||
// Combine depths and sizes to fill the array of supported modes
|
||||
@ -108,13 +109,14 @@ VideoMode VideoModeSupport::GetDesktopVideoMode()
|
||||
|
||||
// Get an access to the display
|
||||
DisplayRef Disp;
|
||||
int Screen = DefaultScreen(Disp.GetDisplay());
|
||||
|
||||
// Check if the XRandR extension is present
|
||||
int Version;
|
||||
if (XQueryExtension(Disp.GetDisplay(), "RANDR", &Version, &Version, &Version))
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
// Get the current video mode
|
||||
@ -125,7 +127,7 @@ VideoMode VideoModeSupport::GetDesktopVideoMode()
|
||||
int NbSizes;
|
||||
XRRScreenSize* Sizes = XRRConfigSizes(Config, &NbSizes);
|
||||
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
|
||||
XRRFreeScreenConfigInfo(Config);
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <SFML/Window/WindowStyle.hpp> // important to be included first (conflict with None)
|
||||
#include <SFML/Window/Linux/WindowImplX11.hpp>
|
||||
#include <SFML/System/Unicode.hpp>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#include <iostream>
|
||||
@ -40,10 +41,10 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
namespace
|
||||
{
|
||||
WindowImplX11* FullscreenWindow = NULL;
|
||||
unsigned long EventMask = FocusChangeMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
|
||||
PointerMotionMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask |
|
||||
EnterWindowMask | LeaveWindowMask;
|
||||
sf::priv::WindowImplX11* FullscreenWindow = NULL;
|
||||
unsigned long EventMask = FocusChangeMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
|
||||
PointerMotionMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask |
|
||||
EnterWindowMask | LeaveWindowMask;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Filter the events received by windows
|
||||
@ -107,13 +108,16 @@ myKeyRepeat (true)
|
||||
WindowImplX11::WindowImplX11(VideoMode Mode, const std::string& Title, unsigned long WindowStyle) :
|
||||
myWindow (0),
|
||||
myIsExternal (false),
|
||||
myGLContext (NULL),
|
||||
myAtomClose (0),
|
||||
myOldVideoMode(-1),
|
||||
myHiddenCursor(0),
|
||||
myInputContext(NULL),
|
||||
myKeyRepeat (true)
|
||||
{
|
||||
// Get the display and screen
|
||||
myDisplay = myDisplayRef.GetDisplay();
|
||||
myScreen = DefaultScreen(myDisplay);
|
||||
|
||||
// Compute position and size
|
||||
int Left, Top;
|
||||
bool Fullscreen = (WindowStyle & Style::Fullscreen) != 0;
|
||||
@ -145,10 +149,10 @@ myKeyRepeat (true)
|
||||
Left, Top,
|
||||
Width, Height,
|
||||
0,
|
||||
Visual.depth,
|
||||
DefaultDepth(myDisplay, myScreen),
|
||||
InputOutput,
|
||||
Visual.visual,
|
||||
CWEventMask | CWColormap | CWOverrideRedirect, &Attributes);
|
||||
DefaultVisual(myDisplay, myScreen),
|
||||
CWEventMask | CWOverrideRedirect, &Attributes);
|
||||
if (!myWindow)
|
||||
{
|
||||
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
|
||||
////////////////////////////////////////////////////////////
|
||||
|
@ -81,6 +81,12 @@ public :
|
||||
|
||||
private :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see WindowImpl::GetHandle
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual WindowHandle GetHandle() const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see WindowImpl::ProcessEvents
|
||||
///
|
||||
|
Loading…
Reference in New Issue
Block a user