Separated OpenGL contexts from Window implementations

Added support for OpenGL 3.0
Replaced WindowSettings with ContextSettings
Synchronized with trunk

git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1065 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
laurentgom 2009-03-28 16:22:58 +00:00
commit 9c370e38da
110 changed files with 2758 additions and 2335 deletions

View file

@ -51,6 +51,9 @@ mySamples (BufferSize)
////////////////////////////////////////////////////////////
Music::~Music()
{
// We must stop before destroying the file :)
Stop();
delete myFile;
}
@ -60,6 +63,9 @@ Music::~Music()
////////////////////////////////////////////////////////////
bool Music::OpenFromFile(const std::string& Filename)
{
// First stop the music if it was already running
Stop();
// Create the sound file implementation, and open it in read mode
delete myFile;
myFile = priv::SoundFile::CreateRead(Filename);
@ -84,6 +90,9 @@ bool Music::OpenFromFile(const std::string& Filename)
////////////////////////////////////////////////////////////
bool Music::OpenFromMemory(const char* Data, std::size_t SizeInBytes)
{
// First stop the music if it was already running
Stop();
// Create the sound file implementation, and open it in read mode
delete myFile;
myFile = priv::SoundFile::CreateRead(Data, SizeInBytes);
@ -108,7 +117,7 @@ bool Music::OpenFromMemory(const char* Data, std::size_t SizeInBytes)
////////////////////////////////////////////////////////////
bool Music::OnStart()
{
return myFile->Restart();
return myFile && myFile->Restart();
}
@ -117,12 +126,19 @@ bool Music::OnStart()
////////////////////////////////////////////////////////////
bool Music::OnGetData(SoundStream::Chunk& Data)
{
// Fill the chunk parameters
Data.Samples = &mySamples[0];
Data.NbSamples = myFile->Read(&mySamples[0], mySamples.size());
if (myFile)
{
// Fill the chunk parameters
Data.Samples = &mySamples[0];
Data.NbSamples = myFile->Read(&mySamples[0], mySamples.size());
// Check if we have reached the end of the audio file
return Data.NbSamples == mySamples.size();
// Check if we have reached the end of the audio file
return Data.NbSamples == mySamples.size();
}
else
{
return false;
}
}

View file

@ -26,7 +26,6 @@
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Audio/SoundStream.hpp>
#include <SFML/Audio/SoundBuffer.hpp>
#include <SFML/Audio/AudioDevice.hpp>
#include <SFML/Audio/OpenAL.hpp>
#include <SFML/System/Sleep.hpp>
@ -191,6 +190,7 @@ void SoundStream::Run()
{
// Create buffers
ALCheck(alGenBuffers(BuffersCount, myBuffers));
unsigned int EndBuffer = 0xFFFF;
// Fill the queue
bool RequestStop = FillQueue();
@ -203,37 +203,15 @@ void SoundStream::Run()
// The stream has been interrupted !
if (Sound::GetStatus() == Stopped)
{
// User requested to stop
if (RequestStop)
if (!RequestStop)
{
if (myLoop)
{
// The stream is in loop mode : restart it
if (OnStart())
{
mySamplesProcessed = 0;
ClearQueue();
RequestStop = FillQueue();
Sound::Play();
}
else
{
// Restart failed : finish the streaming loop
myIsStreaming = false;
break;
}
}
else
{
// The stream is not in loop mode : finish the streaming loop
myIsStreaming = false;
break;
}
// Just continue
Sound::Play();
}
else
{
// Streaming is not completed : restart the sound
Sound::Play();
// End streaming
myIsStreaming = false;
}
}
@ -241,20 +219,45 @@ void SoundStream::Run()
ALint NbProcessed;
ALCheck(alGetSourcei(Sound::mySource, AL_BUFFERS_PROCESSED, &NbProcessed));
while (NbProcessed-- && !RequestStop)
while (NbProcessed--)
{
// Pop the first unused buffer from the queue
ALuint Buffer;
ALCheck(alSourceUnqueueBuffers(Sound::mySource, 1, &Buffer));
// Retrieve its size and add it to the samples count
ALint Size;
ALCheck(alGetBufferi(Buffer, AL_SIZE, &Size));
mySamplesProcessed += Size / sizeof(Int16);
if (Buffer == EndBuffer)
{
// This was the last buffer: reset the sample count
mySamplesProcessed = 0;
EndBuffer = 0xFFFF;
}
else
{
ALint Size;
ALCheck(alGetBufferi(Buffer, AL_SIZE, &Size));
mySamplesProcessed += Size / sizeof(Int16);
}
// Fill it and push it back into the playing queue
if (FillAndPushBuffer(Buffer))
RequestStop = true;
if (!RequestStop)
{
if (FillAndPushBuffer(Buffer))
{
// User requested to stop: check if we must loop or really stop
if (myLoop && OnStart())
{
// Looping: mark the current buffer as the last one
// (to know when to reset the sample count)
EndBuffer = Buffer;
}
else
{
// Not looping or restart failed: request stop
RequestStop = true;
}
}
}
}
// Leave some time for the other threads if the stream is still playing
@ -269,6 +272,7 @@ void SoundStream::Run()
ClearQueue();
// Delete the buffers
ALCheck(alSourcei(Sound::mySource, AL_BUFFER, 0));
ALCheck(alDeleteBuffers(BuffersCount, myBuffers));
}
@ -324,7 +328,7 @@ bool SoundStream::FillQueue()
void SoundStream::ClearQueue()
{
// Get the number of buffers still in the queue
ALint NbQueued;
ALint NbQueued;
ALCheck(alGetSourcei(Sound::mySource, AL_BUFFERS_QUEUED, &NbQueued));
// Unqueue them all

View file

@ -382,7 +382,7 @@ void Drawable::Draw(RenderTarget& Target) const
switch (myBlendMode)
{
case Blend::Alpha : GLCheck(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); break;
case Blend::Add : GLCheck(glBlendFunc(GL_ONE, GL_ONE)); break;
case Blend::Add : GLCheck(glBlendFunc(GL_SRC_ALPHA, GL_ONE)); break;
case Blend::Multiply : GLCheck(glBlendFunc(GL_DST_COLOR, GL_ZERO)); break;
default : break;
}

View file

@ -65,7 +65,7 @@ GraphicsContext::GraphicsContext()
// Activate the global context
if (!Context::IsContextActive())
{
Context::GetGlobal().SetActive(true);
Context::GetDefault().SetActive(true);
myActivated = true;
}
else
@ -86,7 +86,7 @@ GraphicsContext::~GraphicsContext()
{
// Deactivate the global context
if (myActivated)
Context::GetGlobal().SetActive(false);
Context::GetDefault().SetActive(false);
}
} // namespace priv

View file

@ -267,7 +267,7 @@ void Image::CreateMaskFromColor(Color ColorKey, Uint8 Alpha)
/// This function does a slow pixel copy and should only
/// be used at initialization time
////////////////////////////////////////////////////////////
void Image::Copy(const Image& Source, unsigned int DestX, unsigned int DestY, const IntRect& SourceRect)
void Image::Copy(const Image& Source, unsigned int DestX, unsigned int DestY, const IntRect& SourceRect, bool ApplyAlpha)
{
// Make sure both images are valid
if ((Source.myWidth == 0) || (Source.myHeight == 0) || (myWidth == 0) || (myHeight == 0))
@ -313,11 +313,37 @@ void Image::Copy(const Image& Source, unsigned int DestX, unsigned int DestY, co
Uint8* DstPixels = reinterpret_cast<Uint8*>(&myPixels[0]) + (DestX + DestY * myWidth) * 4;
// Copy the pixels
for (int i = 0; i < Rows; ++i)
if (ApplyAlpha)
{
memcpy(DstPixels, SrcPixels, Pitch);
SrcPixels += SrcStride;
DstPixels += DstStride;
// Interpolation using alpha values, pixel by pixel (slower)
for (int i = 0; i < Rows; ++i)
{
for (int j = 0; j < Width; ++j)
{
// Get a direct pointer to the components of the current pixel
const Uint8* Src = SrcPixels + j * 4;
Uint8* Dst = DstPixels + j * 4;
// Interpolate RGB components using the alpha value of the source pixel
Uint8 Alpha = Src[3];
Dst[0] = (Src[0] * Alpha + Dst[0] * (255 - Alpha)) / 255;
Dst[1] = (Src[1] * Alpha + Dst[1] * (255 - Alpha)) / 255;
Dst[2] = (Src[2] * Alpha + Dst[2] * (255 - Alpha)) / 255;
}
SrcPixels += SrcStride;
DstPixels += DstStride;
}
}
else
{
// Optimized copy ignoring alpha values, row by row (faster)
for (int i = 0; i < Rows; ++i)
{
memcpy(DstPixels, SrcPixels, Pitch);
SrcPixels += SrcStride;
DstPixels += DstStride;
}
}
// The texture will need an update

View file

@ -46,18 +46,18 @@ RenderWindow::RenderWindow()
////////////////////////////////////////////////////////////
/// Construct the window
////////////////////////////////////////////////////////////
RenderWindow::RenderWindow(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, const WindowSettings& Params)
RenderWindow::RenderWindow(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, const ContextSettings& Settings)
{
Create(Mode, Title, WindowStyle, Params);
Create(Mode, Title, WindowStyle, Settings);
}
////////////////////////////////////////////////////////////
/// Construct the window from an existing control
////////////////////////////////////////////////////////////
RenderWindow::RenderWindow(WindowHandle Handle, const WindowSettings& Params)
RenderWindow::RenderWindow(WindowHandle Handle, const ContextSettings& Settings)
{
Create(Handle, Params);
Create(Handle, Settings);
}

View file

@ -0,0 +1,86 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Lucas Soltic (elmerod@gmail.com) and Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Config.hpp>
#ifdef SFML_SYSTEM_MACOS
#include <CoreFoundation/CoreFoundation.h>
#include <iostream>
#include <cstdio>
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
/// Under Mac OS X, when launching an application from the Finder,
/// the default working directory is the user home directory ;
/// when launching from Xcode, the default one is the directory
/// containing the application. In order to produce a uniform behaviour
/// and simplify the use of resources, SFML sets the working directory to
/// the Resources folder of the application bundle.
/// The "constructor" attribute forces the function to be called
/// at library loading time.
////////////////////////////////////////////////////////////
void InitializeWorkingDirectory(void) __attribute__ ((constructor));
void InitializeWorkingDirectory(void)
{
char PathBuffer[4096];
bool Encoded = false;
// Get the application bundle
CFBundleRef MainBundle = CFBundleGetMainBundle();
assert(MainBundle != NULL);
// Get the resource directory URL
CFURLRef ResourceDirectory = CFBundleCopyResourcesDirectoryURL(MainBundle);
assert(ResourceDirectory != NULL);
// Convert it as absolute URL
CFURLRef AbsoluteURL = CFURLCopyAbsoluteURL(ResourceDirectory);
assert(AbsoluteURL != NULL);
// Get the path as C string
Encoded = CFURLGetFileSystemRepresentation(AbsoluteURL, true, (UInt8 *)PathBuffer, 4096);
assert(Encoded);
// Set the working directory
chdir(PathBuffer);
CFRelease(AbsoluteURL);
CFRelease(ResourceDirectory);
}
} // namespace priv
} // namespace sf
#endif // SFML_SYSTEM_MACOS

View file

@ -78,7 +78,7 @@ namespace sf
////////////////////////////////////////////////////////////
// Static member data
////////////////////////////////////////////////////////////
const char Unicode::UTF8TrailingBytes[256] =
const int Unicode::UTF8TrailingBytes[256] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

View file

@ -26,62 +26,125 @@
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/Context.hpp>
#include <SFML/Window/WindowImpl.hpp>
#include <SFML/OpenGL.hpp>
#include <SFML/Window/glext/glext.h>
#include <stdlib.h>
namespace
{
// Make sure the dummy context is created at global startup
sf::Context& Dummy = sf::Context::GetGlobal();
}
#if defined(SFML_SYSTEM_WINDOWS)
#include <SFML/Window/Win32/ContextWGL.hpp>
typedef sf::priv::ContextWGL ContextType;
#elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD)
#include <SFML/Window/Linux/ContextGLX.hpp>
typedef sf::priv::ContextGLX ContextType;
#elif defined(SFML_SYSTEM_MACOS)
#include <SFML/Window/Cocoa/ContextAGL.hpp>
typedef sf::priv::ContextAGL ContextType;
#endif
namespace sf
{
////////////////////////////////////////////////////////////
/// Default constructor, create the context
/// Create a new context, not associated to a window
////////////////////////////////////////////////////////////
Context::Context()
Context* Context::New()
{
myDummyWindow = priv::WindowImpl::New();
ContextType* Shared = static_cast<ContextType*>(&GetDefault());
return new ContextType(Shared);
}
////////////////////////////////////////////////////////////
/// Destructor, destroy the context
/// Create a new context attached to a window
////////////////////////////////////////////////////////////
Context::~Context()
Context* Context::New(const priv::WindowImpl* Owner, unsigned int BitsPerPixel, const ContextSettings& Settings)
{
delete myDummyWindow;
ContextType* Shared = static_cast<ContextType*>(&GetDefault());
ContextType* NewContext = new ContextType(Shared, Owner, BitsPerPixel, Settings);
// Enable antialiasing if needed
if (NewContext->GetSettings().AntialiasingLevel > 0)
glEnable(GL_MULTISAMPLE_ARB);
return NewContext;
}
////////////////////////////////////////////////////////////
/// Activate or deactivate the context
////////////////////////////////////////////////////////////
void Context::SetActive(bool Active)
{
myDummyWindow->SetActive(Active);
}
////////////////////////////////////////////////////////////
/// Check if there's a context bound to the current thread
/// Check if a context is active on the current thread
////////////////////////////////////////////////////////////
bool Context::IsContextActive()
{
return priv::WindowImpl::IsContextActive();
return ContextType::IsContextActive();
}
////////////////////////////////////////////////////////////
/// Get the global context
/// Return the default context
////////////////////////////////////////////////////////////
Context& Context::GetGlobal()
Context& Context::GetDefault()
{
static Context* GlobalContext = new Context; // Never deleted, on purpose
static ContextType DefaultContext(NULL);
return *GlobalContext;
return DefaultContext;
}
////////////////////////////////////////////////////////////
/// Destructor
////////////////////////////////////////////////////////////
Context::~Context()
{
// Nothing to do
}
////////////////////////////////////////////////////////////
/// Get the settings of the context
////////////////////////////////////////////////////////////
const ContextSettings& Context::GetSettings() const
{
return mySettings;
}
////////////////////////////////////////////////////////////
/// Activate or deactivate the context as the current target
/// for rendering
////////////////////////////////////////////////////////////
bool Context::SetActive(bool Active)
{
return MakeCurrent(Active);
}
////////////////////////////////////////////////////////////
/// Default constructor
////////////////////////////////////////////////////////////
Context::Context()
{
}
////////////////////////////////////////////////////////////
/// Evaluate a pixel format configuration.
/// This functions can be used by implementations that have
/// several valid formats and want to get the best one
////////////////////////////////////////////////////////////
int Context::EvaluateFormat(unsigned int BitsPerPixel, const ContextSettings& Settings, int ColorBits, int DepthBits, int StencilBits, int Antialiasing)
{
return abs(static_cast<int>(BitsPerPixel - ColorBits)) +
abs(static_cast<int>(Settings.DepthBits - DepthBits)) +
abs(static_cast<int>(Settings.StencilBits - StencilBits)) +
abs(static_cast<int>(Settings.AntialiasingLevel - Antialiasing));
}
} // namespace sf

View file

@ -0,0 +1,313 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/Win32/ContextWGL.hpp>
#include <SFML/Window/WindowImpl.hpp>
#include <GL/gl.h>
#include <SFML/Window/glext/wglext.h>
#include <iostream>
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
/// Create a new context, not associated to a window
////////////////////////////////////////////////////////////
ContextWGL::ContextWGL(ContextWGL* Shared) :
myWindow (NULL),
myDC (NULL),
myContext (NULL),
myOwnsWindow(true)
{
// ------------ TEMP ------------
// 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);
// Create the context
if (myDC)
CreateContext(Shared, VideoMode::GetMode(0).BitsPerPixel, ContextSettings(0, 0, 0));
// ------------ TEMP ------------
}
////////////////////////////////////////////////////////////
/// Create a new context attached to a window
////////////////////////////////////////////////////////////
ContextWGL::ContextWGL(ContextWGL* Shared, const WindowImpl* Owner, unsigned int BitsPerPixel, const ContextSettings& Settings) :
myWindow (NULL),
myDC (NULL),
myContext (NULL),
myOwnsWindow(false)
{
// Get the owner window and its device context
myWindow = static_cast<HWND>(Owner->GetHandle());
myDC = GetDC(myWindow);
// Create the context
if (myDC)
CreateContext(Shared, BitsPerPixel, Settings);
}
////////////////////////////////////////////////////////////
/// Destructor
////////////////////////////////////////////////////////////
ContextWGL::~ContextWGL()
{
// Destroy the OpenGL context
if (myContext)
{
if (wglGetCurrentContext() == myContext)
wglMakeCurrent(NULL, NULL);
wglDeleteContext(myContext);
}
// Release the DC
if (myWindow && myDC)
ReleaseDC(myWindow, myDC);
// Destroy the window if we own it
if (myWindow && myOwnsWindow)
DestroyWindow(myWindow);
}
////////////////////////////////////////////////////////////
/// \see Context::MakeCurrent
////////////////////////////////////////////////////////////
bool ContextWGL::MakeCurrent(bool Active)
{
if (Active)
{
if (myDC && myContext)
{
if (wglGetCurrentContext() != myContext)
return wglMakeCurrent(myDC, myContext) != 0;
else
return true;
}
else
{
return false;
}
}
else
{
if (wglGetCurrentContext() == myContext)
return wglMakeCurrent(NULL, NULL) != 0;
else
return true;
}
}
////////////////////////////////////////////////////////////
/// \see Context::Display
////////////////////////////////////////////////////////////
void ContextWGL::Display()
{
if (myDC && myContext)
SwapBuffers(myDC);
}
////////////////////////////////////////////////////////////
/// \see Context::UseVerticalSync
////////////////////////////////////////////////////////////
void ContextWGL::UseVerticalSync(bool Enabled)
{
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = reinterpret_cast<PFNWGLSWAPINTERVALEXTPROC>(wglGetProcAddress("wglSwapIntervalEXT"));
if (wglSwapIntervalEXT)
wglSwapIntervalEXT(Enabled ? 1 : 0);
}
////////////////////////////////////////////////////////////
/// Check if a context is active on the current thread
////////////////////////////////////////////////////////////
bool ContextWGL::IsContextActive()
{
return wglGetCurrentContext() != NULL;
}
////////////////////////////////////////////////////////////
/// Create the context
////////////////////////////////////////////////////////////
void ContextWGL::CreateContext(ContextWGL* Shared, unsigned int BitsPerPixel, const ContextSettings& Settings)
{
// Save the creation settings
mySettings = Settings;
// Let's find a suitable pixel format -- first try with antialiasing
int BestFormat = 0;
if (mySettings.AntialiasingLevel > 0)
{
// Get the wglChoosePixelFormatARB function (it is an extension)
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = reinterpret_cast<PFNWGLCHOOSEPIXELFORMATARBPROC>(wglGetProcAddress("wglChoosePixelFormatARB"));
// Define the basic attributes we want for our window
int IntAttributes[] =
{
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
WGL_SAMPLE_BUFFERS_ARB, (mySettings.AntialiasingLevel ? GL_TRUE : GL_FALSE),
WGL_SAMPLES_ARB, mySettings.AntialiasingLevel,
0, 0
};
// Let's check how many formats are supporting our requirements
int Formats[128];
UINT NbFormats;
float FloatAttributes[] = {0, 0};
bool IsValid = wglChoosePixelFormatARB(myDC, IntAttributes, FloatAttributes, sizeof(Formats) / sizeof(*Formats), Formats, &NbFormats) != 0;
if (!IsValid || (NbFormats == 0))
{
if (mySettings.AntialiasingLevel > 2)
{
// No format matching our needs : reduce the multisampling level
std::cerr << "Failed to find a pixel format supporting "
<< 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;
}
if (!IsValid || (NbFormats == 0))
{
// Cannot find any pixel format supporting multisampling ; disabling antialiasing
std::cerr << "Failed to find a pixel format supporting antialiasing ; antialiasing will be disabled" << std::endl;
mySettings.AntialiasingLevel = 0;
}
}
// Get the best format among the returned ones
if (IsValid && (NbFormats > 0))
{
int BestScore = 0xFFFF;
for (UINT i = 0; i < NbFormats; ++i)
{
// Get the current format's attributes
PIXELFORMATDESCRIPTOR Attribs;
Attribs.nSize = sizeof(PIXELFORMATDESCRIPTOR);
Attribs.nVersion = 1;
DescribePixelFormat(myDC, Formats[i], sizeof(PIXELFORMATDESCRIPTOR), &Attribs);
// Evaluate the current configuration
int Color = Attribs.cRedBits + Attribs.cGreenBits + Attribs.cBlueBits + Attribs.cAlphaBits;
int Score = EvaluateFormat(BitsPerPixel, mySettings, Color, Attribs.cDepthBits, Attribs.cStencilBits, mySettings.AntialiasingLevel);
// Keep it if it's better than the current best
if (Score < BestScore)
{
BestScore = Score;
BestFormat = Formats[i];
}
}
}
}
// Find a pixel format with no antialiasing, if not needed or not supported
if (BestFormat == 0)
{
// Setup a pixel format descriptor from the rendering settings
PIXELFORMATDESCRIPTOR PixelDescriptor;
ZeroMemory(&PixelDescriptor, sizeof(PIXELFORMATDESCRIPTOR));
PixelDescriptor.nSize = sizeof(PIXELFORMATDESCRIPTOR);
PixelDescriptor.nVersion = 1;
PixelDescriptor.iLayerType = PFD_MAIN_PLANE;
PixelDescriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
PixelDescriptor.iPixelType = PFD_TYPE_RGBA;
PixelDescriptor.cColorBits = static_cast<BYTE>(BitsPerPixel);
PixelDescriptor.cDepthBits = static_cast<BYTE>(mySettings.DepthBits);
PixelDescriptor.cStencilBits = static_cast<BYTE>(mySettings.StencilBits);
// Get the pixel format that best matches our requirements
BestFormat = ChoosePixelFormat(myDC, &PixelDescriptor);
if (BestFormat == 0)
{
std::cerr << "Failed to find a suitable pixel format for device context -- cannot create OpenGL context" << std::endl;
return;
}
}
// Extract the depth and stencil bits from the chosen format
PIXELFORMATDESCRIPTOR ActualFormat;
ActualFormat.nSize = sizeof(PIXELFORMATDESCRIPTOR);
ActualFormat.nVersion = 1;
DescribePixelFormat(myDC, BestFormat, sizeof(PIXELFORMATDESCRIPTOR), &ActualFormat);
mySettings.DepthBits = ActualFormat.cDepthBits;
mySettings.StencilBits = ActualFormat.cStencilBits;
// Set the chosen pixel format
if (!SetPixelFormat(myDC, BestFormat, &ActualFormat))
{
std::cerr << "Failed to set pixel format for device context -- cannot create OpenGL context" << std::endl;
return;
}
// Get the context to share display lists with
HGLRC SharedContext = Shared ? Shared->myContext : NULL;
// Create the OpenGL context -- first try an OpenGL 3.0 context if it is supported
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = reinterpret_cast<PFNWGLCREATECONTEXTATTRIBSARBPROC>(wglGetProcAddress("wglCreateContextAttribsARB"));
if (wglCreateContextAttribsARB)
{
int Attributes[] =
{
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
WGL_CONTEXT_MINOR_VERSION_ARB, 0,
0, 0
};
myContext = wglCreateContextAttribsARB(myDC, SharedContext, Attributes);
}
// If the OpenGL 3.0 context failed, create a regular OpenGL 1.x context
if (!myContext)
{
myContext = wglCreateContext(myDC);
if (!myContext)
{
std::cerr << "Failed to create an OpenGL context for this window" << std::endl;
return;
}
// Share this context with others
if (SharedContext)
wglShareLists(SharedContext, myContext);
}
}
} // namespace priv
} // namespace sf

