Various improvements on OpenGL contexts handling
git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1245 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
parent
31b72b6385
commit
17190bd158
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -16,9 +16,6 @@ namespace sample_opengl
|
||||
// Create main window
|
||||
RenderWindow window = new RenderWindow(new VideoMode(800, 600), "SFML.Net OpenGL");
|
||||
|
||||
// Activate it as the target for OpenGL calls
|
||||
window.SetActive();
|
||||
|
||||
// Setup event handlers
|
||||
window.Closed += new EventHandler(OnClosed);
|
||||
window.KeyPressed += new EventHandler<KeyEventArgs>(OnKeyPressed);
|
||||
@ -79,7 +76,9 @@ namespace sample_opengl
|
||||
// will be rendered on top of the background sprite
|
||||
window.Flush();
|
||||
|
||||
// Activate the window for OpenGL calls
|
||||
// Activate the window before using OpenGL commands.
|
||||
// This is useless here because we have only one window which is
|
||||
// always the active one, but don't forget it if you use multiple windows
|
||||
window.SetActive();
|
||||
|
||||
// Clear depth buffer
|
||||
@ -169,8 +168,6 @@ namespace sample_opengl
|
||||
/// </summary>
|
||||
static void OnResized(object sender, SizeEventArgs e)
|
||||
{
|
||||
RenderWindow window = (RenderWindow)sender;
|
||||
window.SetActive();
|
||||
Gl.glViewport(0, 0, (int)e.Width, (int)e.Height);
|
||||
}
|
||||
}
|
||||
|
@ -15,9 +15,6 @@ namespace sample_window
|
||||
// Create the main window
|
||||
Window window = new Window(new VideoMode(640, 480, 32), "SFML.Net Window");
|
||||
|
||||
// Activate it as the target for OpenGL calls
|
||||
window.SetActive();
|
||||
|
||||
// Setup event handlers
|
||||
window.Closed += new EventHandler(OnClosed);
|
||||
window.KeyPressed += new EventHandler<KeyEventArgs>(OnKeyPressed);
|
||||
@ -44,7 +41,9 @@ namespace sample_window
|
||||
// Process events
|
||||
window.DispatchEvents();
|
||||
|
||||
// Set the active window before using OpenGL commands
|
||||
// Activate the window before using OpenGL commands.
|
||||
// This is useless here because we have only one window which is
|
||||
// always the active one, but don't forget it if you use multiple windows
|
||||
window.SetActive();
|
||||
|
||||
// Clear color and depth buffer
|
||||
@ -129,8 +128,6 @@ namespace sample_window
|
||||
/// </summary>
|
||||
static void OnResized(object sender, SizeEventArgs e)
|
||||
{
|
||||
Window window = (Window)sender;
|
||||
window.SetActive();
|
||||
Gl.glViewport(0, 0, (int)e.Width, (int)e.Height);
|
||||
}
|
||||
}
|
||||
|
@ -71,6 +71,18 @@ public :
|
||||
////////////////////////////////////////////////////////////
|
||||
void SetActive(bool active);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Make the current thread's reference context active
|
||||
///
|
||||
/// This function is meant to be called internally; it is used
|
||||
/// to deactivate the current context by activating another one
|
||||
/// (so that we still have an active context on the current thread).
|
||||
///
|
||||
/// \return True if operation was successful, false otherwise
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool SetReferenceActive();
|
||||
|
||||
private :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
@ -17,9 +17,6 @@ int main()
|
||||
// Create the main window
|
||||
sf::Window window(sf::VideoMode(640, 480, 32), "SFML Window");
|
||||
|
||||
// Activate it as the target for OpenGL calls
|
||||
window.SetActive();
|
||||
|
||||
// Create a clock for measuring the time elapsed
|
||||
sf::Clock clock;
|
||||
|
||||
@ -56,7 +53,9 @@ int main()
|
||||
glViewport(0, 0, event.Size.Width, event.Size.Height);
|
||||
}
|
||||
|
||||
// Activate the window
|
||||
// Activate the window before using OpenGL commands.
|
||||
// This is useless here because we have only one window which is
|
||||
// always the active one, but don't forget it if you use multiple windows
|
||||
window.SetActive();
|
||||
|
||||
// Clear color and depth buffer
|
||||
|
@ -45,8 +45,6 @@ namespace sf
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Default constructor
|
||||
////////////////////////////////////////////////////////////
|
||||
AudioDevice::AudioDevice()
|
||||
{
|
||||
// Create the device
|
||||
@ -78,8 +76,6 @@ AudioDevice::AudioDevice()
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Destructor
|
||||
////////////////////////////////////////////////////////////
|
||||
AudioDevice::~AudioDevice()
|
||||
{
|
||||
@ -94,8 +90,6 @@ AudioDevice::~AudioDevice()
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Get the unique instance of the class
|
||||
////////////////////////////////////////////////////////////
|
||||
AudioDevice& AudioDevice::GetInstance()
|
||||
{
|
||||
@ -103,8 +97,6 @@ AudioDevice& AudioDevice::GetInstance()
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Get the OpenAL audio device
|
||||
////////////////////////////////////////////////////////////
|
||||
ALCdevice* AudioDevice::GetDevice() const
|
||||
{
|
||||
@ -112,8 +104,6 @@ ALCdevice* AudioDevice::GetDevice() const
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Get the OpenAL format that matches the given number of channels
|
||||
////////////////////////////////////////////////////////////
|
||||
ALenum AudioDevice::GetFormatFromChannelsCount(unsigned int channelsCount) const
|
||||
{
|
||||
|
@ -37,30 +37,30 @@ namespace sf
|
||||
{
|
||||
namespace priv
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// AudioDevice is the high-level wrapper around the audio API,
|
||||
/// it manages creation and destruction of the audio device and context
|
||||
/// and stores the device capabilities
|
||||
/// \brief High-level wrapper around the audio API, it manages
|
||||
/// the creation and destruction of the audio device and
|
||||
/// context and stores the device capabilities
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class AudioDevice
|
||||
{
|
||||
public :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Default constructor
|
||||
/// \brief Default constructor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
AudioDevice();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Destructor
|
||||
/// \brief Destructor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
~AudioDevice();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Get the unique instance of the class
|
||||
/// \brief Get the unique instance of the class
|
||||
///
|
||||
/// \return Unique instance of the class
|
||||
///
|
||||
@ -68,7 +68,7 @@ public :
|
||||
static AudioDevice& GetInstance();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Get the OpenAL audio device
|
||||
/// \brief Get the OpenAL audio device
|
||||
///
|
||||
/// \return OpenAL device (cannot be NULL)
|
||||
///
|
||||
@ -76,9 +76,9 @@ public :
|
||||
ALCdevice* GetDevice() const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Get the OpenAL format that matches the given number of channels
|
||||
/// \brief Get the OpenAL format that matches the given number of channels
|
||||
///
|
||||
/// \param channelsCount : Number of channels
|
||||
/// \param channelsCount Number of channels
|
||||
///
|
||||
/// \return Corresponding format
|
||||
///
|
||||
|
@ -407,8 +407,6 @@ bool Image::CopyScreen(RenderWindow& window, const IntRect& sourceRect)
|
||||
myNeedArrayUpdate = true;
|
||||
myPixelsFlipped = true;
|
||||
|
||||
window.SetActive(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
@ -27,7 +27,7 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics/Linux/RenderImageImplPBuffer.hpp>
|
||||
#include <SFML/Graphics/GLCheck.hpp>
|
||||
#include <SFML/Window/Context.hpp>
|
||||
#include <SFML/Window/Context.hpp>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
@ -58,12 +58,12 @@ RenderImageImplPBuffer::~RenderImageImplPBuffer()
|
||||
|
||||
if (myPBuffer)
|
||||
glXDestroyGLXPbufferSGIX(myDisplay, myPBuffer);
|
||||
|
||||
XCloseDisplay(myDisplay);
|
||||
|
||||
XCloseDisplay(myDisplay);
|
||||
|
||||
// This is to make sure that another valid context is made
|
||||
// active after we destroy the P-Buffer's one
|
||||
Context context;
|
||||
Context::SetReferenceActive();
|
||||
}
|
||||
|
||||
|
||||
@ -72,18 +72,18 @@ RenderImageImplPBuffer::~RenderImageImplPBuffer()
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderImageImplPBuffer::IsSupported()
|
||||
{
|
||||
// Make sure that GLEW is initialized
|
||||
EnsureGlewInit();
|
||||
// Make sure that GLEW is initialized
|
||||
EnsureGlewInit();
|
||||
|
||||
return glxewIsSupported("GLX_SGIX_pbuffer");
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see RenderImageImpl::Create
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderImageImplPBuffer::Create(unsigned int width, unsigned int height, unsigned int, bool depthBuffer)
|
||||
{
|
||||
{
|
||||
// Store the dimensions
|
||||
myWidth = width;
|
||||
myHeight = height;
|
||||
@ -91,11 +91,11 @@ bool RenderImageImplPBuffer::Create(unsigned int width, unsigned int height, uns
|
||||
// Define the PBuffer attributes
|
||||
int visualAttributes[] =
|
||||
{
|
||||
GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
||||
GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
||||
GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
|
||||
GLX_RED_SIZE, 8,
|
||||
GLX_GREEN_SIZE, 8,
|
||||
GLX_BLUE_SIZE, 8,
|
||||
GLX_RED_SIZE, 8,
|
||||
GLX_GREEN_SIZE, 8,
|
||||
GLX_BLUE_SIZE, 8,
|
||||
GLX_ALPHA_SIZE, 8,
|
||||
GLX_DEPTH_SIZE, (depthBuffer ? 24 : 0),
|
||||
0
|
||||
@ -106,24 +106,24 @@ bool RenderImageImplPBuffer::Create(unsigned int width, unsigned int height, uns
|
||||
GLX_PBUFFER_HEIGHT, height,
|
||||
0
|
||||
};
|
||||
|
||||
// Get the available FB configurations
|
||||
int nbConfigs = 0;
|
||||
GLXFBConfig* configs = glXChooseFBConfigSGIX(myDisplay, DefaultScreen(myDisplay), visualAttributes, &nbConfigs);
|
||||
if (!configs || !nbConfigs)
|
||||
{
|
||||
|
||||
// Get the available FB configurations
|
||||
int nbConfigs = 0;
|
||||
GLXFBConfig* configs = glXChooseFBConfigSGIX(myDisplay, DefaultScreen(myDisplay), visualAttributes, &nbConfigs);
|
||||
if (!configs || !nbConfigs)
|
||||
{
|
||||
std::cerr << "Impossible to create render image (failed to find a suitable pixel format for PBuffer)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the P-Buffer
|
||||
myPBuffer = glXCreateGLXPbufferSGIX(myDisplay, configs[0], width, height, PBufferAttributes);
|
||||
if (!myPBuffer)
|
||||
{
|
||||
std::cerr << "Impossible to create render image (failed to create the OpenGL PBuffer)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the P-Buffer
|
||||
myPBuffer = glXCreateGLXPbufferSGIX(myDisplay, configs[0], width, height, PBufferAttributes);
|
||||
if (!myPBuffer)
|
||||
{
|
||||
std::cerr << "Impossible to create render image (failed to create the OpenGL PBuffer)" << std::endl;
|
||||
XFree(configs);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the actual size of the P-Buffer
|
||||
unsigned int actualWidth, actualHeight;
|
||||
@ -134,35 +134,35 @@ bool RenderImageImplPBuffer::Create(unsigned int width, unsigned int height, uns
|
||||
std::cerr << "Impossible to create render image (failed to match the requested size). "
|
||||
<< "Size: " << actualWidth << "x" << actualHeight << " - "
|
||||
<< "Requested: " << width << "x" << height
|
||||
<< std::endl;
|
||||
<< std::endl;
|
||||
XFree(configs);
|
||||
return false;
|
||||
}
|
||||
|
||||
// We'll have to share the P-Buffer context with the current context
|
||||
// We'll have to share the P-Buffer context with the current context
|
||||
GLXDrawable currentDrawable = glXGetCurrentDrawable();
|
||||
GLXContext currentContext = glXGetCurrentContext();
|
||||
if (currentContext)
|
||||
glXMakeCurrent(myDisplay, NULL, NULL);
|
||||
|
||||
// Create the context
|
||||
XVisualInfo* visual = glXGetVisualFromFBConfig(myDisplay, configs[0]);
|
||||
myContext = glXCreateContext(myDisplay, visual, currentContext, true);
|
||||
if (!myContext)
|
||||
{
|
||||
glXMakeCurrent(myDisplay, NULL, NULL);
|
||||
|
||||
// Create the context
|
||||
XVisualInfo* visual = glXGetVisualFromFBConfig(myDisplay, configs[0]);
|
||||
myContext = glXCreateContext(myDisplay, visual, currentContext, true);
|
||||
if (!myContext)
|
||||
{
|
||||
std::cerr << "Impossible to create render image (failed to create the OpenGL context)" << std::endl;
|
||||
XFree(configs);
|
||||
XFree(visual);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Restore the previous active context
|
||||
XFree(configs);
|
||||
XFree(visual);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Restore the previous active context
|
||||
if (currentContext)
|
||||
glXMakeCurrent(myDisplay, currentDrawable, currentContext);
|
||||
|
||||
// Cleanup resources
|
||||
XFree(configs);
|
||||
XFree(visual);
|
||||
glXMakeCurrent(myDisplay, currentDrawable, currentContext);
|
||||
|
||||
// Cleanup resources
|
||||
XFree(configs);
|
||||
XFree(visual);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -175,22 +175,25 @@ bool RenderImageImplPBuffer::Activate(bool active)
|
||||
{
|
||||
if (active)
|
||||
{
|
||||
if (myPBuffer && myContext && (glXGetCurrentContext() != myContext))
|
||||
if (myPBuffer && myContext)
|
||||
{
|
||||
// Bind the OpenGL context of the P-Buffer
|
||||
if (!glXMakeCurrent(myDisplay, myPBuffer, myContext))
|
||||
{
|
||||
std::cout << "Failed to activate render image" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (glXGetCurrentContext() != myContext)
|
||||
return glXMakeCurrent(myDisplay, myPBuffer, myContext) != 0;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We don't actually unbind the P-Buffer, for performances reasons
|
||||
// To deactivate the P-Buffer's context, we actually activate
|
||||
// another one so that we make sure that there is always an
|
||||
// active context for subsequent graphics operations
|
||||
return Context::SetReferenceActive();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -199,10 +202,6 @@ bool RenderImageImplPBuffer::Activate(bool active)
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderImageImplPBuffer::UpdateTexture(unsigned int textureId)
|
||||
{
|
||||
// Store the current active context
|
||||
GLXDrawable currentDrawable = glXGetCurrentDrawable();
|
||||
GLXContext currentContext = glXGetCurrentContext();
|
||||
|
||||
if (Activate(true))
|
||||
{
|
||||
// Bind the texture
|
||||
@ -212,8 +211,8 @@ bool RenderImageImplPBuffer::UpdateTexture(unsigned int textureId)
|
||||
// Copy the rendered pixels to the image
|
||||
GLCheck(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, myWidth, myHeight));
|
||||
|
||||
// Restore the previous context
|
||||
glXMakeCurrent(myDisplay, currentDrawable, currentContext);
|
||||
// Deactivate the P-Buffer
|
||||
Activate(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ RenderWindow::RenderWindow()
|
||||
////////////////////////////////////////////////////////////
|
||||
RenderWindow::RenderWindow(VideoMode mode, const std::string& title, unsigned long style, const ContextSettings& settings)
|
||||
{
|
||||
// Don't call the base class constructor because it contains virtual function calls
|
||||
Create(mode, title, style, settings);
|
||||
}
|
||||
|
||||
@ -57,6 +58,7 @@ RenderWindow::RenderWindow(VideoMode mode, const std::string& title, unsigned lo
|
||||
////////////////////////////////////////////////////////////
|
||||
RenderWindow::RenderWindow(WindowHandle handle, const ContextSettings& settings)
|
||||
{
|
||||
// Don't call the base class constructor because it contains virtual function calls
|
||||
Create(handle, settings);
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ RenderImageImplPBuffer::~RenderImageImplPBuffer()
|
||||
|
||||
// This is to make sure that another valid context is made
|
||||
// active after we destroy the P-Buffer's one
|
||||
Context context;
|
||||
Context::SetReferenceActive();
|
||||
}
|
||||
|
||||
|
||||
@ -167,23 +167,25 @@ bool RenderImageImplPBuffer::Activate(bool active)
|
||||
{
|
||||
if (active)
|
||||
{
|
||||
if (myDeviceContext && myContext && (wglGetCurrentContext() != myContext))
|
||||
if (myDeviceContext && myContext)
|
||||
{
|
||||
// Bind the OpenGL context of the P-Buffer
|
||||
if (!wglMakeCurrent(myDeviceContext, myContext))
|
||||
{
|
||||
std::cout << "Failed to activate render image" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (wglGetCurrentContext() != myContext)
|
||||
return wglMakeCurrent(myDeviceContext, myContext) != 0;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We don't actually unbind the P-Buffer,
|
||||
// for performances and consistency reasons
|
||||
// To deactivate the P-Buffer's context, we actually activate
|
||||
// another one so that we make sure that there is always an
|
||||
// active context for subsequent graphics operations
|
||||
return Context::SetReferenceActive();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -192,10 +194,6 @@ bool RenderImageImplPBuffer::Activate(bool active)
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderImageImplPBuffer::UpdateTexture(unsigned int textureId)
|
||||
{
|
||||
// Store the current active context
|
||||
HDC currentDC = wglGetCurrentDC();
|
||||
HGLRC currentContext = wglGetCurrentContext();
|
||||
|
||||
if (Activate(true))
|
||||
{
|
||||
// Bind the texture
|
||||
@ -205,8 +203,8 @@ bool RenderImageImplPBuffer::UpdateTexture(unsigned int textureId)
|
||||
// Copy the rendered pixels to the image
|
||||
GLCheck(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, myWidth, myHeight));
|
||||
|
||||
// Restore the previous context
|
||||
wglMakeCurrent(currentDC, currentContext);
|
||||
// Deactivate the P-Buffer
|
||||
Activate(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -54,4 +54,11 @@ void Context::SetActive(bool active)
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Context::SetReferenceActive()
|
||||
{
|
||||
return priv::ContextGL::SetReferenceActive();
|
||||
}
|
||||
|
||||
|
||||
} // namespace sf
|
||||
|
@ -99,8 +99,9 @@ ContextGL::~ContextGL()
|
||||
{
|
||||
threadContext = NULL;
|
||||
}
|
||||
else if (threadContext != NULL)
|
||||
else if (threadContext)
|
||||
{
|
||||
// Don't call this->SetActive(false), it would lead to a pure virtual function call
|
||||
threadContext->SetActive(true);
|
||||
}
|
||||
}
|
||||
@ -116,27 +117,41 @@ const ContextSettings& ContextGL::GetSettings() const
|
||||
////////////////////////////////////////////////////////////
|
||||
bool ContextGL::SetActive(bool active)
|
||||
{
|
||||
if (MakeCurrent(active))
|
||||
if (active)
|
||||
{
|
||||
if (active && (threadContext == 0))
|
||||
// Activate the context
|
||||
if (MakeCurrent())
|
||||
{
|
||||
// If this is the first context to be activated on this thread, make
|
||||
// it the reference context for the whole thread
|
||||
threadContext = this;
|
||||
}
|
||||
else if (!active && (threadContext != NULL) && (threadContext != this))
|
||||
{
|
||||
// Activate the reference context for this thread to ensure
|
||||
// that there is always an active context for subsequent graphics operations
|
||||
threadContext->SetActive(true);
|
||||
}
|
||||
if (!threadContext)
|
||||
threadContext = this;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
// Deactivate the context
|
||||
if (threadContext && (threadContext != this))
|
||||
{
|
||||
// To deactivate the context, we actually activate another one
|
||||
// so that we make sure that there is always an active context
|
||||
// for subsequent graphics operations
|
||||
return threadContext->SetActive(true);
|
||||
}
|
||||
}
|
||||
|
||||
// If we got there then something failed
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool ContextGL::SetReferenceActive()
|
||||
{
|
||||
if (threadContext)
|
||||
return threadContext->SetActive(true);
|
||||
}
|
||||
|
||||
|
||||
|
@ -129,6 +129,18 @@ public :
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void UseVerticalSync(bool enabled) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Make the current thread's reference context active
|
||||
///
|
||||
/// This function is meant to be called internally; it is used
|
||||
/// to deactivate the current context by activating another one
|
||||
/// (so that we still have an active context on the current thread).
|
||||
///
|
||||
/// \return True if operation was successful, false otherwise
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool SetReferenceActive();
|
||||
|
||||
protected :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -140,15 +152,13 @@ protected :
|
||||
ContextGL();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Activate or deactivate the context as the current target
|
||||
/// \brief Activate the context as the current target
|
||||
/// for rendering
|
||||
///
|
||||
/// \param active True to activate, false to deactivate
|
||||
///
|
||||
/// \return True on success, false if any error happened
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual bool MakeCurrent(bool active) = 0;
|
||||
virtual bool MakeCurrent() = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Evaluate a pixel format configuration
|
||||
|
@ -113,28 +113,18 @@ ContextGLX::~ContextGLX()
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool ContextGLX::MakeCurrent(bool active)
|
||||
bool ContextGLX::MakeCurrent()
|
||||
{
|
||||
if (active)
|
||||
if (myContext)
|
||||
{
|
||||
if (myContext)
|
||||
{
|
||||
if (glXGetCurrentContext() != myContext)
|
||||
return glXMakeCurrent(myDisplay, myWindow, myContext) != 0;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
if (glXGetCurrentContext() != myContext)
|
||||
return glXMakeCurrent(myDisplay, myWindow, myContext) != 0;
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (glXGetCurrentContext() == myContext)
|
||||
return glXMakeCurrent(myDisplay, None, NULL) != 0;
|
||||
else
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,15 +71,13 @@ public :
|
||||
~ContextGLX();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Activate or deactivate the context as the current target
|
||||
/// \brief Activate the context as the current target
|
||||
/// for rendering
|
||||
///
|
||||
/// \param active True to activate, false to deactivate
|
||||
///
|
||||
/// \return True on success, false if any error happened
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual bool MakeCurrent(bool active);
|
||||
virtual bool MakeCurrent();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Display what has been rendered to the context so far
|
||||
|
@ -29,6 +29,8 @@
|
||||
#include <SFML/Window/WindowImpl.hpp>
|
||||
#include <SFML/OpenGL.hpp>
|
||||
#include <SFML/Window/glext/wglext.h>
|
||||
#include <SFML/System/Lock.hpp>
|
||||
#include <SFML/System/Mutex.hpp>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
@ -38,20 +40,20 @@ namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
ContextWGL::ContextWGL(ContextWGL* shared) :
|
||||
myWindow (NULL),
|
||||
myDC (NULL),
|
||||
myContext (NULL),
|
||||
myOwnsWindow(true)
|
||||
myWindow (NULL),
|
||||
myDeviceContext(NULL),
|
||||
myContext (NULL),
|
||||
myOwnsWindow (true)
|
||||
{
|
||||
// TODO : try to create a bitmap in memory instead of a dummy window
|
||||
|
||||
// Create a dummy window (disabled and hidden)
|
||||
myWindow = CreateWindowA("STATIC", "", WS_POPUP | WS_DISABLED, 0, 0, 1, 1, NULL, NULL, GetModuleHandle(NULL), NULL);
|
||||
ShowWindow(myWindow, SW_HIDE);
|
||||
myDC = GetDC(myWindow);
|
||||
myDeviceContext = GetDC(myWindow);
|
||||
|
||||
// Create the context
|
||||
if (myDC)
|
||||
if (myDeviceContext)
|
||||
CreateContext(shared, VideoMode::GetDesktopMode().BitsPerPixel, ContextSettings(0, 0, 0));
|
||||
|
||||
// Activate the context
|
||||
@ -61,17 +63,17 @@ myOwnsWindow(true)
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
ContextWGL::ContextWGL(ContextWGL* shared, const WindowImpl* owner, unsigned int bitsPerPixel, const ContextSettings& settings) :
|
||||
myWindow (NULL),
|
||||
myDC (NULL),
|
||||
myContext (NULL),
|
||||
myOwnsWindow(false)
|
||||
myWindow (NULL),
|
||||
myDeviceContext(NULL),
|
||||
myContext (NULL),
|
||||
myOwnsWindow (false)
|
||||
{
|
||||
// Get the owner window and its device context
|
||||
myWindow = static_cast<HWND>(owner->GetHandle());
|
||||
myDC = GetDC(myWindow);
|
||||
myDeviceContext = GetDC(myWindow);
|
||||
|
||||
// Create the context
|
||||
if (myDC)
|
||||
if (myDeviceContext)
|
||||
CreateContext(shared, bitsPerPixel, settings);
|
||||
|
||||
// Activate the context
|
||||
@ -91,8 +93,8 @@ ContextWGL::~ContextWGL()
|
||||
}
|
||||
|
||||
// Release the DC
|
||||
if (myWindow && myDC)
|
||||
ReleaseDC(myWindow, myDC);
|
||||
if (myWindow && myDeviceContext)
|
||||
ReleaseDC(myWindow, myDeviceContext);
|
||||
|
||||
// Destroy the window if we own it
|
||||
if (myWindow && myOwnsWindow)
|
||||
@ -101,28 +103,18 @@ ContextWGL::~ContextWGL()
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool ContextWGL::MakeCurrent(bool active)
|
||||
bool ContextWGL::MakeCurrent()
|
||||
{
|
||||
if (active)
|
||||
if (myDeviceContext && myContext)
|
||||
{
|
||||
if (myDC && myContext)
|
||||
{
|
||||
if (wglGetCurrentContext() != myContext)
|
||||
return wglMakeCurrent(myDC, myContext) != 0;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
if (wglGetCurrentContext() != myContext)
|
||||
return wglMakeCurrent(myDeviceContext, myContext) != 0;
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wglGetCurrentContext() == myContext)
|
||||
return wglMakeCurrent(NULL, NULL) != 0;
|
||||
else
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -130,8 +122,8 @@ bool ContextWGL::MakeCurrent(bool active)
|
||||
////////////////////////////////////////////////////////////
|
||||
void ContextWGL::Display()
|
||||
{
|
||||
if (myDC && myContext)
|
||||
SwapBuffers(myDC);
|
||||
if (myDeviceContext && myContext)
|
||||
SwapBuffers(myDeviceContext);
|
||||
}
|
||||
|
||||
|
||||
@ -180,7 +172,7 @@ void ContextWGL::CreateContext(ContextWGL* shared, unsigned int bitsPerPixel, co
|
||||
int formats[128];
|
||||
UINT nbFormats;
|
||||
float floatAttributes[] = {0, 0};
|
||||
bool isValid = wglChoosePixelFormatARB(myDC, intAttributes, floatAttributes, sizeof(formats) / sizeof(*formats), formats, &nbFormats) != 0;
|
||||
bool isValid = wglChoosePixelFormatARB(myDeviceContext, intAttributes, floatAttributes, sizeof(formats) / sizeof(*formats), formats, &nbFormats) != 0;
|
||||
if (!isValid || (nbFormats == 0))
|
||||
{
|
||||
if (mySettings.AntialiasingLevel > 2)
|
||||
@ -190,7 +182,7 @@ void ContextWGL::CreateContext(ContextWGL* shared, unsigned int bitsPerPixel, co
|
||||
<< mySettings.AntialiasingLevel << " antialiasing levels ; trying with 2 levels" << std::endl;
|
||||
|
||||
mySettings.AntialiasingLevel = intAttributes[1] = 2;
|
||||
isValid = wglChoosePixelFormatARB(myDC, intAttributes, floatAttributes, sizeof(formats) / sizeof(*formats), formats, &nbFormats) != 0;
|
||||
isValid = wglChoosePixelFormatARB(myDeviceContext, intAttributes, floatAttributes, sizeof(formats) / sizeof(*formats), formats, &nbFormats) != 0;
|
||||
}
|
||||
|
||||
if (!isValid || (nbFormats == 0))
|
||||
@ -211,7 +203,7 @@ void ContextWGL::CreateContext(ContextWGL* shared, unsigned int bitsPerPixel, co
|
||||
PIXELFORMATDESCRIPTOR attributes;
|
||||
attributes.nSize = sizeof(attributes);
|
||||
attributes.nVersion = 1;
|
||||
DescribePixelFormat(myDC, formats[i], sizeof(attributes), &attributes);
|
||||
DescribePixelFormat(myDeviceContext, formats[i], sizeof(attributes), &attributes);
|
||||
|
||||
// Evaluate the current configuration
|
||||
int color = attributes.cRedBits + attributes.cGreenBits + attributes.cBlueBits + attributes.cAlphaBits;
|
||||
@ -243,7 +235,7 @@ void ContextWGL::CreateContext(ContextWGL* shared, unsigned int bitsPerPixel, co
|
||||
descriptor.cStencilBits = static_cast<BYTE>(mySettings.StencilBits);
|
||||
|
||||
// Get the pixel format that best matches our requirements
|
||||
bestFormat = ChoosePixelFormat(myDC, &descriptor);
|
||||
bestFormat = ChoosePixelFormat(myDeviceContext, &descriptor);
|
||||
if (bestFormat == 0)
|
||||
{
|
||||
std::cerr << "Failed to find a suitable pixel format for device context -- cannot create OpenGL context" << std::endl;
|
||||
@ -255,12 +247,12 @@ void ContextWGL::CreateContext(ContextWGL* shared, unsigned int bitsPerPixel, co
|
||||
PIXELFORMATDESCRIPTOR actualFormat;
|
||||
actualFormat.nSize = sizeof(actualFormat);
|
||||
actualFormat.nVersion = 1;
|
||||
DescribePixelFormat(myDC, bestFormat, sizeof(actualFormat), &actualFormat);
|
||||
DescribePixelFormat(myDeviceContext, bestFormat, sizeof(actualFormat), &actualFormat);
|
||||
mySettings.DepthBits = actualFormat.cDepthBits;
|
||||
mySettings.StencilBits = actualFormat.cStencilBits;
|
||||
|
||||
// Set the chosen pixel format
|
||||
if (!SetPixelFormat(myDC, bestFormat, &actualFormat))
|
||||
if (!SetPixelFormat(myDeviceContext, bestFormat, &actualFormat))
|
||||
{
|
||||
std::cerr << "Failed to set pixel format for device context -- cannot create OpenGL context" << std::endl;
|
||||
return;
|
||||
@ -279,13 +271,13 @@ void ContextWGL::CreateContext(ContextWGL* shared, unsigned int bitsPerPixel, co
|
||||
WGL_CONTEXT_MINOR_VERSION_ARB, 0,
|
||||
0, 0
|
||||
};
|
||||
myContext = wglCreateContextAttribsARB(myDC, sharedContext, attributes);
|
||||
myContext = wglCreateContextAttribsARB(myDeviceContext, sharedContext, attributes);
|
||||
}
|
||||
|
||||
// If the OpenGL 3.0 context failed, create a regular OpenGL 1.x context
|
||||
if (!myContext)
|
||||
{
|
||||
myContext = wglCreateContext(myDC);
|
||||
myContext = wglCreateContext(myDeviceContext);
|
||||
if (!myContext)
|
||||
{
|
||||
std::cerr << "Failed to create an OpenGL context for this window" << std::endl;
|
||||
@ -295,6 +287,10 @@ void ContextWGL::CreateContext(ContextWGL* shared, unsigned int bitsPerPixel, co
|
||||
// Share this context with others
|
||||
if (sharedContext)
|
||||
{
|
||||
// wglShareLists doesn't seem to be thread-safe
|
||||
static Mutex mutex;
|
||||
Lock lock(mutex);
|
||||
|
||||
if (!wglShareLists(sharedContext, myContext))
|
||||
std::cerr << "Failed to share the OpenGL context" << std::endl;
|
||||
}
|
||||
|
@ -70,15 +70,13 @@ public :
|
||||
~ContextWGL();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Activate or deactivate the context as the current target
|
||||
/// \brief Activate the context as the current target
|
||||
/// for rendering
|
||||
///
|
||||
/// \param active True to activate, false to deactivate
|
||||
///
|
||||
/// \return True on success, false if any error happened
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual bool MakeCurrent(bool active);
|
||||
virtual bool MakeCurrent();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Display what has been rendered to the context so far
|
||||
@ -122,10 +120,10 @@ private :
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
HWND myWindow; ///< Window to which the context is attached
|
||||
HDC myDC; ///< Device context of the window
|
||||
HGLRC myContext; ///< OpenGL context
|
||||
bool myOwnsWindow; ///< Did we create the host window?
|
||||
HWND myWindow; ///< Window to which the context is attached
|
||||
HDC myDeviceContext; ///< Device context of the window
|
||||
HGLRC myContext; ///< OpenGL context
|
||||
bool myOwnsWindow; ///< Did we create the host window?
|
||||
};
|
||||
|
||||
} // namespace priv
|
||||
|
@ -27,7 +27,6 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/Window.hpp>
|
||||
#include <SFML/Window/ContextGL.hpp>
|
||||
#include <SFML/Window/Context.hpp>
|
||||
#include <SFML/Window/WindowImpl.hpp>
|
||||
#include <SFML/System/Sleep.hpp>
|
||||
#include <iostream>
|
||||
@ -127,16 +126,9 @@ void Window::Create(VideoMode mode, const std::string& title, unsigned long styl
|
||||
style |= Style::Titlebar;
|
||||
|
||||
// Recreate the window implementation
|
||||
delete myWindow;
|
||||
myWindow = priv::WindowImpl::New(mode, title, style);
|
||||
|
||||
// Make sure another context is bound, so that:
|
||||
// - the context creation can request OpenGL extensions if necessary
|
||||
// - myContext can safely be destroyed (it's no longer bound)
|
||||
Context context;
|
||||
|
||||
// Recreate the context
|
||||
delete myContext;
|
||||
myContext = priv::ContextGL::New(myWindow, mode.BitsPerPixel, settings);
|
||||
|
||||
// Perform common initializations
|
||||
@ -147,17 +139,13 @@ void Window::Create(VideoMode mode, const std::string& title, unsigned long styl
|
||||
////////////////////////////////////////////////////////////
|
||||
void Window::Create(WindowHandle handle, const ContextSettings& settings)
|
||||
{
|
||||
// Recreate the window implementation
|
||||
// Destroy the previous window implementation
|
||||
Close();
|
||||
|
||||
// Recreate the window implementation
|
||||
myWindow = priv::WindowImpl::New(handle);
|
||||
|
||||
// Make sure another context is bound, so that:
|
||||
// - the context creation can request OpenGL extensions if necessary
|
||||
// - myContext can safely be destroyed (it's no longer bound)
|
||||
Context context;
|
||||
|
||||
// Recreate the context
|
||||
delete myContext;
|
||||
myContext = priv::ContextGL::New(myWindow, VideoMode::GetDesktopMode().BitsPerPixel, settings);
|
||||
|
||||
// Perform common initializations
|
||||
@ -325,6 +313,7 @@ bool Window::SetActive(bool active) const
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Trying to activate the window, but it doesn't have a valid context" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -349,11 +338,8 @@ void Window::Display()
|
||||
myClock.Reset();
|
||||
|
||||
// Display the backbuffer on screen
|
||||
if (SetActive(true))
|
||||
{
|
||||
if (SetActive())
|
||||
myContext->Display();
|
||||
SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -435,7 +421,7 @@ void Window::Initialize()
|
||||
myLastFrameTime = 0.f;
|
||||
|
||||
// Activate the window
|
||||
SetActive(true);
|
||||
SetActive();
|
||||
|
||||
// Notify the derived class
|
||||
OnCreate();
|
||||
|
Loading…
Reference in New Issue
Block a user