mirror of
https://github.com/glfw/glfw.git
synced 2024-11-10 09:01:46 +00:00
Moved more OpenGL logic to opengl.c.
This commit is contained in:
parent
d1d550d1ab
commit
19be24afb7
@ -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_
|
||||||
|
199
src/opengl.c
199
src/opengl.c
@ -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
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
117
src/window.c
117
src/window.c
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user