View file

@ -0,0 +1,122 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_CONTEXTWGL_HPP
#define SFML_CONTEXTWGL_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/Context.hpp>
#include <windows.h>
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
/// Windows (WGL) implementation of OpenGL contexts
////////////////////////////////////////////////////////////
class ContextWGL : public Context
{
public :
////////////////////////////////////////////////////////////
/// Create a new context, not associated to a window
///
/// \param Shared : Context to share the new one with (can be NULL)
///
////////////////////////////////////////////////////////////
ContextWGL(ContextWGL* Shared);
////////////////////////////////////////////////////////////
/// Create a new context attached to a window
///
/// \param Shared : Context to share the new one with (can be NULL)
/// \param Owner : Pointer to the owner window
/// \param BitsPerPixel : Pixel depth (in bits per pixel)
/// \param Settings : Creation parameters
///
////////////////////////////////////////////////////////////
ContextWGL(ContextWGL* Shared, const WindowImpl* Owner, unsigned int BitsPerPixel, const ContextSettings& Settings);
////////////////////////////////////////////////////////////
/// Destructor
///
////////////////////////////////////////////////////////////
~ContextWGL();
////////////////////////////////////////////////////////////
/// \see Context::MakeCurrent
///
////////////////////////////////////////////////////////////
virtual bool MakeCurrent(bool Active);
////////////////////////////////////////////////////////////
/// \see Context::Display
///
////////////////////////////////////////////////////////////
virtual void Display();
////////////////////////////////////////////////////////////
/// \see Context::UseVerticalSync
///
////////////////////////////////////////////////////////////
virtual void UseVerticalSync(bool Enabled);
////////////////////////////////////////////////////////////
/// Check if a context is active on the current thread
///
/// \return True if there's an active context, false otherwise
///
////////////////////////////////////////////////////////////
static bool IsContextActive();
private :
////////////////////////////////////////////////////////////
/// Create the context
///
/// \param Shared : Context to share the new one with (can be NULL)
/// \param BitsPerPixel : Pixel depth, in bits per pixel
/// \param Settings : Creation parameters
///
////////////////////////////////////////////////////////////
void CreateContext(ContextWGL* Shared, unsigned int BitsPerPixel, const ContextSettings& Settings);
////////////////////////////////////////////////////////////
// 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?
};
} // namespace priv
} // namespace sf
#endif // SFML_CONTEXTWGL_HPP

