diff options
Diffstat (limited to 'src/SFML/Window/Context.cpp')
-rw-r--r-- | src/SFML/Window/Context.cpp | 110 |
1 files changed, 108 insertions, 2 deletions
diff --git a/src/SFML/Window/Context.cpp b/src/SFML/Window/Context.cpp index 0ec500a..2d51bbc 100644 --- a/src/SFML/Window/Context.cpp +++ b/src/SFML/Window/Context.cpp @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org) +// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org) // // 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. @@ -27,7 +27,32 @@ //////////////////////////////////////////////////////////// #include <SFML/Window/Context.hpp> #include <SFML/Window/GlContext.hpp> +#include <SFML/System/ThreadLocalPtr.hpp> +#include <SFML/OpenGL.hpp> +#include <algorithm> +#include <vector> +#include <string> +#if defined(SFML_SYSTEM_WINDOWS) + + typedef const GLubyte* (APIENTRY *glGetStringiFuncType)(GLenum, GLuint); + +#else + + typedef const GLubyte* (*glGetStringiFuncType)(GLenum, GLuint); + +#endif + +#if !defined(GL_NUM_EXTENSIONS) + #define GL_NUM_EXTENSIONS 0x821D +#endif + + +namespace +{ + // This per-thread variable holds the current context for each thread + sf::ThreadLocalPtr<sf::Context> currentContext(NULL); +} namespace sf { @@ -42,6 +67,7 @@ Context::Context() //////////////////////////////////////////////////////////// Context::~Context() { + setActive(false); delete m_context; } @@ -49,7 +75,26 @@ Context::~Context() //////////////////////////////////////////////////////////// bool Context::setActive(bool active) { - return m_context->setActive(active); + bool result = m_context->setActive(active); + + if (result) + currentContext = (active ? this : NULL); + + return result; +} + + +//////////////////////////////////////////////////////////// +const ContextSettings& Context::getSettings() const +{ + return m_context->getSettings(); +} + + +//////////////////////////////////////////////////////////// +const Context* Context::getActiveContext() +{ + return currentContext; } @@ -61,6 +106,67 @@ GlFunctionPointer Context::getFunction(const char* name) //////////////////////////////////////////////////////////// +bool Context::isExtensionAvailable(const char* name) +{ + static std::vector<std::string> extensions; + static bool loaded = false; + + if (!loaded) + { + const Context* context = getActiveContext(); + + if (!context) + return false; + + const char* extensionString = NULL; + + if(context->getSettings().majorVersion < 3) + { + // Try to load the < 3.0 way + extensionString = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)); + + do + { + const char* extension = extensionString; + + while(*extensionString && (*extensionString != ' ')) + extensionString++; + + extensions.push_back(std::string(extension, extensionString)); + } + while (*extensionString++); + } + else + { + // Try to load the >= 3.0 way + glGetStringiFuncType glGetStringiFunc = NULL; + glGetStringiFunc = reinterpret_cast<glGetStringiFuncType>(getFunction("glGetStringi")); + + if (glGetStringiFunc) + { + int numExtensions = 0; + glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions); + + if (numExtensions) + { + for (unsigned int i = 0; i < static_cast<unsigned int>(numExtensions); ++i) + { + extensionString = reinterpret_cast<const char*>(glGetStringiFunc(GL_EXTENSIONS, i)); + + extensions.push_back(extensionString); + } + } + } + } + + loaded = true; + } + + return std::find(extensions.begin(), extensions.end(), name) != extensions.end(); +} + + +//////////////////////////////////////////////////////////// Context::Context(const ContextSettings& settings, unsigned int width, unsigned int height) { m_context = priv::GlContext::create(settings, width, height); |