Skip to content

Commit

Permalink
Fixed GL_ARB_compatibility not being detected causing false compatibi…
Browse files Browse the repository at this point in the history
…lity warnings to be emitted when a 3.1 context is created.
  • Loading branch information
binary1248 authored and eXpl0it3r committed Apr 8, 2015
1 parent 22c9674 commit 01f46ce
Showing 1 changed file with 55 additions and 17 deletions.
72 changes: 55 additions & 17 deletions src/SFML/Window/GlContext.cpp
Expand Up @@ -33,6 +33,7 @@
#include <SFML/OpenGL.hpp>
#include <set>
#include <cstdlib>
#include <cstring>

#if !defined(SFML_OPENGL_ES)

Expand Down Expand Up @@ -69,6 +70,16 @@

#endif

#if defined(SFML_SYSTEM_WINDOWS)

typedef const GLubyte* (APIENTRY *glGetStringiFuncType)(GLenum, GLuint);

#else

typedef const GLubyte* (*glGetStringiFuncType)(GLenum, GLuint);

#endif

#if !defined(GL_MULTISAMPLE)
#define GL_MULTISAMPLE 0x809D
#endif
Expand All @@ -81,6 +92,10 @@
#define GL_MINOR_VERSION 0x821C
#endif

#if !defined(GL_NUM_EXTENSIONS)
#define GL_NUM_EXTENSIONS 0x821D
#endif

#if !defined(GL_CONTEXT_FLAGS)
#define GL_CONTEXT_FLAGS 0x821E
#endif
Expand Down Expand Up @@ -371,6 +386,22 @@ void GlContext::initialize()
}
}

// 3.0 contexts only deprecate features, but do not remove them yet
// 3.1 contexts remove features if ARB_compatibility is not present
// 3.2+ contexts remove features only if a core profile is requested

// If the context was created with wglCreateContext, it is guaranteed to be compatibility.
// If a 3.0 context was created with wglCreateContextAttribsARB, it is guaranteed to be compatibility.
// If a 3.1 context was created with wglCreateContextAttribsARB, the compatibility flag
// is set only if ARB_compatibility is present
// If a 3.2+ context was created with wglCreateContextAttribsARB, the compatibility flag
// would have been set correctly already depending on whether ARB_create_context_profile is supported.

// If the user requests a 3.0 context, it will be a compatibility context regardless of the requested profile.
// If the user requests a 3.1 context and its creation was successful, the specification
// states that it will not be a compatibility profile context regardless of the requested
// profile unless ARB_compatibility is present.

m_settings.attributeFlags = ContextSettings::Default;

if (m_settings.majorVersion >= 3)
Expand All @@ -382,7 +413,30 @@ void GlContext::initialize()
if (flags & GL_CONTEXT_FLAG_DEBUG_BIT)
m_settings.attributeFlags |= ContextSettings::Debug;

if ((m_settings.majorVersion > 3) || (m_settings.minorVersion >= 2))
if ((m_settings.majorVersion == 3) && (m_settings.minorVersion == 1))
{
m_settings.attributeFlags |= ContextSettings::Core;

glGetStringiFuncType glGetStringiFunc = reinterpret_cast<glGetStringiFuncType>(getFunction("glGetStringi"));

if (glGetStringiFunc)
{
int numExtensions = 0;
glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);

for (unsigned int i = 0; i < static_cast<unsigned int>(numExtensions); ++i)
{
const char* extensionString = reinterpret_cast<const char*>(glGetStringiFunc(GL_EXTENSIONS, i));

if (std::strstr(extensionString, "GL_ARB_compatibility"))
{
m_settings.attributeFlags &= ~static_cast<Uint32>(ContextSettings::Core);
break;
}
}
}
}
else if ((m_settings.majorVersion > 3) || (m_settings.minorVersion >= 2))
{
// Retrieve the context profile
int profile = 0;
Expand All @@ -404,22 +458,6 @@ void GlContext::checkSettings(const ContextSettings& requestedSettings)
{
// Perform checks to inform the user if they are getting a context they might not have expected

// 3.0 contexts only deprecate features, but do not remove them yet
// 3.1 contexts remove features if ARB_compatibility is not present (we assume it isn't for simplicity)
// 3.2+ contexts remove features only if a core profile is requested

// If the context was created with wglCreateContext, it is guaranteed to be compatibility.
// If a 3.2+ context was created with wglCreateContextAttribsARB, the compatibility flag
// would have been set correctly already depending on whether ARB_create_context_profile is supported.

// If the user requests a 3.0 context, it will be a compatibility context regardless of the requested profile.
// If the user requests a 3.1 context and its creation was successful, the specification
// states that it will not be a compatibility profile context regardless of the requested profile.
if ((m_settings.majorVersion == 3) && (m_settings.minorVersion == 0))
m_settings.attributeFlags &= ~ContextSettings::Core;
else if ((m_settings.majorVersion == 3) && (m_settings.minorVersion == 1))
m_settings.attributeFlags |= ContextSettings::Core;

int version = m_settings.majorVersion * 10 + m_settings.minorVersion;
int requestedVersion = requestedSettings.majorVersion * 10 + requestedSettings.minorVersion;

Expand Down

0 comments on commit 01f46ce

Please sign in to comment.