View file

@ -28,7 +28,6 @@
#define _WIN32_WINDOWS 0x0501
#define _WIN32_WINNT 0x0501
#include <SFML/Window/Win32/WindowImplWin32.hpp>
#include <SFML/Window/WindowSettings.hpp>
#include <SFML/Window/WindowStyle.hpp>
#include <GL/gl.h>
#include <SFML/Window/glext/wglext.h>
@ -58,53 +57,10 @@ const wchar_t* WindowImplWin32::ourClassNameW = L"SFML_Window";
WindowImplWin32* WindowImplWin32::ourFullscreenWindow = NULL;
////////////////////////////////////////////////////////////
/// Default constructor
/// (creates a dummy window to provide a valid OpenGL context)
////////////////////////////////////////////////////////////
WindowImplWin32::WindowImplWin32() :
myHandle (NULL),
myCallback (0),
myCursor (NULL),
myIcon (NULL),
myKeyRepeatEnabled(true),
myIsCursorIn (false)
{
// Register the window class at first call
if (ourWindowCount == 0)
RegisterWindowClass();
// Use small dimensions
myWidth = 1;
myHeight = 1;
// Create a dummy window (disabled and hidden)
if (HasUnicodeSupport())
{
myHandle = CreateWindowW(ourClassNameW, L"", WS_POPUP | WS_DISABLED, 0, 0, myWidth, myHeight, NULL, NULL, GetModuleHandle(NULL), NULL);
}
else
{
myHandle = CreateWindowA(ourClassNameA, "", WS_POPUP | WS_DISABLED, 0, 0, myWidth, myHeight, NULL, NULL, GetModuleHandle(NULL), NULL);
}
ShowWindow(myHandle, SW_HIDE);
// Create the rendering context
if (myHandle)
{
WindowSettings Params(0, 0, 0);
CreateContext(VideoMode(myWidth, myHeight, 32), Params);
// Don't activate by default
SetActive(false);
}
}
////////////////////////////////////////////////////////////
/// Create the window implementation from an existing control
////////////////////////////////////////////////////////////
WindowImplWin32::WindowImplWin32(WindowHandle Handle, WindowSettings& Params) :
WindowImplWin32::WindowImplWin32(WindowHandle Handle) :
myHandle (NULL),
myCallback (0),
myCursor (NULL),
@ -123,10 +79,6 @@ myIsCursorIn (false)
myWidth = Rect.right - Rect.left;
myHeight = Rect.bottom - Rect.top;
// Create the rendering context
VideoMode Mode(myWidth, myHeight, VideoMode::GetDesktopMode().BitsPerPixel);
CreateContext(Mode, Params);
// We change the event procedure of the control (it is important to save the old one)
SetWindowLongPtr(myHandle, GWLP_USERDATA, reinterpret_cast<long>(this));
myCallback = SetWindowLongPtr(myHandle, GWLP_WNDPROC, reinterpret_cast<long>(&WindowImplWin32::GlobalOnEvent));
@ -137,7 +89,7 @@ myIsCursorIn (false)
////////////////////////////////////////////////////////////
/// Create the window implementation
////////////////////////////////////////////////////////////
WindowImplWin32::WindowImplWin32(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, WindowSettings& Params) :
WindowImplWin32::WindowImplWin32(VideoMode Mode, const std::string& Title, unsigned long WindowStyle) :
myHandle (NULL),
myCallback (0),
myCursor (NULL),
@ -195,10 +147,6 @@ myIsCursorIn (false)
if (Fullscreen)
SwitchToFullscreen(Mode);
// Create the rendering context
if (myHandle)
CreateContext(Mode, Params);
// Increment window count
ourWindowCount++;
@ -251,11 +199,11 @@ WindowImplWin32::~WindowImplWin32()
////////////////////////////////////////////////////////////
/// Check if there's an active context on the current thread
/// /see WindowImpl::GetHandle
////////////////////////////////////////////////////////////
bool WindowImplWin32::IsContextActive()
WindowHandle WindowImplWin32::GetHandle() const
{
return wglGetCurrentContext() != NULL;
return myHandle;
}
@ -277,45 +225,6 @@ void WindowImplWin32::ProcessEvents()
}
////////////////////////////////////////////////////////////
/// /see WindowImpl::Display
////////////////////////////////////////////////////////////
void WindowImplWin32::Display()
{
if (myDeviceContext && myGLContext)
SwapBuffers(myDeviceContext);
}
////////////////////////////////////////////////////////////
/// /see WindowImpl::SetActive
////////////////////////////////////////////////////////////
void WindowImplWin32::SetActive(bool Active) const
{
if (Active)
{
if (myDeviceContext && myGLContext && (wglGetCurrentContext() != myGLContext))
wglMakeCurrent(myDeviceContext, myGLContext);
}
else
{
if (wglGetCurrentContext() == myGLContext)
wglMakeCurrent(NULL, NULL);
}
}
////////////////////////////////////////////////////////////
/// /see WindowImpl::UseVerticalSync
////////////////////////////////////////////////////////////
void WindowImplWin32::UseVerticalSync(bool Enabled)
{
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = reinterpret_cast<PFNWGLSWAPINTERVALEXTPROC>(wglGetProcAddress("wglSwapIntervalEXT"));
if (wglSwapIntervalEXT)
wglSwapIntervalEXT(Enabled ? 1 : 0);
}
////////////////////////////////////////////////////////////
/// /see WindowImpl::ShowMouseCursor
////////////////////////////////////////////////////////////
@ -355,6 +264,13 @@ void WindowImplWin32::SetPosition(int Left, int Top)
////////////////////////////////////////////////////////////
void WindowImplWin32::SetSize(unsigned int Width, unsigned int Height)
{
// SetWindowPos wants the total size of the window (including title bar and borders),
// so we have to compute it
RECT Rect = {0, 0, Width, Height};
AdjustWindowRect(&Rect, GetWindowLong(myHandle, GWL_STYLE), false);
Width = Rect.right - Rect.left;
Height = Rect.bottom - Rect.top;
SetWindowPos(myHandle, NULL, 0, 0, Width, Height, SWP_NOMOVE | SWP_NOZORDER);
}
@ -486,150 +402,6 @@ void WindowImplWin32::SwitchToFullscreen(const VideoMode& Mode)
}
////////////////////////////////////////////////////////////
/// Construct the context from graphics settings
////////////////////////////////////////////////////////////
void WindowImplWin32::CreateContext(const VideoMode& Mode, WindowSettings& Params)
{
// Get the device context attached to the window
myDeviceContext = GetDC(myHandle);
if (myDeviceContext == NULL)
{
std::cerr << "Failed to get device context of window -- cannot create OpenGL context" << std::endl;
return;
}
// Let's find a suitable pixel format -- first try with antialiasing
int BestFormat = 0;
if (Params.AntialiasingLevel > 0)
{
// Get the wglChoosePixelFormatARB function (it is an extension)
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = reinterpret_cast<PFNWGLCHOOSEPIXELFORMATARBPROC>(wglGetProcAddress("wglChoosePixelFormatARB"));
// Define the basic attributes we want for our window
int IntAttributes[] =
{
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
WGL_SAMPLE_BUFFERS_ARB, (Params.AntialiasingLevel ? GL_TRUE : GL_FALSE),
WGL_SAMPLES_ARB, Params.AntialiasingLevel,
0, 0
};
// Let's check how many formats are supporting our requirements
int Formats[128];
UINT NbFormats;
float FloatAttributes[] = {0, 0};
bool IsValid = wglChoosePixelFormatARB(myDeviceContext, IntAttributes, FloatAttributes, sizeof(Formats) / sizeof(*Formats), Formats, &NbFormats) != 0;
if (!IsValid || (NbFormats == 0))
{
if (Params.AntialiasingLevel > 2)
{
// No format matching our needs : reduce the multisampling level
std::cerr << "Failed to find a pixel format supporting "
<< Params.AntialiasingLevel << " antialiasing levels ; trying with 2 levels" << std::endl;
Params.AntialiasingLevel = IntAttributes[1] = 2;
IsValid = wglChoosePixelFormatARB(myDeviceContext, IntAttributes, FloatAttributes, sizeof(Formats) / sizeof(*Formats), Formats, &NbFormats) != 0;
}
if (!IsValid || (NbFormats == 0))
{
// Cannot find any pixel format supporting multisampling ; disabling antialiasing
std::cerr << "Failed to find a pixel format supporting antialiasing ; antialiasing will be disabled" << std::endl;
Params.AntialiasingLevel = 0;
}
}
// Get the best format among the returned ones
if (IsValid && (NbFormats > 0))
{
int BestScore = 0xFFFF;
for (UINT i = 0; i < NbFormats; ++i)
{
// Get the current format's attributes
PIXELFORMATDESCRIPTOR Attribs;
Attribs.nSize = sizeof(PIXELFORMATDESCRIPTOR);
Attribs.nVersion = 1;
DescribePixelFormat(myDeviceContext, Formats[i], sizeof(PIXELFORMATDESCRIPTOR), &Attribs);
// Evaluate the current configuration
int Color = Attribs.cRedBits + Attribs.cGreenBits + Attribs.cBlueBits + Attribs.cAlphaBits;
int Score = EvaluateConfig(Mode, Params, Color, Attribs.cDepthBits, Attribs.cStencilBits, Params.AntialiasingLevel);
// Keep it if it's better than the current best
if (Score < BestScore)
{
BestScore = Score;
BestFormat = Formats[i];
}
}
}
}
// Find a pixel format with no antialiasing, if not needed or not supported
if (BestFormat == 0)
{
// Setup a pixel format descriptor from the rendering settings
PIXELFORMATDESCRIPTOR PixelDescriptor;
ZeroMemory(&PixelDescriptor, sizeof(PIXELFORMATDESCRIPTOR));
PixelDescriptor.nSize = sizeof(PIXELFORMATDESCRIPTOR);
PixelDescriptor.nVersion = 1;
PixelDescriptor.iLayerType = PFD_MAIN_PLANE;
PixelDescriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
PixelDescriptor.iPixelType = PFD_TYPE_RGBA;
PixelDescriptor.cColorBits = static_cast<BYTE>(Mode.BitsPerPixel);
PixelDescriptor.cDepthBits = static_cast<BYTE>(Params.DepthBits);
PixelDescriptor.cStencilBits = static_cast<BYTE>(Params.StencilBits);
// Get the pixel format that best matches our requirements
BestFormat = ChoosePixelFormat(myDeviceContext, &PixelDescriptor);
if (BestFormat == 0)
{
std::cerr << "Failed to find a suitable pixel format for device context -- cannot create OpenGL context" << std::endl;
return;
}
}
// Extract the depth and stencil bits from the chosen format
PIXELFORMATDESCRIPTOR ActualFormat;
ActualFormat.nSize = sizeof(PIXELFORMATDESCRIPTOR);
ActualFormat.nVersion = 1;
DescribePixelFormat(myDeviceContext, BestFormat, sizeof(PIXELFORMATDESCRIPTOR), &ActualFormat);
Params.DepthBits = ActualFormat.cDepthBits;
Params.StencilBits = ActualFormat.cStencilBits;
// Set the chosen pixel format
if (!SetPixelFormat(myDeviceContext, BestFormat, &ActualFormat))
{
std::cerr << "Failed to set pixel format for device context -- cannot create OpenGL context" << std::endl;
return;
}
// Create the OpenGL context from the device context
myGLContext = wglCreateContext(myDeviceContext);
if (myGLContext == NULL)
{
std::cerr << "Failed to create an OpenGL context for this window" << std::endl;
return;
}
// Share display lists with other contexts
HGLRC CurrentContext = wglGetCurrentContext();
if (CurrentContext)
wglShareLists(CurrentContext, myGLContext);
// Activate the context
SetActive(true);
// Enable multisampling
if (Params.AntialiasingLevel > 0)
glEnable(GL_MULTISAMPLE_ARB);
}
////////////////////////////////////////////////////////////
/// Free all the graphical resources attached to the window
////////////////////////////////////////////////////////////
@ -644,21 +416,6 @@ void WindowImplWin32::Cleanup()
// Unhide the mouse cursor (in case it was hidden)
ShowMouseCursor(true);
// Destroy the OpenGL context
if (myGLContext)
{
// Unbind the context before destroying it
SetActive(false);
wglDeleteContext(myGLContext);
myGLContext = NULL;
}
if (myDeviceContext)
{
ReleaseDC(myHandle, myDeviceContext);
myDeviceContext = NULL;
}
}

