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
|
// Create main window
|
||||||
RenderWindow window = new RenderWindow(new VideoMode(800, 600), "SFML.Net OpenGL");
|
RenderWindow window = new RenderWindow(new VideoMode(800, 600), "SFML.Net OpenGL");
|
||||||
|
|
||||||
// Activate it as the target for OpenGL calls
|
|
||||||
window.SetActive();
|
|
||||||
|
|
||||||
// Setup event handlers
|
// Setup event handlers
|
||||||
window.Closed += new EventHandler(OnClosed);
|
window.Closed += new EventHandler(OnClosed);
|
||||||
window.KeyPressed += new EventHandler<KeyEventArgs>(OnKeyPressed);
|
window.KeyPressed += new EventHandler<KeyEventArgs>(OnKeyPressed);
|
||||||
@ -79,7 +76,9 @@ namespace sample_opengl
|
|||||||
// will be rendered on top of the background sprite
|
// will be rendered on top of the background sprite
|
||||||
window.Flush();
|
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();
|
window.SetActive();
|
||||||
|
|
||||||
// Clear depth buffer
|
// Clear depth buffer
|
||||||
@ -169,8 +168,6 @@ namespace sample_opengl
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
static void OnResized(object sender, SizeEventArgs e)
|
static void OnResized(object sender, SizeEventArgs e)
|
||||||
{
|
{
|
||||||
RenderWindow window = (RenderWindow)sender;
|
|
||||||
window.SetActive();
|
|
||||||
Gl.glViewport(0, 0, (int)e.Width, (int)e.Height);
|
Gl.glViewport(0, 0, (int)e.Width, (int)e.Height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,9 +15,6 @@ namespace sample_window
|
|||||||
// Create the main window
|
// Create the main window
|
||||||
Window window = new Window(new VideoMode(640, 480, 32), "SFML.Net 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
|
// Setup event handlers
|
||||||
window.Closed += new EventHandler(OnClosed);
|
window.Closed += new EventHandler(OnClosed);
|
||||||
window.KeyPressed += new EventHandler<KeyEventArgs>(OnKeyPressed);
|
window.KeyPressed += new EventHandler<KeyEventArgs>(OnKeyPressed);
|
||||||
@ -44,7 +41,9 @@ namespace sample_window
|
|||||||
// Process events
|
// Process events
|
||||||
window.DispatchEvents();
|
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();
|
window.SetActive();
|
||||||
|
|
||||||
// Clear color and depth buffer
|
// Clear color and depth buffer
|
||||||
@ -129,8 +128,6 @@ namespace sample_window
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
static void OnResized(object sender, SizeEventArgs e)
|
static void OnResized(object sender, SizeEventArgs e)
|
||||||
{
|
{
|
||||||
Window window = (Window)sender;
|
|
||||||
window.SetActive();
|
|
||||||
Gl.glViewport(0, 0, (int)e.Width, (int)e.Height);
|
Gl.glViewport(0, 0, (int)e.Width, (int)e.Height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,6 +71,18 @@ public :
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void SetActive(bool active);
|
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 :
|
private :
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
@ -17,9 +17,6 @@ int main()
|
|||||||
// Create the main window
|
// Create the main window
|
||||||
sf::Window window(sf::VideoMode(640, 480, 32), "SFML 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
|
// Create a clock for measuring the time elapsed
|
||||||
sf::Clock clock;
|
sf::Clock clock;
|
||||||
|
|
||||||
@ -56,7 +53,9 @@ int main()
|
|||||||
glViewport(0, 0, event.Size.Width, event.Size.Height);
|
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();
|
window.SetActive();
|
||||||
|
|
||||||
// Clear color and depth buffer
|
// Clear color and depth buffer
|
||||||
|
@ -45,8 +45,6 @@ namespace sf
|
|||||||
namespace priv
|
namespace priv
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Default constructor
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
AudioDevice::AudioDevice()
|
AudioDevice::AudioDevice()
|
||||||
{
|
{
|
||||||
// Create the device
|
// Create the device
|
||||||
@ -78,8 +76,6 @@ AudioDevice::AudioDevice()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// Destructor
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
AudioDevice::~AudioDevice()
|
AudioDevice::~AudioDevice()
|
||||||
{
|
{
|
||||||
@ -94,8 +90,6 @@ AudioDevice::~AudioDevice()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// Get the unique instance of the class
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
AudioDevice& AudioDevice::GetInstance()
|
AudioDevice& AudioDevice::GetInstance()
|
||||||
{
|
{
|
||||||
@ -103,8 +97,6 @@ AudioDevice& AudioDevice::GetInstance()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// Get the OpenAL audio device
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
ALCdevice* AudioDevice::GetDevice() const
|
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
|
ALenum AudioDevice::GetFormatFromChannelsCount(unsigned int channelsCount) const
|
||||||
{
|
{
|
||||||
|
@ -37,30 +37,30 @@ namespace sf
|
|||||||
{
|
{
|
||||||
namespace priv
|
namespace priv
|
||||||
{
|
{
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// AudioDevice is the high-level wrapper around the audio API,
|
/// \brief High-level wrapper around the audio API, it manages
|
||||||
/// it manages creation and destruction of the audio device and context
|
/// the creation and destruction of the audio device and
|
||||||
/// and stores the device capabilities
|
/// context and stores the device capabilities
|
||||||
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
class AudioDevice
|
class AudioDevice
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Default constructor
|
/// \brief Default constructor
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
AudioDevice();
|
AudioDevice();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Destructor
|
/// \brief Destructor
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
~AudioDevice();
|
~AudioDevice();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Get the unique instance of the class
|
/// \brief Get the unique instance of the class
|
||||||
///
|
///
|
||||||
/// \return Unique instance of the class
|
/// \return Unique instance of the class
|
||||||
///
|
///
|
||||||
@ -68,7 +68,7 @@ public :
|
|||||||
static AudioDevice& GetInstance();
|
static AudioDevice& GetInstance();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Get the OpenAL audio device
|
/// \brief Get the OpenAL audio device
|
||||||
///
|
///
|
||||||
/// \return OpenAL device (cannot be NULL)
|
/// \return OpenAL device (cannot be NULL)
|
||||||
///
|
///
|
||||||
@ -76,9 +76,9 @@ public :
|
|||||||
ALCdevice* GetDevice() const;
|
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
|
/// \return Corresponding format
|
||||||
///
|
///
|
||||||
|
@ -407,8 +407,6 @@ bool Image::CopyScreen(RenderWindow& window, const IntRect& sourceRect)
|
|||||||
myNeedArrayUpdate = true;
|
myNeedArrayUpdate = true;
|
||||||
myPixelsFlipped = true;
|
myPixelsFlipped = true;
|
||||||
|
|
||||||
window.SetActive(false);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -63,7 +63,7 @@ RenderImageImplPBuffer::~RenderImageImplPBuffer()
|
|||||||
|
|
||||||
// This is to make sure that another valid context is made
|
// This is to make sure that another valid context is made
|
||||||
// active after we destroy the P-Buffer's one
|
// active after we destroy the P-Buffer's one
|
||||||
Context context;
|
Context::SetReferenceActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -175,22 +175,25 @@ bool RenderImageImplPBuffer::Activate(bool active)
|
|||||||
{
|
{
|
||||||
if (active)
|
if (active)
|
||||||
{
|
{
|
||||||
if (myPBuffer && myContext && (glXGetCurrentContext() != myContext))
|
if (myPBuffer && myContext)
|
||||||
{
|
{
|
||||||
// Bind the OpenGL context of the P-Buffer
|
if (glXGetCurrentContext() != myContext)
|
||||||
if (!glXMakeCurrent(myDisplay, myPBuffer, myContext))
|
return glXMakeCurrent(myDisplay, myPBuffer, myContext) != 0;
|
||||||
{
|
else
|
||||||
std::cout << "Failed to activate render image" << std::endl;
|
return true;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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)
|
bool RenderImageImplPBuffer::UpdateTexture(unsigned int textureId)
|
||||||
{
|
{
|
||||||
// Store the current active context
|
|
||||||
GLXDrawable currentDrawable = glXGetCurrentDrawable();
|
|
||||||
GLXContext currentContext = glXGetCurrentContext();
|
|
||||||
|
|
||||||
if (Activate(true))
|
if (Activate(true))
|
||||||
{
|
{
|
||||||
// Bind the texture
|
// Bind the texture
|
||||||
@ -212,8 +211,8 @@ bool RenderImageImplPBuffer::UpdateTexture(unsigned int textureId)
|
|||||||
// Copy the rendered pixels to the image
|
// Copy the rendered pixels to the image
|
||||||
GLCheck(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, myWidth, myHeight));
|
GLCheck(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, myWidth, myHeight));
|
||||||
|
|
||||||
// Restore the previous context
|
// Deactivate the P-Buffer
|
||||||
glXMakeCurrent(myDisplay, currentDrawable, currentContext);
|
Activate(false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,7 @@ RenderWindow::RenderWindow()
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
RenderWindow::RenderWindow(VideoMode mode, const std::string& title, unsigned long style, const ContextSettings& settings)
|
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);
|
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)
|
RenderWindow::RenderWindow(WindowHandle handle, const ContextSettings& settings)
|
||||||
{
|
{
|
||||||
|
// Don't call the base class constructor because it contains virtual function calls
|
||||||
Create(handle, settings);
|
Create(handle, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ RenderImageImplPBuffer::~RenderImageImplPBuffer()
|
|||||||
|
|
||||||
// This is to make sure that another valid context is made
|
// This is to make sure that another valid context is made
|
||||||
// active after we destroy the P-Buffer's one
|
// 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 (active)
|
||||||
{
|
{
|
||||||
if (myDeviceContext && myContext && (wglGetCurrentContext() != myContext))
|
if (myDeviceContext && myContext)
|
||||||
{
|
{
|
||||||
// Bind the OpenGL context of the P-Buffer
|
if (wglGetCurrentContext() != myContext)
|
||||||
if (!wglMakeCurrent(myDeviceContext, myContext))
|
return wglMakeCurrent(myDeviceContext, myContext) != 0;
|
||||||
{
|
else
|
||||||
std::cout << "Failed to activate render image" << std::endl;
|
return true;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// We don't actually unbind the P-Buffer,
|
// To deactivate the P-Buffer's context, we actually activate
|
||||||
// for performances and consistency reasons
|
// 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)
|
bool RenderImageImplPBuffer::UpdateTexture(unsigned int textureId)
|
||||||
{
|
{
|
||||||
// Store the current active context
|
|
||||||
HDC currentDC = wglGetCurrentDC();
|
|
||||||
HGLRC currentContext = wglGetCurrentContext();
|
|
||||||
|
|
||||||
if (Activate(true))
|
if (Activate(true))
|
||||||
{
|
{
|
||||||
// Bind the texture
|
// Bind the texture
|
||||||
@ -205,8 +203,8 @@ bool RenderImageImplPBuffer::UpdateTexture(unsigned int textureId)
|
|||||||
// Copy the rendered pixels to the image
|
// Copy the rendered pixels to the image
|
||||||
GLCheck(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, myWidth, myHeight));
|
GLCheck(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, myWidth, myHeight));
|
||||||
|
|
||||||
// Restore the previous context
|
// Deactivate the P-Buffer
|
||||||
wglMakeCurrent(currentDC, currentContext);
|
Activate(false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -54,4 +54,11 @@ void Context::SetActive(bool active)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
bool Context::SetReferenceActive()
|
||||||
|
{
|
||||||
|
return priv::ContextGL::SetReferenceActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
@ -99,8 +99,9 @@ ContextGL::~ContextGL()
|
|||||||
{
|
{
|
||||||
threadContext = NULL;
|
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);
|
threadContext->SetActive(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,27 +117,41 @@ const ContextSettings& ContextGL::GetSettings() const
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool ContextGL::SetActive(bool active)
|
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
|
// If this is the first context to be activated on this thread, make
|
||||||
// it the reference context for the whole thread
|
// it the reference context for the whole thread
|
||||||
|
if (!threadContext)
|
||||||
threadContext = this;
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
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;
|
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 :
|
protected :
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@ -140,15 +152,13 @@ protected :
|
|||||||
ContextGL();
|
ContextGL();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Activate or deactivate the context as the current target
|
/// \brief Activate the context as the current target
|
||||||
/// for rendering
|
/// for rendering
|
||||||
///
|
///
|
||||||
/// \param active True to activate, false to deactivate
|
|
||||||
///
|
|
||||||
/// \return True on success, false if any error happened
|
/// \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
|
/// \brief Evaluate a pixel format configuration
|
||||||
|
@ -113,10 +113,8 @@ ContextGLX::~ContextGLX()
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool ContextGLX::MakeCurrent(bool active)
|
bool ContextGLX::MakeCurrent()
|
||||||
{
|
{
|
||||||
if (active)
|
|
||||||
{
|
|
||||||
if (myContext)
|
if (myContext)
|
||||||
{
|
{
|
||||||
if (glXGetCurrentContext() != myContext)
|
if (glXGetCurrentContext() != myContext)
|
||||||
@ -128,14 +126,6 @@ bool ContextGLX::MakeCurrent(bool active)
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (glXGetCurrentContext() == myContext)
|
|
||||||
return glXMakeCurrent(myDisplay, None, NULL) != 0;
|
|
||||||
else
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,15 +71,13 @@ public :
|
|||||||
~ContextGLX();
|
~ContextGLX();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Activate or deactivate the context as the current target
|
/// \brief Activate the context as the current target
|
||||||
/// for rendering
|
/// for rendering
|
||||||
///
|
///
|
||||||
/// \param active True to activate, false to deactivate
|
|
||||||
///
|
|
||||||
/// \return True on success, false if any error happened
|
/// \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
|
/// \brief Display what has been rendered to the context so far
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
#include <SFML/Window/WindowImpl.hpp>
|
#include <SFML/Window/WindowImpl.hpp>
|
||||||
#include <SFML/OpenGL.hpp>
|
#include <SFML/OpenGL.hpp>
|
||||||
#include <SFML/Window/glext/wglext.h>
|
#include <SFML/Window/glext/wglext.h>
|
||||||
|
#include <SFML/System/Lock.hpp>
|
||||||
|
#include <SFML/System/Mutex.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
@ -39,19 +41,19 @@ namespace priv
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
ContextWGL::ContextWGL(ContextWGL* shared) :
|
ContextWGL::ContextWGL(ContextWGL* shared) :
|
||||||
myWindow (NULL),
|
myWindow (NULL),
|
||||||
myDC (NULL),
|
myDeviceContext(NULL),
|
||||||
myContext (NULL),
|
myContext (NULL),
|
||||||
myOwnsWindow(true)
|
myOwnsWindow (true)
|
||||||
{
|
{
|
||||||
// TODO : try to create a bitmap in memory instead of a dummy window
|
// TODO : try to create a bitmap in memory instead of a dummy window
|
||||||
|
|
||||||
// Create a dummy window (disabled and hidden)
|
// Create a dummy window (disabled and hidden)
|
||||||
myWindow = CreateWindowA("STATIC", "", WS_POPUP | WS_DISABLED, 0, 0, 1, 1, NULL, NULL, GetModuleHandle(NULL), NULL);
|
myWindow = CreateWindowA("STATIC", "", WS_POPUP | WS_DISABLED, 0, 0, 1, 1, NULL, NULL, GetModuleHandle(NULL), NULL);
|
||||||
ShowWindow(myWindow, SW_HIDE);
|
ShowWindow(myWindow, SW_HIDE);
|
||||||
myDC = GetDC(myWindow);
|
myDeviceContext = GetDC(myWindow);
|
||||||
|
|
||||||
// Create the context
|
// Create the context
|
||||||
if (myDC)
|
if (myDeviceContext)
|
||||||
CreateContext(shared, VideoMode::GetDesktopMode().BitsPerPixel, ContextSettings(0, 0, 0));
|
CreateContext(shared, VideoMode::GetDesktopMode().BitsPerPixel, ContextSettings(0, 0, 0));
|
||||||
|
|
||||||
// Activate the context
|
// Activate the context
|
||||||
@ -62,16 +64,16 @@ myOwnsWindow(true)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
ContextWGL::ContextWGL(ContextWGL* shared, const WindowImpl* owner, unsigned int bitsPerPixel, const ContextSettings& settings) :
|
ContextWGL::ContextWGL(ContextWGL* shared, const WindowImpl* owner, unsigned int bitsPerPixel, const ContextSettings& settings) :
|
||||||
myWindow (NULL),
|
myWindow (NULL),
|
||||||
myDC (NULL),
|
myDeviceContext(NULL),
|
||||||
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<HWND>(owner->GetHandle());
|
myWindow = static_cast<HWND>(owner->GetHandle());
|
||||||
myDC = GetDC(myWindow);
|
myDeviceContext = GetDC(myWindow);
|
||||||
|
|
||||||
// Create the context
|
// Create the context
|
||||||
if (myDC)
|
if (myDeviceContext)
|
||||||
CreateContext(shared, bitsPerPixel, settings);
|
CreateContext(shared, bitsPerPixel, settings);
|
||||||
|
|
||||||
// Activate the context
|
// Activate the context
|
||||||
@ -91,8 +93,8 @@ ContextWGL::~ContextWGL()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Release the DC
|
// Release the DC
|
||||||
if (myWindow && myDC)
|
if (myWindow && myDeviceContext)
|
||||||
ReleaseDC(myWindow, myDC);
|
ReleaseDC(myWindow, myDeviceContext);
|
||||||
|
|
||||||
// Destroy the window if we own it
|
// Destroy the window if we own it
|
||||||
if (myWindow && myOwnsWindow)
|
if (myWindow && myOwnsWindow)
|
||||||
@ -101,14 +103,12 @@ ContextWGL::~ContextWGL()
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool ContextWGL::MakeCurrent(bool active)
|
bool ContextWGL::MakeCurrent()
|
||||||
{
|
{
|
||||||
if (active)
|
if (myDeviceContext && myContext)
|
||||||
{
|
|
||||||
if (myDC && myContext)
|
|
||||||
{
|
{
|
||||||
if (wglGetCurrentContext() != myContext)
|
if (wglGetCurrentContext() != myContext)
|
||||||
return wglMakeCurrent(myDC, myContext) != 0;
|
return wglMakeCurrent(myDeviceContext, myContext) != 0;
|
||||||
else
|
else
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -116,22 +116,14 @@ bool ContextWGL::MakeCurrent(bool active)
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (wglGetCurrentContext() == myContext)
|
|
||||||
return wglMakeCurrent(NULL, NULL) != 0;
|
|
||||||
else
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void ContextWGL::Display()
|
void ContextWGL::Display()
|
||||||
{
|
{
|
||||||
if (myDC && myContext)
|
if (myDeviceContext && myContext)
|
||||||
SwapBuffers(myDC);
|
SwapBuffers(myDeviceContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -180,7 +172,7 @@ void ContextWGL::CreateContext(ContextWGL* shared, unsigned int bitsPerPixel, co
|
|||||||
int formats[128];
|
int formats[128];
|
||||||
UINT nbFormats;
|
UINT nbFormats;
|
||||||
float floatAttributes[] = {0, 0};
|
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 (!isValid || (nbFormats == 0))
|
||||||
{
|
{
|
||||||
if (mySettings.AntialiasingLevel > 2)
|
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 << " antialiasing levels ; trying with 2 levels" << std::endl;
|
||||||
|
|
||||||
mySettings.AntialiasingLevel = intAttributes[1] = 2;
|
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))
|
if (!isValid || (nbFormats == 0))
|
||||||
@ -211,7 +203,7 @@ void ContextWGL::CreateContext(ContextWGL* shared, unsigned int bitsPerPixel, co
|
|||||||
PIXELFORMATDESCRIPTOR attributes;
|
PIXELFORMATDESCRIPTOR attributes;
|
||||||
attributes.nSize = sizeof(attributes);
|
attributes.nSize = sizeof(attributes);
|
||||||
attributes.nVersion = 1;
|
attributes.nVersion = 1;
|
||||||
DescribePixelFormat(myDC, formats[i], sizeof(attributes), &attributes);
|
DescribePixelFormat(myDeviceContext, formats[i], sizeof(attributes), &attributes);
|
||||||
|
|
||||||
// Evaluate the current configuration
|
// Evaluate the current configuration
|
||||||
int color = attributes.cRedBits + attributes.cGreenBits + attributes.cBlueBits + attributes.cAlphaBits;
|
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);
|
descriptor.cStencilBits = static_cast<BYTE>(mySettings.StencilBits);
|
||||||
|
|
||||||
// Get the pixel format that best matches our requirements
|
// Get the pixel format that best matches our requirements
|
||||||
bestFormat = ChoosePixelFormat(myDC, &descriptor);
|
bestFormat = ChoosePixelFormat(myDeviceContext, &descriptor);
|
||||||
if (bestFormat == 0)
|
if (bestFormat == 0)
|
||||||
{
|
{
|
||||||
std::cerr << "Failed to find a suitable pixel format for device context -- cannot create OpenGL context" << std::endl;
|
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;
|
PIXELFORMATDESCRIPTOR actualFormat;
|
||||||
actualFormat.nSize = sizeof(actualFormat);
|
actualFormat.nSize = sizeof(actualFormat);
|
||||||
actualFormat.nVersion = 1;
|
actualFormat.nVersion = 1;
|
||||||
DescribePixelFormat(myDC, bestFormat, sizeof(actualFormat), &actualFormat);
|
DescribePixelFormat(myDeviceContext, bestFormat, sizeof(actualFormat), &actualFormat);
|
||||||
mySettings.DepthBits = actualFormat.cDepthBits;
|
mySettings.DepthBits = actualFormat.cDepthBits;
|
||||||
mySettings.StencilBits = actualFormat.cStencilBits;
|
mySettings.StencilBits = actualFormat.cStencilBits;
|
||||||
|
|
||||||
// Set the chosen pixel format
|
// 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;
|
std::cerr << "Failed to set pixel format for device context -- cannot create OpenGL context" << std::endl;
|
||||||
return;
|
return;
|
||||||
@ -279,13 +271,13 @@ void ContextWGL::CreateContext(ContextWGL* shared, unsigned int bitsPerPixel, co
|
|||||||
WGL_CONTEXT_MINOR_VERSION_ARB, 0,
|
WGL_CONTEXT_MINOR_VERSION_ARB, 0,
|
||||||
0, 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 the OpenGL 3.0 context failed, create a regular OpenGL 1.x context
|
||||||
if (!myContext)
|
if (!myContext)
|
||||||
{
|
{
|
||||||
myContext = wglCreateContext(myDC);
|
myContext = wglCreateContext(myDeviceContext);
|
||||||
if (!myContext)
|
if (!myContext)
|
||||||
{
|
{
|
||||||
std::cerr << "Failed to create an OpenGL context for this window" << std::endl;
|
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
|
// Share this context with others
|
||||||
if (sharedContext)
|
if (sharedContext)
|
||||||
{
|
{
|
||||||
|
// wglShareLists doesn't seem to be thread-safe
|
||||||
|
static Mutex mutex;
|
||||||
|
Lock lock(mutex);
|
||||||
|
|
||||||
if (!wglShareLists(sharedContext, myContext))
|
if (!wglShareLists(sharedContext, myContext))
|
||||||
std::cerr << "Failed to share the OpenGL context" << std::endl;
|
std::cerr << "Failed to share the OpenGL context" << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -70,15 +70,13 @@ public :
|
|||||||
~ContextWGL();
|
~ContextWGL();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Activate or deactivate the context as the current target
|
/// \brief Activate the context as the current target
|
||||||
/// for rendering
|
/// for rendering
|
||||||
///
|
///
|
||||||
/// \param active True to activate, false to deactivate
|
|
||||||
///
|
|
||||||
/// \return True on success, false if any error happened
|
/// \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
|
/// \brief Display what has been rendered to the context so far
|
||||||
@ -123,7 +121,7 @@ private :
|
|||||||
// Member data
|
// Member data
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
HWND myWindow; ///< Window to which the context is attached
|
HWND myWindow; ///< Window to which the context is attached
|
||||||
HDC myDC; ///< Device context of the window
|
HDC myDeviceContext; ///< Device context of the window
|
||||||
HGLRC myContext; ///< OpenGL context
|
HGLRC myContext; ///< OpenGL context
|
||||||
bool myOwnsWindow; ///< Did we create the host window?
|
bool myOwnsWindow; ///< Did we create the host window?
|
||||||
};
|
};
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/Window/Window.hpp>
|
#include <SFML/Window/Window.hpp>
|
||||||
#include <SFML/Window/ContextGL.hpp>
|
#include <SFML/Window/ContextGL.hpp>
|
||||||
#include <SFML/Window/Context.hpp>
|
|
||||||
#include <SFML/Window/WindowImpl.hpp>
|
#include <SFML/Window/WindowImpl.hpp>
|
||||||
#include <SFML/System/Sleep.hpp>
|
#include <SFML/System/Sleep.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -127,16 +126,9 @@ void Window::Create(VideoMode mode, const std::string& title, unsigned long styl
|
|||||||
style |= Style::Titlebar;
|
style |= Style::Titlebar;
|
||||||
|
|
||||||
// Recreate the window implementation
|
// Recreate the window implementation
|
||||||
delete myWindow;
|
|
||||||
myWindow = priv::WindowImpl::New(mode, title, style);
|
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
|
// Recreate the context
|
||||||
delete myContext;
|
|
||||||
myContext = priv::ContextGL::New(myWindow, mode.BitsPerPixel, settings);
|
myContext = priv::ContextGL::New(myWindow, mode.BitsPerPixel, settings);
|
||||||
|
|
||||||
// Perform common initializations
|
// 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)
|
void Window::Create(WindowHandle handle, const ContextSettings& settings)
|
||||||
{
|
{
|
||||||
// Recreate the window implementation
|
// Destroy the previous window implementation
|
||||||
Close();
|
Close();
|
||||||
|
|
||||||
|
// Recreate the window implementation
|
||||||
myWindow = priv::WindowImpl::New(handle);
|
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
|
// Recreate the context
|
||||||
delete myContext;
|
|
||||||
myContext = priv::ContextGL::New(myWindow, VideoMode::GetDesktopMode().BitsPerPixel, settings);
|
myContext = priv::ContextGL::New(myWindow, VideoMode::GetDesktopMode().BitsPerPixel, settings);
|
||||||
|
|
||||||
// Perform common initializations
|
// Perform common initializations
|
||||||
@ -325,6 +313,7 @@ bool Window::SetActive(bool active) const
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
std::cerr << "Trying to activate the window, but it doesn't have a valid context" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -349,11 +338,8 @@ void Window::Display()
|
|||||||
myClock.Reset();
|
myClock.Reset();
|
||||||
|
|
||||||
// Display the backbuffer on screen
|
// Display the backbuffer on screen
|
||||||
if (SetActive(true))
|
if (SetActive())
|
||||||
{
|
|
||||||
myContext->Display();
|
myContext->Display();
|
||||||
SetActive(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -435,7 +421,7 @@ void Window::Initialize()
|
|||||||
myLastFrameTime = 0.f;
|
myLastFrameTime = 0.f;
|
||||||
|
|
||||||
// Activate the window
|
// Activate the window
|
||||||
SetActive(true);
|
SetActive();
|
||||||
|
|
||||||
// Notify the derived class
|
// Notify the derived class
|
||||||
OnCreate();
|
OnCreate();
|
||||||
|
Loading…
Reference in New Issue
Block a user