summaryrefslogtreecommitdiff
path: root/src/SFML/Window/Context.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/SFML/Window/Context.cpp')
-rw-r--r--src/SFML/Window/Context.cpp110
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);