View file

@ -45,21 +45,13 @@ class WindowImplWin32 : public WindowImpl
{
public :
////////////////////////////////////////////////////////////
/// Default constructor
/// (creates a dummy window to provide a valid OpenGL context)
///
////////////////////////////////////////////////////////////
WindowImplWin32();
////////////////////////////////////////////////////////////
/// Construct the window implementation from an existing control
///
/// \param Handle : Platform-specific handle of the control
/// \param Params : Creation settings
///
////////////////////////////////////////////////////////////
WindowImplWin32(WindowHandle Handle, WindowSettings& Params);
WindowImplWin32(WindowHandle Handle);
////////////////////////////////////////////////////////////
/// Create the window implementation
@ -67,10 +59,9 @@ public :
/// \param Mode : Video mode to use
/// \param Title : Title of the window
/// \param WindowStyle : Window style
/// \param Params : Creation settings
///
////////////////////////////////////////////////////////////
WindowImplWin32(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, WindowSettings& Params);
WindowImplWin32(VideoMode Mode, const std::string& Title, unsigned long WindowStyle);
////////////////////////////////////////////////////////////
/// Destructor
@ -78,40 +69,20 @@ public :
////////////////////////////////////////////////////////////
~WindowImplWin32();
////////////////////////////////////////////////////////////
/// Check if there's an active context on the current thread
///
/// \return True if there's a context bound to the current thread
///
////////////////////////////////////////////////////////////
static bool IsContextActive();
private :
////////////////////////////////////////////////////////////
/// /see WindowImpl::GetHandle
///
////////////////////////////////////////////////////////////
virtual WindowHandle GetHandle() const;
////////////////////////////////////////////////////////////
/// /see WindowImpl::ProcessEvents
///
////////////////////////////////////////////////////////////
virtual void ProcessEvents();
////////////////////////////////////////////////////////////
/// /see WindowImpl::Display
///
////////////////////////////////////////////////////////////
virtual void Display();
////////////////////////////////////////////////////////////
/// /see WindowImpl::SetActive
///
////////////////////////////////////////////////////////////
virtual void SetActive(bool Active = true) const;
////////////////////////////////////////////////////////////
/// /see WindowImpl::UseVerticalSync
///
////////////////////////////////////////////////////////////
virtual void UseVerticalSync(bool Enabled);
////////////////////////////////////////////////////////////
/// /see WindowImpl::ShowMouseCursor
///
@ -168,15 +139,6 @@ private :
////////////////////////////////////////////////////////////
void SwitchToFullscreen(const VideoMode& Mode);
////////////////////////////////////////////////////////////
/// Construct the context from graphics settings
///
/// \param Mode : Video mode
/// \param Params : Creation settings
///
////////////////////////////////////////////////////////////
void CreateContext(const VideoMode& Mode, WindowSettings& Params);
////////////////////////////////////////////////////////////
/// Free all the graphical resources attached to the window
///
@ -249,14 +211,12 @@ private :
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
HWND myHandle; ///< Win32 handle of the window
long myCallback; ///< Stores the original event callback function of the control
HCURSOR myCursor; ///< The system cursor to display into the window
HICON myIcon; ///< Custom icon assigned to the window
bool myKeyRepeatEnabled; ///< Automatic key-repeat state for keydown events
bool myIsCursorIn; ///< Is the mouse cursor in the window's area ?
HDC myDeviceContext; ///< HDC associated to the window
HGLRC myGLContext; ///< OpenGL rendering context associated to the HDC
HWND myHandle; ///< Win32 handle of the window
long myCallback; ///< Stores the original event callback function of the control
HCURSOR myCursor; ///< The system cursor to display into the window
HICON myIcon; ///< Custom icon assigned to the window
bool myKeyRepeatEnabled; ///< Automatic key-repeat state for keydown events
bool myIsCursorIn; ///< Is the mouse cursor in the window's area ?
};
} // namespace priv

