Moved more OpenGL logic to opengl.c.

This commit is contained in:
Camilla Berglund 2011-03-07 14:55:11 +01:00
parent d1d550d1ab
commit 19be24afb7
3 changed files with 168 additions and 151 deletions

View File

@ -334,11 +334,12 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action);
void _glfwInputWindowFocus(_GLFWwindow* window, GLboolean activated); void _glfwInputWindowFocus(_GLFWwindow* window, GLboolean activated);
// OpenGL context helpers (opengl.c) // OpenGL context helpers (opengl.c)
void _glfwParseGLVersion(int* major, int* minor, int* rev);
int _glfwStringInExtensionString(const char* string, const GLubyte* extensions); int _glfwStringInExtensionString(const char* string, const GLubyte* extensions);
const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
const _GLFWfbconfig* alternatives, const _GLFWfbconfig* alternatives,
unsigned int count); unsigned int count);
GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig);
GLboolean _glfwIsValidContext(_GLFWwindow* window, _GLFWwndconfig* wndconfig);
#endif // _internal_h_ #endif // _internal_h_

View File

@ -34,6 +34,56 @@
#include <limits.h> #include <limits.h>
//========================================================================
// Parses the OpenGL version string and extracts the version number
//========================================================================
static void parseGLVersion(int* major, int* minor, int* rev)
{
GLuint _major, _minor = 0, _rev = 0;
const GLubyte* version;
const GLubyte* ptr;
const char* glesPrefix = "OpenGL ES ";
version = glGetString(GL_VERSION);
if (!version)
return;
if (strncmp((const char*) version, glesPrefix, strlen(glesPrefix)) == 0)
{
// The version string on OpenGL ES has a prefix before the version
// number, so we skip past it and then continue as normal
version += strlen(glesPrefix);
}
// Parse version from string
ptr = version;
for (_major = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
_major = 10 * _major + (*ptr - '0');
if (*ptr == '.')
{
ptr++;
for (_minor = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
_minor = 10 * _minor + (*ptr - '0');
if (*ptr == '.')
{
ptr++;
for (_rev = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
_rev = 10 * _rev + (*ptr - '0');
}
}
// Store result
*major = _major;
*minor = _minor;
*rev = _rev;
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW internal API ////// ////// GLFW internal API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -196,54 +246,133 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
//======================================================================== //========================================================================
// Parses the OpenGL version string and extracts the version number // Checks whether the OpenGL part of the window config is sane
// It blames glfwOpenWindow because that's the only caller
//======================================================================== //========================================================================
void _glfwParseGLVersion(int* major, int* minor, int* rev) GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig)
{ {
GLuint _major, _minor = 0, _rev = 0; if (wndconfig->glMajor < 1 || wndconfig->glMinor < 0)
const GLubyte* version;
const GLubyte* ptr;
const char* glesPrefix = "OpenGL ES ";
version = glGetString(GL_VERSION);
if (!version)
return;
if (strncmp((const char*) version, glesPrefix, strlen(glesPrefix)) == 0)
{ {
// The version string on OpenGL ES has a prefix before the version // OpenGL 1.0 is the smallest valid version
// number, so we skip past it and then continue as normal _glfwSetError(GLFW_INVALID_VALUE, "glfwOpenWindow: Invalid OpenGL version requested");
return GL_FALSE;
version += strlen(glesPrefix); }
if (wndconfig->glMajor == 1 && wndconfig->glMinor > 5)
{
// OpenGL 1.x series ended with version 1.5
_glfwSetError(GLFW_INVALID_VALUE, "glfwOpenWindow: Invalid OpenGL version requested");
return GL_FALSE;
}
else if (wndconfig->glMajor == 2 && wndconfig->glMinor > 1)
{
// OpenGL 2.x series ended with version 2.1
_glfwSetError(GLFW_INVALID_VALUE, "glfwOpenWindow: Invalid OpenGL version requested");
return GL_FALSE;
}
else if (wndconfig->glMajor == 3 && wndconfig->glMinor > 3)
{
// OpenGL 3.x series ended with version 3.3
_glfwSetError(GLFW_INVALID_VALUE, "glfwOpenWindow: Invalid OpenGL version requested");
return GL_FALSE;
}
else
{
// For now, let everything else through
} }
// Parse version from string if (wndconfig->glProfile == GLFW_OPENGL_ES2_PROFILE)
ptr = version;
for (_major = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
_major = 10 * _major + (*ptr - '0');
if (*ptr == '.')
{ {
ptr++; if (wndconfig->glMajor != 2 || wndconfig->glMinor < 0)
for (_minor = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
_minor = 10 * _minor + (*ptr - '0');
if (*ptr == '.')
{ {
ptr++; // The OpenGL ES 2.0 profile is currently only defined for version
for (_rev = 0; *ptr >= '0' && *ptr <= '9'; ptr++) // 2.0 (see {WGL|GLX}_EXT_create_context_es2_profile), but for
_rev = 10 * _rev + (*ptr - '0'); // compatibility with future updates to OpenGL ES, we allow
// everything 2.x and let the driver report invalid 2.x versions
_glfwSetError(GLFW_INVALID_VALUE, "glfwOpenWindow: Invalid OpenGL ES 2.x version requested");
return GL_FALSE;
}
}
else if (wndconfig->glProfile)
{
if (wndconfig->glProfile != GLFW_OPENGL_CORE_PROFILE &&
wndconfig->glProfile != GLFW_OPENGL_COMPAT_PROFILE)
{
_glfwSetError(GLFW_INVALID_ENUM, "glfwOpenWindow: Invalid OpenGL profile requested");
return GL_FALSE;
}
if (wndconfig->glMajor < 3 || (wndconfig->glMajor == 3 && wndconfig->glMinor < 2))
{
// Desktop OpenGL context profiles are only defined for version 3.2
// and above
_glfwSetError(GLFW_INVALID_VALUE, "glfwOpenWindow: Context profiles only exist for OpenGL version 3.2 and above");
return GL_FALSE;
} }
} }
// Store result if (wndconfig->glForward && wndconfig->glMajor < 3)
*major = _major; {
*minor = _minor; // Forward-compatible contexts are only defined for OpenGL version 3.0 and above
*rev = _rev; _glfwSetError(GLFW_INVALID_VALUE, "glfwOpenWindow: Forward compatibility only exist for OpenGL version 3.0 and above");
return GL_FALSE;
}
return GL_TRUE;
} }
//========================================================================
// Checks whether the specified context fulfils the requirements
// It blames glfwOpenWindow because that's the only caller
//========================================================================
GLboolean _glfwIsValidContext(_GLFWwindow* window, _GLFWwndconfig* wndconfig)
{
parseGLVersion(&window->glMajor, &window->glMinor, &window->glRevision);
// As these are hard constraints when non-zero, we can simply copy them
window->glProfile = wndconfig->glProfile;
window->glForward = wndconfig->glForward;
if (window->glMajor < wndconfig->glMajor ||
(window->glMajor == wndconfig->glMajor &&
window->glMinor < wndconfig->glMinor))
{
// The desired OpenGL version is greater than the actual version
// This only happens if the machine lacks {GLX|WGL}_ARB_create_context
// /and/ the user has requested an OpenGL version greater than 1.0
// For API consistency, we emulate the behavior of the
// {GLX|WGL}_ARB_create_context extension and fail here
_glfwSetError(GLFW_VERSION_UNAVAILABLE, "glfwOpenWindow: The requested OpenGL version is not available");
return GL_FALSE;
}
if (window->glMajor > 2)
{
// OpenGL 3.0+ uses a different function for extension string retrieval
// We cache it here instead of in glfwExtensionSupported mostly to alert
// users as early as possible that their build may be broken
window->GetStringi = (PFNGLGETSTRINGIPROC) glfwGetProcAddress("glGetStringi");
if (!window->GetStringi)
{
// This is a very common problem among people who compile GLFW
// on X11/GLX using custom build systems, as it needs explicit
// configuration in order to work
_glfwSetError(GLFW_PLATFORM_ERROR, "glfwOpenWindow: Entry point retrieval is broken; see the build documentation for your platform");
return GL_FALSE;
}
}
return GL_TRUE;
}
//======================================================================== //========================================================================
// Check if a string can be found in an OpenGL extension string // Check if a string can be found in an OpenGL extension string
//======================================================================== //========================================================================

View File

@ -85,84 +85,6 @@ static void clearScrollOffsets(void)
} }
//========================================================================
// Checks whether the OpenGL part of the window config is sane
//========================================================================
static GLboolean isValidContextConfig(_GLFWwndconfig* wndconfig)
{
if (wndconfig->glMajor < 1 || wndconfig->glMinor < 0)
{
// OpenGL 1.0 is the smallest valid version
_glfwSetError(GLFW_INVALID_VALUE, "glfwOpenWindow: Invalid OpenGL version requested");
return GL_FALSE;
}
if (wndconfig->glMajor == 1 && wndconfig->glMinor > 5)
{
// OpenGL 1.x series ended with version 1.5
_glfwSetError(GLFW_INVALID_VALUE, "glfwOpenWindow: Invalid OpenGL version requested");
return GL_FALSE;
}
else if (wndconfig->glMajor == 2 && wndconfig->glMinor > 1)
{
// OpenGL 2.x series ended with version 2.1
_glfwSetError(GLFW_INVALID_VALUE, "glfwOpenWindow: Invalid OpenGL version requested");
return GL_FALSE;
}
else if (wndconfig->glMajor == 3 && wndconfig->glMinor > 3)
{
// OpenGL 3.x series ended with version 3.3
_glfwSetError(GLFW_INVALID_VALUE, "glfwOpenWindow: Invalid OpenGL version requested");
return GL_FALSE;
}
else
{
// For now, let everything else through
}
if (wndconfig->glProfile == GLFW_OPENGL_ES2_PROFILE)
{
if (wndconfig->glMajor != 2 || wndconfig->glMinor < 0)
{
// The OpenGL ES 2.0 profile is currently only defined for version
// 2.0 (see {WGL|GLX}_EXT_create_context_es2_profile), but for
// compatibility with future updates to OpenGL ES, we allow
// everything 2.x and let the driver report invalid 2.x versions
_glfwSetError(GLFW_INVALID_VALUE, "glfwOpenWindow: Invalid OpenGL ES 2.x version requested");
return GL_FALSE;
}
}
else if (wndconfig->glProfile)
{
if (wndconfig->glProfile != GLFW_OPENGL_CORE_PROFILE &&
wndconfig->glProfile != GLFW_OPENGL_COMPAT_PROFILE)
{
_glfwSetError(GLFW_INVALID_ENUM, "glfwOpenWindow: Invalid OpenGL profile");
return GL_FALSE;
}
if (wndconfig->glMajor < 3 || (wndconfig->glMajor == 3 && wndconfig->glMinor < 2))
{
// Desktop OpenGL context profiles are only defined for version 3.2
// and above
_glfwSetError(GLFW_INVALID_VALUE, "glfwOpenWindow: Context profiles only exist for OpenGL version 3.2 and above");
return GL_FALSE;
}
}
if (wndconfig->glForward && wndconfig->glMajor < 3)
{
// Forward-compatible contexts are only defined for OpenGL version 3.0 and above
_glfwSetError(GLFW_INVALID_VALUE, "glfwOpenWindow: Forward compatibility only exist for OpenGL version 3.0 and above");
return GL_FALSE;
}
return GL_TRUE;
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW internal API ////// ////// GLFW internal API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -361,7 +283,7 @@ GLFWAPI GLFWwindow glfwOpenWindow(int width, int height,
_glfwSetDefaultWindowHints(); _glfwSetDefaultWindowHints();
// Check the OpenGL bits of the window config // Check the OpenGL bits of the window config
if (!isValidContextConfig(&wndconfig)) if (!_glfwIsValidContextConfig(&wndconfig))
return GL_FALSE; return GL_FALSE;
if (mode != GLFW_WINDOWED && mode != GLFW_FULLSCREEN) if (mode != GLFW_WINDOWED && mode != GLFW_FULLSCREEN)
@ -416,47 +338,12 @@ GLFWAPI GLFWwindow glfwOpenWindow(int width, int height,
glfwMakeWindowCurrent(window); glfwMakeWindowCurrent(window);
_glfwPlatformRefreshWindowParams(); _glfwPlatformRefreshWindowParams();
// As these are hard constraints when non-zero, we can simply copy them if (!_glfwIsValidContext(window, &wndconfig))
window->glProfile = wndconfig.glProfile;
window->glForward = wndconfig.glForward;
_glfwParseGLVersion(&window->glMajor, &window->glMinor, &window->glRevision);
if (window->glMajor < wndconfig.glMajor ||
(window->glMajor == wndconfig.glMajor &&
window->glMinor < wndconfig.glMinor))
{ {
// The desired OpenGL version is greater than the actual version
// This only happens if the machine lacks {GLX|WGL}_ARB_create_context
// /and/ the user has requested an OpenGL version greater than 1.0
// For API consistency, we emulate the behavior of the
// {GLX|WGL}_ARB_create_context extension and fail here
glfwCloseWindow(window); glfwCloseWindow(window);
_glfwSetError(GLFW_VERSION_UNAVAILABLE, "glfwOpenWindow: The requested OpenGL version is not available");
return GL_FALSE; return GL_FALSE;
} }
if (window->glMajor > 2)
{
// OpenGL 3.0+ uses a different function for extension string retrieval
// We cache it here instead of in glfwExtensionSupported mostly to alert
// users as early as possible that their build may be broken
window->GetStringi = (PFNGLGETSTRINGIPROC) glfwGetProcAddress("glGetStringi");
if (!window->GetStringi)
{
// This is a very common problem among people who compile GLFW
// on X11/GLX using custom build systems, as it needs explicit
// configuration in order to work
glfwCloseWindow(window);
_glfwSetError(GLFW_PLATFORM_ERROR, "glfwOpenWindow: Entry point retrieval is broken; see the build documentation for your platform");
return GL_FALSE;
}
}
// The GLFW specification states that fullscreen windows have the cursor // The GLFW specification states that fullscreen windows have the cursor
// locked by default // locked by default
if (mode == GLFW_FULLSCREEN) if (mode == GLFW_FULLSCREEN)