View file

@ -40,6 +40,7 @@ namespace sf
////////////////////////////////////////////////////////////
Window::Window() :
myWindow (NULL),
myContext (NULL),
myLastFrameTime (0.f),
myIsExternal (false),
myFramerateLimit(0),
@ -53,30 +54,32 @@ mySetCursorPosY (0xFFFF)
////////////////////////////////////////////////////////////
/// Construct a new window
////////////////////////////////////////////////////////////
Window::Window(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, const WindowSettings& Params) :
Window::Window(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, const ContextSettings& Settings) :
myWindow (NULL),
myContext (NULL),
myLastFrameTime (0.f),
myIsExternal (false),
myFramerateLimit(0),
mySetCursorPosX (0xFFFF),
mySetCursorPosY (0xFFFF)
{
Create(Mode, Title, WindowStyle, Params);
Create(Mode, Title, WindowStyle, Settings);
}
////////////////////////////////////////////////////////////
/// Construct the window from an existing control
////////////////////////////////////////////////////////////
Window::Window(WindowHandle Handle, const WindowSettings& Params) :
Window::Window(WindowHandle Handle, const ContextSettings& Settings) :
myWindow (NULL),
myContext (NULL),
myLastFrameTime (0.f),
myIsExternal (true),
myFramerateLimit(0),
mySetCursorPosX (0xFFFF),
mySetCursorPosY (0xFFFF)
{
Create(Handle, Params);
Create(Handle, Settings);
}
@ -85,7 +88,6 @@ mySetCursorPosY (0xFFFF)
////////////////////////////////////////////////////////////
Window::~Window()
{
// Close the window
Close();
}
@ -93,7 +95,7 @@ Window::~Window()
////////////////////////////////////////////////////////////
/// Create the window
////////////////////////////////////////////////////////////
void Window::Create(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, const WindowSettings& Params)
void Window::Create(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, const ContextSettings& Settings)
{
// Check validity of video mode
if ((WindowStyle & Style::Fullscreen) && !Mode.IsValid())
@ -106,30 +108,42 @@ void Window::Create(VideoMode Mode, const std::string& Title, unsigned long Wind
if ((WindowStyle & Style::Close) || (WindowStyle & Style::Resize))
WindowStyle |= Style::Titlebar;
// Destroy the previous window implementation
// Recreate the window implementation
delete myWindow;
myWindow = priv::WindowImpl::New(Mode, Title, WindowStyle);
// Activate the global context
Context::GetGlobal().SetActive(true);
// 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::GetDefault().SetActive(true);
mySettings = Params;
Initialize(priv::WindowImpl::New(Mode, Title, WindowStyle, mySettings));
// Recreate the context
delete myContext;
myContext = Context::New(myWindow, Mode.BitsPerPixel, Settings);
Initialize();
}
////////////////////////////////////////////////////////////
/// Create the window from an existing control
////////////////////////////////////////////////////////////
void Window::Create(WindowHandle Handle, const WindowSettings& Params)
void Window::Create(WindowHandle Handle, const ContextSettings& Settings)
{
// Destroy the previous window implementation
// Recreate the window implementation
delete myWindow;
myWindow = priv::WindowImpl::New(Handle);
// Activate the global context
Context::GetGlobal().SetActive(true);
// 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::GetDefault().SetActive(true);
mySettings = Params;
Initialize(priv::WindowImpl::New(Handle, mySettings));
// Recreate the context
delete myContext;
myContext = Context::New(myWindow, VideoMode::GetDesktopMode().BitsPerPixel, Settings);
Initialize();
}
@ -140,9 +154,22 @@ void Window::Create(WindowHandle Handle, const WindowSettings& Params)
////////////////////////////////////////////////////////////
void Window::Close()
{
// Delete the window implementation
delete myWindow;
myWindow = NULL;
if (myContext)
{
// Make sure that our context is no longer bound
Context::GetDefault().SetActive(true);
// Delete the context
delete myContext;
myContext = NULL;
}
if (myWindow)
{
// Delete the window implementation
delete myWindow;
myWindow = NULL;
}
}
@ -178,9 +205,11 @@ unsigned int Window::GetHeight() const
////////////////////////////////////////////////////////////
/// Get the creation settings of the window
////////////////////////////////////////////////////////////
const WindowSettings& Window::GetSettings() const
const ContextSettings& Window::GetSettings() const
{
return mySettings;
static ContextSettings EmptySettings(0, 0, 0);
return myContext ? myContext->GetSettings() : EmptySettings;
}
@ -212,7 +241,7 @@ bool Window::GetEvent(Event& EventReceived)
void Window::UseVerticalSync(bool Enabled)
{
if (SetActive())
myWindow->UseVerticalSync(Enabled);
myContext->UseVerticalSync(Enabled);
}
@ -247,15 +276,8 @@ void Window::SetCursorPosition(unsigned int Left, unsigned int Top)
////////////////////////////////////////////////////////////
void Window::SetPosition(int Left, int Top)
{
if (!myIsExternal)
{
if (myWindow)
myWindow->SetPosition(Left, Top);
}
else
{
std::cerr << "Warning : trying to change the position of an external SFML window, which is not allowed" << std::endl;
}
if (myWindow)
myWindow->SetPosition(Left, Top);
}
@ -274,11 +296,8 @@ void Window::SetSize(unsigned int Width, unsigned int Height)
////////////////////////////////////////////////////////////
void Window::Show(bool State)
{
if (!myIsExternal)
{
if (myWindow)
myWindow->Show(State);
}
if (myWindow)
myWindow->Show(State);
}
@ -304,18 +323,27 @@ void Window::SetIcon(unsigned int Width, unsigned int Height, const Uint8* Pixel
////////////////////////////////////////////////////////////
/// Activate of deactivate the window as the current target
/// Activate or deactivate the window as the current target
/// for rendering
////////////////////////////////////////////////////////////
bool Window::SetActive(bool Active) const
{
if (myWindow)
if (myContext)
{
myWindow->SetActive(Active);
return true;
if (myContext->SetActive(Active))
{
return true;
}
else
{
std::cerr << "Failed to activate the window's context" << std::endl;
return false;
}
}
else
{
return false;
}
return false;
}
@ -338,7 +366,7 @@ void Window::Display()
// Display the backbuffer on screen
if (SetActive())
myWindow->Display();
myContext->Display();
}
@ -409,14 +437,10 @@ void Window::OnEvent(const Event& EventReceived)
////////////////////////////////////////////////////////////
/// Initialize internal window
/// Do some common internal initializations
////////////////////////////////////////////////////////////
void Window::Initialize(priv::WindowImpl* Window)
void Window::Initialize()
{
// Assign and initialize the new window
myWindow = Window;
myWindow->Initialize();
// Listen to events from the new window
myWindow->AddListener(this);
myWindow->AddListener(&myInput);

View file

@ -56,27 +56,18 @@ namespace priv
////////////////////////////////////////////////////////////
/// Create a new window depending on the current OS
////////////////////////////////////////////////////////////
WindowImpl* WindowImpl::New()
WindowImpl* WindowImpl::New(VideoMode Mode, const std::string& Title, unsigned long WindowStyle)
{
return new WindowImplType();
return new WindowImplType(Mode, Title, WindowStyle);
}
////////////////////////////////////////////////////////////
/// Create a new window depending on the current OS
////////////////////////////////////////////////////////////
WindowImpl* WindowImpl::New(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, WindowSettings& Params)
WindowImpl* WindowImpl::New(WindowHandle Handle)
{
return new WindowImplType(Mode, Title, WindowStyle, Params);
}
////////////////////////////////////////////////////////////
/// Create a new window depending on the current OS
////////////////////////////////////////////////////////////
WindowImpl* WindowImpl::New(WindowHandle Handle, WindowSettings& Params)
{
return new WindowImplType(Handle, Params);
return new WindowImplType(Handle);
}
@ -88,6 +79,12 @@ myWidth (0),
myHeight (0),
myJoyThreshold(0.1f)
{
// Initialize the joysticks
for (unsigned int i = 0; i < JoysticksCount; ++i)
{
myJoysticks[i].Initialize(i);
myJoyStates[i] = myJoysticks[i].UpdateState();
}
}
@ -119,20 +116,6 @@ void WindowImpl::RemoveListener(WindowListener* Listener)
}
////////////////////////////////////////////////////////////
/// Initialize window's states that can't be done at construction
////////////////////////////////////////////////////////////
void WindowImpl::Initialize()
{
// Initialize the joysticks
for (unsigned int i = 0; i < JoysticksCount; ++i)
{
myJoysticks[i].Initialize(i);
myJoyStates[i] = myJoysticks[i].UpdateState();
}
}
////////////////////////////////////////////////////////////
/// Get the client width of the window
////////////////////////////////////////////////////////////
@ -174,15 +157,6 @@ void WindowImpl::DoEvents()
}
////////////////////////////////////////////////////////////
/// Check if there's an active context on the current thread
////////////////////////////////////////////////////////////
bool WindowImpl::IsContextActive()
{
return WindowImplType::IsContextActive();
}
////////////////////////////////////////////////////////////
/// Send an event to listeners
////////////////////////////////////////////////////////////
@ -195,20 +169,6 @@ void WindowImpl::SendEvent(const Event& EventToSend)
}
////////////////////////////////////////////////////////////
/// Evaluate a pixel format configuration.
/// This functions can be used by implementations that have
/// several valid formats and want to get the best one
////////////////////////////////////////////////////////////
int WindowImpl::EvaluateConfig(const VideoMode& Mode, const WindowSettings& Settings, int ColorBits, int DepthBits, int StencilBits, int Antialiasing)
{
return abs(static_cast<int>(Mode.BitsPerPixel - ColorBits)) +
abs(static_cast<int>(Settings.DepthBits - DepthBits)) +
abs(static_cast<int>(Settings.StencilBits - StencilBits)) +
abs(static_cast<int>(Settings.AntialiasingLevel - Antialiasing));
}
////////////////////////////////////////////////////////////
/// Read the joysticks state and generate the appropriate events
////////////////////////////////////////////////////////////

View file

@ -33,7 +33,6 @@
#include <SFML/Window/Joystick.hpp>
#include <SFML/Window/VideoMode.hpp>
#include <SFML/Window/WindowHandle.hpp>
#include <SFML/Window/WindowSettings.hpp>
#include <set>
#include <string>
@ -52,37 +51,27 @@ class WindowImpl : NonCopyable
{
public :
////////////////////////////////////////////////////////////
/// Create a new window depending on the current OS
///
/// \return Pointer to the created window
///
////////////////////////////////////////////////////////////
static WindowImpl* New();
////////////////////////////////////////////////////////////
/// Create a new window depending on the current OS
///
/// \param Mode : Video mode to use
/// \param Title : Title of the window
/// \param WindowStyle : Window style
/// \param Params : Creation parameters
///
/// \return Pointer to the created window
///
////////////////////////////////////////////////////////////
static WindowImpl* New(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, WindowSettings& Params);
static WindowImpl* New(VideoMode Mode, const std::string& Title, unsigned long WindowStyle);
////////////////////////////////////////////////////////////
/// Create a new window depending on to the current OS
///
/// \param Handle : Platform-specific handle of the control
/// \param Params : Creation parameters
///
/// \return Pointer to the created window
///
////////////////////////////////////////////////////////////
static WindowImpl* New(WindowHandle Handle, WindowSettings& Params);
static WindowImpl* New(WindowHandle Handle);
public :
@ -108,12 +97,6 @@ public :
////////////////////////////////////////////////////////////
void RemoveListener(WindowListener* Listener);
////////////////////////////////////////////////////////////
/// Initialize window's states that can't be done at construction
///
////////////////////////////////////////////////////////////
void Initialize();
////////////////////////////////////////////////////////////
/// Get the client width of the window
///
@ -130,15 +113,6 @@ public :
////////////////////////////////////////////////////////////
unsigned int GetHeight() const;
////////////////////////////////////////////////////////////
/// Activate of deactivate the window as the current target
/// for rendering
///
/// \param Active : True to activate, false to deactivate (true by default)
///
////////////////////////////////////////////////////////////
virtual void SetActive(bool Active = true) const = 0;
////////////////////////////////////////////////////////////
/// Change the joystick threshold, ie. the value below which
/// no move event will be generated
@ -155,26 +129,12 @@ public :
void DoEvents();
////////////////////////////////////////////////////////////
/// Check if there's an active context on the current thread
/// Get the OS-specific handle of the window
///
/// \return True if there's a context bound to the current thread
/// \return Handle of the window
///
////////////////////////////////////////////////////////////
static bool IsContextActive();
////////////////////////////////////////////////////////////
/// Display the window on screen
///
////////////////////////////////////////////////////////////
virtual void Display() = 0;
////////////////////////////////////////////////////////////
/// Enable / disable vertical synchronization
///
/// \param Enabled : True to enable v-sync, false to deactivate
///
////////////////////////////////////////////////////////////
virtual void UseVerticalSync(bool Enabled) = 0;
virtual WindowHandle GetHandle() const = 0;
////////////////////////////////////////////////////////////
/// Show or hide the mouse cursor
@ -253,23 +213,6 @@ protected :
////////////////////////////////////////////////////////////
void SendEvent(const Event& EventToSend);
////////////////////////////////////////////////////////////
/// Evaluate a pixel format configuration.
/// This functions can be used by implementations that have
/// several valid formats and want to get the best one
///
/// \param Mode : Requested video mode
/// \param Settings : Requested additionnal settings
/// \param ColorBits : Color bits of the configuration to evaluate
/// \param DepthBits : Depth bits of the configuration to evaluate
/// \param StencilBits : Stencil bits of the configuration to evaluate
/// \param Antialiasing : Antialiasing level of the configuration to evaluate
///
/// \return Score of the configuration : the lower the better
///
////////////////////////////////////////////////////////////
static int EvaluateConfig(const VideoMode& Mode, const WindowSettings& Settings, int ColorBits, int DepthBits, int StencilBits, int Antialiasing);
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////

View file

@ -6,32 +6,26 @@ extern "C" {
#endif
/*
** License Applicability. Except to the extent portions of this file are
** made subject to an alternative license as permitted in the SGI Free
** Software License B, Version 1.1 (the "License"), the contents of this
** file are subject only to the provisions of the License. You may not use
** this file except in compliance with the License. You may obtain a copy
** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
** Copyright (c) 2007 The Khronos Group Inc.
**
** http://oss.sgi.com/projects/FreeB
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** Note that, as provided in the License, the Software is distributed on an
** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** Original Code. The Original Code is: OpenGL Sample Implementation,
** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
** Inc. The Original Code is Copyright (c) 1991-2004 Silicon Graphics, Inc.
** Copyright in any portions created by third parties is as indicated
** elsewhere herein. All Rights Reserved.
**
** Additional Notice Provisions: This software was created using the
** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has
** not been independently verified as being compliant with the OpenGL(R)
** version 1.2.1 Specification.
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
@ -52,9 +46,9 @@ extern "C" {
/*************************************************************/
/* Header file version number */
/* wglext.h last updated 2005/01/07 */
/* Current version at http://oss.sgi.com/projects/ogl-sample/registry/ */
#define WGL_WGLEXT_VERSION 6
/* wglext.h last updated 2009/03/03 */
/* Current version at http://www.opengl.org/registry/ */
#define WGL_WGLEXT_VERSION 12
#ifndef WGL_ARB_buffer_region
#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001
@ -179,6 +173,16 @@ extern "C" {
#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0
#endif
#ifndef WGL_ARB_create_context
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
#define WGL_CONTEXT_FLAGS_ARB 0x2094
#define ERROR_INVALID_VERSION_ARB 0x2095
#endif
#ifndef WGL_EXT_make_current_read
#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043
#endif
@ -319,6 +323,62 @@ extern "C" {
#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8
#endif
#ifndef WGL_3DL_stereo_control
#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055
#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056
#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057
#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058
#endif
#ifndef WGL_EXT_pixel_format_packed_float
#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8
#endif
#ifndef WGL_EXT_framebuffer_sRGB
#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9
#endif
#ifndef WGL_NV_present_video
#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0
#endif
#ifndef WGL_NV_video_out
#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0
#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1
#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2
#define WGL_VIDEO_OUT_COLOR_NV 0x20C3
#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4
#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5
#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6
#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7
#define WGL_VIDEO_OUT_FRAME 0x20C8
#define WGL_VIDEO_OUT_FIELD_1 0x20C9
#define WGL_VIDEO_OUT_FIELD_2 0x20CA
#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB
#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC
#endif
#ifndef WGL_NV_swap_group
#endif
#ifndef WGL_NV_gpu_affinity
#define WGL_ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0
#define WGL_ERROR_MISSING_AFFINITY_MASK_NV 0x20D1
#endif
#ifndef WGL_AMD_gpu_association
#define WGL_GPU_VENDOR_AMD 0x1F00
#define WGL_GPU_RENDERER_STRING_AMD 0x1F01
#define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02
#define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2
#define WGL_GPU_RAM_AMD 0x21A3
#define WGL_GPU_CLOCK_AMD 0x21A4
#define WGL_GPU_NUM_PIPES_AMD 0x21A5
#define WGL_GPU_NUM_SIMD_AMD 0x21A6
#define WGL_GPU_NUM_RB_AMD 0x21A7
#define WGL_GPU_NUM_SPI_AMD 0x21A8
#endif
/*************************************************************/
@ -328,6 +388,24 @@ DECLARE_HANDLE(HPBUFFERARB);
#ifndef WGL_EXT_pbuffer
DECLARE_HANDLE(HPBUFFEREXT);
#endif
#ifndef WGL_NV_present_video
DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV);
#endif
#ifndef WGL_NV_video_out
DECLARE_HANDLE(HPVIDEODEV);
#endif
#ifndef WGL_NV_gpu_affinity
DECLARE_HANDLE(HPGPUNV);
DECLARE_HANDLE(HGPUNV);
typedef struct _GPU_DEVICE {
DWORD cb;
CHAR DeviceName[32];
CHAR DeviceString[128];
DWORD Flags;
RECT rcVirtualScreen;
} GPU_DEVICE, *PGPU_DEVICE;
#endif
#ifndef WGL_ARB_buffer_region
#define WGL_ARB_buffer_region 1
@ -409,6 +487,14 @@ typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, con
#define WGL_ARB_pixel_format_float 1
#endif
#ifndef WGL_ARB_create_context
#define WGL_ARB_create_context 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern HGLRC WINAPI wglCreateContextAttribsARB (HDC, HGLRC, const int *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList);
#endif
#ifndef WGL_EXT_display_color_table
#define WGL_EXT_display_color_table 1
#ifdef WGL_WGLEXT_PROTOTYPES
@ -623,6 +709,102 @@ typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWO
#define WGL_NV_float_buffer 1
#endif
#ifndef WGL_EXT_pixel_format_packed_float
#define WGL_EXT_pixel_format_packed_float 1
#endif
#ifndef WGL_EXT_framebuffer_sRGB
#define WGL_EXT_framebuffer_sRGB 1
#endif
#ifndef WGL_NV_present_video
#define WGL_NV_present_video 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern int WINAPI wglEnumerateVideoDevicesNV (HDC, HVIDEOOUTPUTDEVICENV *);
extern BOOL WINAPI wglBindVideoDeviceNV (HDC, unsigned int, HVIDEOOUTPUTDEVICENV, const int *);
extern BOOL WINAPI wglQueryCurrentContextNV (int, int *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList);
typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList);
typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int *piValue);
#endif
#ifndef WGL_NV_video_out
#define WGL_NV_video_out 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglGetVideoDeviceNV (HDC, int, HPVIDEODEV *);
extern BOOL WINAPI wglReleaseVideoDeviceNV (HPVIDEODEV);
extern BOOL WINAPI wglBindVideoImageNV (HPVIDEODEV, HPBUFFERARB, int);
extern BOOL WINAPI wglReleaseVideoImageNV (HPBUFFERARB, int);
extern BOOL WINAPI wglSendPbufferToVideoNV (HPBUFFERARB, int, unsigned long *, BOOL);
extern BOOL WINAPI wglGetVideoInfoNV (HPVIDEODEV, unsigned long *, unsigned long *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice);
typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice);
typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer);
typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer);
typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock);
typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
#endif
#ifndef WGL_NV_swap_group
#define WGL_NV_swap_group 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglJoinSwapGroupNV (HDC, GLuint);
extern BOOL WINAPI wglBindSwapBarrierNV (GLuint, GLuint);
extern BOOL WINAPI wglQuerySwapGroupNV (HDC, GLuint *, GLuint *);
extern BOOL WINAPI wglQueryMaxSwapGroupsNV (HDC, GLuint *, GLuint *);
extern BOOL WINAPI wglQueryFrameCountNV (HDC, GLuint *);
extern BOOL WINAPI wglResetFrameCountNV (HDC);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group);
typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier);
typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint *group, GLuint *barrier);
typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers);
typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint *count);
typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC);
#endif
#ifndef WGL_NV_gpu_affinity
#define WGL_NV_gpu_affinity 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglEnumGpusNV (UINT, HGPUNV *);
extern BOOL WINAPI wglEnumGpuDevicesNV (HGPUNV, UINT, PGPU_DEVICE);
extern HDC WINAPI wglCreateAffinityDCNV (const HGPUNV *);
extern BOOL WINAPI wglEnumGpusFromAffinityDCNV (HDC, UINT, HGPUNV *);
extern BOOL WINAPI wglDeleteDCNV (HDC);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV *phGpu);
typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice);
typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *phGpuList);
typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu);
typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hdc);
#endif
#ifndef WGL_AMD_gpu_association
#define WGL_AMD_gpu_association 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern UINT WINAPI wglGetGPUIDsAMD (UINT, UINT *);
extern INT WINAPI wglGetGPUInfoAMD (UINT, int, GLenum, UINT, void *);
extern UINT WINAPI wglGetContextGPUIDAMD (HGLRC);
extern HGLRC WINAPI wglCreateAssociatedContextAMD (UINT);
extern HGLRC WINAPI wglCreateAssociatedContextAttribsAMD (UINT, HGLRC, const int *);
extern BOOL WINAPI wglDeleteAssociatedContextAMD (HGLRC);
extern BOOL WINAPI wglMakeAssociatedContextCurrentAMD (HGLRC);
extern HGLRC WINAPI wglGetCurrentAssociatedContextAMD (void);
extern VOID WINAPI wglBlitContextFramebufferAMD (HGLRC, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef UINT (WINAPI * PFNWGLGETGPUIDSAMDPROC) (UINT maxCount, UINT *ids);
typedef INT (WINAPI * PFNWGLGETGPUINFOAMDPROC) (UINT id, int property, GLenum dataType, UINT size, void *data);
typedef UINT (WINAPI * PFNWGLGETCONTEXTGPUIDAMDPROC) (HGLRC hglrc);
typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC) (UINT id);
typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (UINT id, HGLRC hShareContext, const int *attribList);
typedef BOOL (WINAPI * PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC) (HGLRC hglrc);
typedef BOOL (WINAPI * PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (HGLRC hglrc);
typedef HGLRC (WINAPI * PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void);
typedef VOID (WINAPI * PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC) (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
#endif
#ifdef __cplusplus
}