Added client API window hint.

This commit is contained in:
Camilla Berglund 2012-07-22 01:10:59 +02:00
parent e9c82a82b2
commit 3b6ec4e775
10 changed files with 274 additions and 163 deletions

View File

@ -413,12 +413,17 @@ extern "C" {
#define GLFW_STEREO 0x0002100C
#define GLFW_WINDOW_RESIZABLE 0x0002100D
#define GLFW_FSAA_SAMPLES 0x0002100E
#define GLFW_OPENGL_VERSION_MAJOR 0x0002100F
#define GLFW_OPENGL_VERSION_MINOR 0x00021010
#define GLFW_OPENGL_FORWARD_COMPAT 0x00021011
#define GLFW_OPENGL_DEBUG_CONTEXT 0x00021012
#define GLFW_OPENGL_PROFILE 0x00021013
#define GLFW_OPENGL_ROBUSTNESS 0x00021014
#define GLFW_CLIENT_API 0x0002100F
#define GLFW_OPENGL_VERSION_MAJOR 0x00021010
#define GLFW_OPENGL_VERSION_MINOR 0x00021011
#define GLFW_OPENGL_FORWARD_COMPAT 0x00021012
#define GLFW_OPENGL_DEBUG_CONTEXT 0x00021013
#define GLFW_OPENGL_PROFILE 0x00021014
#define GLFW_OPENGL_ROBUSTNESS 0x00021015
/* GLFW_OPENGL_API mode tokens */
#define GLFW_OPENGL_API 0x00000001
#define GLFW_OPENGL_ES_API 0x00000002
/* GLFW_OPENGL_ROBUSTNESS mode tokens */
#define GLFW_OPENGL_NO_ROBUSTNESS 0x00000000
@ -429,7 +434,6 @@ extern "C" {
#define GLFW_OPENGL_NO_PROFILE 0x00000000
#define GLFW_OPENGL_CORE_PROFILE 0x00000001
#define GLFW_OPENGL_COMPAT_PROFILE 0x00000002
#define GLFW_OPENGL_ES2_PROFILE 0x00000004
/* glfwGetInputMode/glfwSetInputMode tokens */
#define GLFW_CURSOR_MODE 0x00030001

View File

@ -280,7 +280,7 @@ version of GLFW.</p>
<li>Added <code>glfwGetClipboardString</code> and <code>glfwSetClipboardString</code> functions for interacting with the system clipboard</li>
<li>Added <code>glfwGetCurrentContext</code> function for retrieving the window whose OpenGL context is current</li>
<li>Added <code>glfwCopyContext</code> function for copying OpenGL state categories between contexts</li>
<li>Added <code>GLFW_OPENGL_ES2_PROFILE</code> profile for creating OpenGL ES 2.0 contexts using the <code>GLX_EXT_create_context_es2_profile</code> and <code>WGL_EXT_create_context_es2_profile</code> extensions</li>
<li>Added <code>GLFW_CLIENT_API</code> window hint for creating contexts for APIs other than desktop OpenGL</li>
<li>Added <code>GLFW_OPENGL_ROBUSTNESS</code> window hint and associated strategy tokens for <code>GL_ARB_robustness</code> support</li>
<li>Added <code>GLFW_OPENGL_REVISION</code> window parameter to make up for removal of <code>glfwGetGLVersion</code></li>
<li>Added <code>GLFW_INCLUDE_GL3</code> macro for telling the GLFW header to include <code>gl3.h</code> header instead of <code>gl.h</code></li>

View File

@ -717,6 +717,13 @@ static GLboolean createContext(_GLFWwindow* window,
else if (colorBits < 15)
colorBits = 15;
if (wndconfig->clientAPI != GLFW_OPENGL_ES_API)
{
_glfwSetError(GLFW_VERSION_UNAVAILABLE,
"Cocoa/NSOpenGL: NSOpenGL does not support OpenGL ES");
return GL_FALSE;
}
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
// Fail if any OpenGL version above 2.1 other than 3.2 was requested
if (wndconfig->glMajor > 3 ||

View File

@ -110,6 +110,7 @@ struct _GLFWhints
GLboolean stereo;
GLboolean resizable;
int samples;
int clientAPI;
int glMajor;
int glMinor;
GLboolean glForward;
@ -131,6 +132,7 @@ struct _GLFWwndconfig
const char* title;
int refreshRate;
GLboolean resizable;
int clientAPI;
int glMajor;
int glMinor;
GLboolean glForward;
@ -212,6 +214,7 @@ struct _GLFWwindow
// OpenGL extensions and context attributes
GLboolean accelerated; // GL_TRUE if OpenGL context is "accelerated"
int clientAPI;
int glMajor, glMinor, glRevision;
GLboolean glForward, glDebug;
int glProfile;

View File

@ -36,7 +36,7 @@
//========================================================================
// Parses the OpenGL version string and extracts the version number
// Parses the client API version string and extracts the version number
//========================================================================
static void parseGLVersion(int* major, int* minor, int* rev)
@ -256,89 +256,125 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
//========================================================================
// Checks whether the OpenGL part of the window config is sane
// Checks whether the client API part of the window config is sane
// It blames glfwOpenWindow because that's the only caller
//========================================================================
GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig)
{
if (wndconfig->glMajor < 1 || wndconfig->glMinor < 0)
if (wndconfig->clientAPI != GLFW_OPENGL_API &&
wndconfig->clientAPI != GLFW_OPENGL_ES_API)
{
// OpenGL 1.0 is the smallest valid version
_glfwSetError(GLFW_INVALID_VALUE,
"glfwOpenWindow: Invalid OpenGL version requested");
_glfwSetError(GLFW_INVALID_ENUM,
"glfwOpenWindow: Invalid client API 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->clientAPI == GLFW_OPENGL_API)
{
if (wndconfig->glMajor != 2 || wndconfig->glMinor < 0)
if (wndconfig->glMajor < 1 || 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
// OpenGL 1.0 is the smallest valid version
_glfwSetError(GLFW_INVALID_VALUE,
"glfwOpenWindow: Invalid OpenGL ES 2.x version requested");
"glfwOpenWindow: Invalid OpenGL version requested");
return GL_FALSE;
}
}
else if (wndconfig->glProfile)
{
if (wndconfig->glProfile != GLFW_OPENGL_CORE_PROFILE &&
wndconfig->glProfile != GLFW_OPENGL_COMPAT_PROFILE)
if (wndconfig->glMajor == 1 && wndconfig->glMinor > 5)
{
_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
// OpenGL 1.x series ended with version 1.5
_glfwSetError(GLFW_INVALID_VALUE,
"glfwOpenWindow: Context profiles only exist for "
"OpenGL version 3.2 and above");
"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)
{
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;
}
}
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;
}
}
if (wndconfig->glForward && wndconfig->glMajor < 3)
else if (wndconfig->clientAPI == GLFW_OPENGL_ES_API)
{
// 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;
if (wndconfig->glMajor < 1 || wndconfig->glMinor < 0)
{
// OpenGL ES 1.0 is the smallest valid version
_glfwSetError(GLFW_INVALID_VALUE,
"glfwOpenWindow: Invalid OpenGL ES version requested");
return GL_FALSE;
}
if (wndconfig->glMajor == 1 && wndconfig->glMinor > 1)
{
// OpenGL ES 1.x series ended with version 1.1
_glfwSetError(GLFW_INVALID_VALUE,
"glfwOpenWindow: Invalid OpenGL ES version requested");
return GL_FALSE;
}
else
{
// For now, let everything else through
}
if (wndconfig->glProfile)
{
// OpenGL ES does not support profiles
_glfwSetError(GLFW_INVALID_VALUE,
"glfwOpenWindow: Context profiles are not supported "
"by OpenGL ES");
return GL_FALSE;
}
if (wndconfig->glForward)
{
// OpenGL ES does not support Forward-compatibility
_glfwSetError(GLFW_INVALID_VALUE,
"glfwOpenWindow: Forward compatibility is not "
"supported by OpenGL ES");
return GL_FALSE;
}
}
if (wndconfig->glRobustness)
@ -347,7 +383,8 @@ GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig)
wndconfig->glRobustness != GLFW_OPENGL_LOSE_CONTEXT_ON_RESET)
{
_glfwSetError(GLFW_INVALID_VALUE,
"glfwOpenWindow: Invalid OpenGL robustness mode requested");
"glfwOpenWindow: Invalid OpenGL robustness mode "
"requested");
return GL_FALSE;
}
}
@ -363,6 +400,8 @@ GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig)
GLboolean _glfwIsValidContext(_GLFWwindow* window, _GLFWwndconfig* wndconfig)
{
window->clientAPI = wndconfig->clientAPI;
parseGLVersion(&window->glMajor, &window->glMinor, &window->glRevision);
// Read back forward-compatibility flag
@ -433,7 +472,7 @@ GLboolean _glfwIsValidContext(_GLFWwindow* window, _GLFWwndconfig* wndconfig)
//========================================================================
// Check if a string can be found in an OpenGL extension string
// Check if a string can be found in a client API extension string
//========================================================================
int _glfwStringInExtensionString(const char* string,
@ -472,7 +511,7 @@ int _glfwStringInExtensionString(const char* string,
//////////////////////////////////////////////////////////////////////////
//========================================================================
// Make the OpenGL context associated with the specified window current
// Make the context associated with the specified window current
//========================================================================
GLFWAPI void glfwMakeContextCurrent(GLFWwindow handle)
@ -494,7 +533,7 @@ GLFWAPI void glfwMakeContextCurrent(GLFWwindow handle)
//========================================================================
// Returns the window whose OpenGL context is current
// Returns the window whose context is current
//========================================================================
GLFWAPI GLFWwindow glfwGetCurrentContext(void)
@ -554,7 +593,7 @@ GLFWAPI void glfwSwapInterval(int interval)
//========================================================================
// Check if an OpenGL extension is available at runtime
// Check if a client API extension is available at runtime
//========================================================================
GLFWAPI int glfwExtensionSupported(const char* extension)
@ -619,8 +658,8 @@ GLFWAPI int glfwExtensionSupported(const char* extension)
//========================================================================
// Get the function pointer to an OpenGL function.
// This function can be used to get access to extended OpenGL functions.
// Get the function pointer to a client API function
// This can be used to get access to client API extension functions
//========================================================================
GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
@ -642,7 +681,7 @@ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
//========================================================================
// Copies the specified OpenGL state categories from src to dst
// Copies the specified context state categories from src to dst
//========================================================================
GLFWAPI void glfwCopyContext(GLFWwindow hsrc, GLFWwindow hdst, unsigned long mask)

View File

@ -336,6 +336,21 @@ static GLboolean createContext(_GLFWwindow* window,
attribs[i++] = wndconfig->glMinor;
}
if (wndconfig->clientAPI == GLFW_OPENGL_ES_API)
{
if (!window->WGL.ARB_create_context_profile ||
!window->WGL.EXT_create_context_es2_profile)
{
_glfwSetError(GLFW_VERSION_UNAVAILABLE,
"Win32/WGL: OpenGL ES 2.x requested but "
"WGL_EXT_create_context_es2_profile is unavailable");
return GL_FALSE;
}
attribs[i++] = WGL_CONTEXT_PROFILE_MASK_ARB;
attribs[i++] = WGL_CONTEXT_ES2_PROFILE_BIT_EXT;
}
if (wndconfig->glForward || wndconfig->glDebug || wndconfig->glRobustness)
{
int flags = 0;
@ -365,21 +380,10 @@ static GLboolean createContext(_GLFWwindow* window,
return GL_FALSE;
}
if (wndconfig->glProfile == GLFW_OPENGL_ES2_PROFILE &&
!window->WGL.EXT_create_context_es2_profile)
{
_glfwSetError(GLFW_VERSION_UNAVAILABLE,
"Win32/WGL: OpenGL ES 2.x profile requested but "
"WGL_EXT_create_context_es2_profile is unavailable");
return GL_FALSE;
}
if (wndconfig->glProfile == GLFW_OPENGL_CORE_PROFILE)
flags = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
else if (wndconfig->glProfile == GLFW_OPENGL_COMPAT_PROFILE)
flags = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
else if (wndconfig->glProfile == GLFW_OPENGL_ES2_PROFILE)
flags = WGL_CONTEXT_ES2_PROFILE_BIT_EXT;
attribs[i++] = WGL_CONTEXT_PROFILE_MASK_ARB;
attribs[i++] = flags;

View File

@ -97,7 +97,8 @@ void _glfwSetDefaultWindowHints(void)
{
memset(&_glfwLibrary.hints, 0, sizeof(_glfwLibrary.hints));
// The default minimum OpenGL version is 1.0
// The default is OpenGL with minimum version 1.0
_glfwLibrary.hints.clientAPI = GLFW_OPENGL_API;
_glfwLibrary.hints.glMajor = 1;
_glfwLibrary.hints.glMinor = 0;
@ -251,6 +252,7 @@ GLFWAPI GLFWwindow glfwOpenWindow(int width, int height,
wndconfig.title = title;
wndconfig.refreshRate = Max(_glfwLibrary.hints.refreshRate, 0);
wndconfig.resizable = _glfwLibrary.hints.resizable ? GL_TRUE : GL_FALSE;
wndconfig.clientAPI = _glfwLibrary.hints.clientAPI;
wndconfig.glMajor = _glfwLibrary.hints.glMajor;
wndconfig.glMinor = _glfwLibrary.hints.glMinor;
wndconfig.glForward = _glfwLibrary.hints.glForward ? GL_TRUE : GL_FALSE;
@ -429,6 +431,9 @@ GLFWAPI void glfwOpenWindowHint(int target, int hint)
case GLFW_FSAA_SAMPLES:
_glfwLibrary.hints.samples = hint;
break;
case GLFW_CLIENT_API:
_glfwLibrary.hints.clientAPI = hint;
break;
case GLFW_OPENGL_VERSION_MAJOR:
_glfwLibrary.hints.glMajor = hint;
break;
@ -714,6 +719,8 @@ GLFWAPI int glfwGetWindowParam(GLFWwindow handle, int param)
return window->resizable;
case GLFW_FSAA_SAMPLES:
return window->samples;
case GLFW_CLIENT_API:
return window->clientAPI;
case GLFW_OPENGL_VERSION_MAJOR:
return window->glMajor;
case GLFW_OPENGL_VERSION_MINOR:

View File

@ -110,18 +110,23 @@ static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window,
continue;
}
if (!(getConfigAttrib(configs[i], EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES_BIT) &&
!(getConfigAttrib(configs[i], EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT))
if (wndconfig->clientAPI == GLFW_OPENGL_ES_API)
{
// Only consider OpenGL ES context
continue;
if (wndconfig->glMajor == 1)
{
if (!(getConfigAttrib(configs[i], EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES_BIT))
continue;
}
else
{
if (!(getConfigAttrib(configs[i], EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT))
continue;
}
}
if (wndconfig->glProfile == GLFW_OPENGL_ES2_PROFILE &&
!(getConfigAttrib(configs[i], EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT))
else if (wndconfig->clientAPI == GLFW_OPENGL_API)
{
// User requested only OpenGL ES 2.0 context
continue;
if (!(getConfigAttrib(configs[i], EGL_RENDERABLE_TYPE) & EGL_OPENGL_BIT))
continue;
}
f->redBits = getConfigAttrib(configs[i], EGL_RED_SIZE);
@ -248,19 +253,17 @@ static int createContext(_GLFWwindow* window,
}
index = 0;
if (wndconfig->glProfile == GLFW_OPENGL_ES2_PROFILE)
if (wndconfig->clientAPI == GLFW_OPENGL_ES_API)
{
setEGLattrib(attribs, index, EGL_CONTEXT_CLIENT_VERSION, 2);
eglBindAPI(EGL_OPENGL_ES_API);
setEGLattrib(attribs, index, EGL_CONTEXT_CLIENT_VERSION, wndconfig->glMajor);
}
else
{
setEGLattrib(attribs, index, EGL_CONTEXT_CLIENT_VERSION, 1);
}
eglBindAPI(EGL_OPENGL_API);
setEGLattrib(attribs, index, EGL_NONE, EGL_NONE);
eglBindAPI(EGL_OPENGL_ES_API);
window->EGL.context = eglCreateContext(_glfwLibrary.EGL.display,
config, share, attribs);

View File

@ -346,6 +346,22 @@ static int createContext(_GLFWwindow* window,
setGLXattrib(attribs, index, GLX_CONTEXT_MINOR_VERSION_ARB, wndconfig->glMinor);
}
if (wndconfig->clientAPI == GLFW_OPENGL_ES_API)
{
if (!_glfwLibrary.GLX.ARB_create_context_profile ||
!_glfwLibrary.GLX.EXT_create_context_es2_profile)
{
_glfwSetError(GLFW_VERSION_UNAVAILABLE,
"X11/GLX: OpenGL ES 2.x requested but "
"GLX_EXT_create_context_es2_profile is unavailable");
return GL_FALSE;
}
setGLXattrib(attribs, index,
GLX_CONTEXT_PROFILE_MASK_ARB,
GLX_CONTEXT_ES2_PROFILE_BIT_EXT);
}
if (wndconfig->glForward || wndconfig->glDebug || wndconfig->glRobustness)
{
int flags = 0;
@ -374,21 +390,10 @@ static int createContext(_GLFWwindow* window,
return GL_FALSE;
}
if (wndconfig->glProfile == GLFW_OPENGL_ES2_PROFILE &&
!_glfwLibrary.GLX.EXT_create_context_es2_profile)
{
_glfwSetError(GLFW_VERSION_UNAVAILABLE,
"X11/GLX: OpenGL ES 2.x profile requested but "
"GLX_EXT_create_context_es2_profile is unavailable");
return GL_FALSE;
}
if (wndconfig->glProfile == GLFW_OPENGL_CORE_PROFILE)
flags = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
else if (wndconfig->glProfile == GLFW_OPENGL_COMPAT_PROFILE)
flags = GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
else if (wndconfig->glProfile == GLFW_OPENGL_ES2_PROFILE)
flags = GLX_CONTEXT_ES2_PROFILE_BIT_EXT;
setGLXattrib(attribs, index, GLX_CONTEXT_PROFILE_MASK_ARB, flags);
}

View File

@ -42,17 +42,20 @@
#define strcasecmp(x, y) _stricmp(x, y)
#endif
#define API_OPENGL "gl"
#define API_OPENGL_ES "es"
#define PROFILE_NAME_CORE "core"
#define PROFILE_NAME_COMPAT "compat"
#define PROFILE_NAME_ES2 "es2"
#define STRATEGY_NAME_NONE "none"
#define STRATEGY_NAME_LOSE "lose"
static void usage(void)
{
printf("Usage: glfwinfo [-h] [-m MAJOR] [-n MINOR] [-d] [-l] [-f] [-p PROFILE] [-r STRATEGY]\n");
printf("available profiles: " PROFILE_NAME_CORE " " PROFILE_NAME_COMPAT " " PROFILE_NAME_ES2 "\n");
printf("Usage: glfwinfo [-h] [-a API] [-m MAJOR] [-n MINOR] [-d] [-l] [-f] [-p PROFILE] [-r STRATEGY]\n");
printf("available APIs: " API_OPENGL " " API_OPENGL_ES "\n");
printf("available profiles: " PROFILE_NAME_CORE " " PROFILE_NAME_COMPAT "\n");
printf("available strategies: " STRATEGY_NAME_NONE " " STRATEGY_NAME_LOSE "\n");
}
@ -61,14 +64,22 @@ static void error_callback(int error, const char* description)
fprintf(stderr, "Error: %s in %s\n", glfwErrorString(error), description);
}
static const char* get_client_api_name(int api)
{
if (api == GLFW_OPENGL_API)
return "OpenGL";
else if (api == GLFW_OPENGL_ES_API)
return "OpenGL ES";
return "Unknown API";
}
static const char* get_glfw_profile_name(int profile)
{
if (profile == GLFW_OPENGL_COMPAT_PROFILE)
return PROFILE_NAME_COMPAT;
return "compatibility";
else if (profile == GLFW_OPENGL_CORE_PROFILE)
return PROFILE_NAME_CORE;
else if (profile == GLFW_OPENGL_ES2_PROFILE)
return PROFILE_NAME_ES2;
return "core";
return "unknown";
}
@ -76,22 +87,22 @@ static const char* get_glfw_profile_name(int profile)
static const char* get_profile_name(GLint mask)
{
if (mask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT)
return PROFILE_NAME_COMPAT;
return "compatibility";
if (mask & GL_CONTEXT_CORE_PROFILE_BIT)
return PROFILE_NAME_CORE;
return "core";
return "unknown";
}
static void list_extensions(int major, int minor)
static void list_extensions(int api, int major, int minor)
{
int i;
GLint count;
const GLubyte* extensions;
printf("OpenGL context supported extensions:\n");
printf("%s context supported extensions:\n", get_client_api_name(api));
if (major > 2)
if (api == GLFW_OPENGL_API && major > 2)
{
PFNGLGETSTRINGIPROC glGetStringi = (PFNGLGETSTRINGIPROC) glfwGetProcAddress("glGetStringi");
if (!glGetStringi)
@ -121,15 +132,25 @@ static void list_extensions(int major, int minor)
int main(int argc, char** argv)
{
int ch, profile = 0, strategy = 0, major = 1, minor = 0, revision;
int ch, api = 0, profile = 0, strategy = 0, major = 1, minor = 0, revision;
GLboolean debug = GL_FALSE, forward = GL_FALSE, list = GL_FALSE;
GLint flags, mask;
GLFWwindow window;
while ((ch = getopt(argc, argv, "dfhlm:n:p:r:")) != -1)
while ((ch = getopt(argc, argv, "a:dfhlm:n:p:r:")) != -1)
{
switch (ch)
{
case 'a':
if (strcasecmp(optarg, API_OPENGL) == 0)
api = GLFW_OPENGL_API;
else if (strcasecmp(optarg, API_OPENGL_ES) == 0)
api = GLFW_OPENGL_ES_API;
else
{
usage();
exit(EXIT_FAILURE);
}
case 'd':
debug = GL_TRUE;
break;
@ -153,8 +174,6 @@ int main(int argc, char** argv)
profile = GLFW_OPENGL_CORE_PROFILE;
else if (strcasecmp(optarg, PROFILE_NAME_COMPAT) == 0)
profile = GLFW_OPENGL_COMPAT_PROFILE;
else if (strcasecmp(optarg, PROFILE_NAME_ES2) == 0)
profile = GLFW_OPENGL_ES2_PROFILE;
else
{
usage();
@ -195,6 +214,9 @@ int main(int argc, char** argv)
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, minor);
}
if (api != 0)
glfwOpenWindowHint(GLFW_CLIENT_API, api);
if (debug)
glfwOpenWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
@ -234,53 +256,70 @@ int main(int argc, char** argv)
printf("GLFW library version string: \"%s\"\n", glfwGetVersionString());
// Report OpenGL version
printf("OpenGL context version string: \"%s\"\n", glGetString(GL_VERSION));
// Report client API version
api = glfwGetWindowParam(window, GLFW_CLIENT_API);
major = glfwGetWindowParam(window, GLFW_OPENGL_VERSION_MAJOR);
minor = glfwGetWindowParam(window, GLFW_OPENGL_VERSION_MINOR);
revision = glfwGetWindowParam(window, GLFW_OPENGL_REVISION);
printf("OpenGL context version parsed by GLFW: %u.%u.%u\n", major, minor, revision);
printf("%s context version string: \"%s\"\n",
get_client_api_name(api),
glGetString(GL_VERSION));
// Report OpenGL context properties
printf("%s context version parsed by GLFW: %u.%u.%u\n",
get_client_api_name(api),
major, minor, revision);
if (major >= 3)
// Report client API context properties
if (api == GLFW_OPENGL_API)
{
glGetIntegerv(GL_CONTEXT_FLAGS, &flags);
printf("OpenGL context flags:");
if (major >= 3)
{
glGetIntegerv(GL_CONTEXT_FLAGS, &flags);
printf("%s context flags:", get_client_api_name(api));
if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
puts(" forward-compatible");
else
puts(" none");
if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
puts(" forward-compatible");
else
puts(" none");
printf("OpenGL forward-compatible flag parsed by GLFW: %s\n",
glfwGetWindowParam(window, GLFW_OPENGL_FORWARD_COMPAT) ? "true" : "false");
printf("%s forward-compatible flag parsed by GLFW: %s\n",
get_client_api_name(api),
glfwGetWindowParam(window, GLFW_OPENGL_FORWARD_COMPAT) ? "true" : "false");
}
if (major > 3 || (major == 3 && minor >= 2))
{
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask);
printf("%s profile mask: %s (0x%08x)\n",
get_client_api_name(api),
get_profile_name(mask), mask);
printf("%s profile parsed by GLFW: %s\n",
get_client_api_name(api),
get_glfw_profile_name(glfwGetWindowParam(window, GLFW_OPENGL_PROFILE)));
}
}
if (major > 3 || (major == 3 && minor >= 2))
{
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask);
printf("OpenGL profile mask: %s (0x%08x)\n", get_profile_name(mask), mask);
printf("OpenGL profile parsed by GLFW: %s\n",
get_glfw_profile_name(glfwGetWindowParam(window, GLFW_OPENGL_PROFILE)));
}
printf("OpenGL context renderer string: \"%s\"\n", glGetString(GL_RENDERER));
printf("OpenGL context vendor string: \"%s\"\n", glGetString(GL_VENDOR));
printf("%s context renderer string: \"%s\"\n",
get_client_api_name(api),
glGetString(GL_RENDERER));
printf("%s context vendor string: \"%s\"\n",
get_client_api_name(api),
glGetString(GL_VENDOR));
if (major > 1)
{
printf("OpenGL context shading language version: \"%s\"\n",
printf("%s context shading language version: \"%s\"\n",
get_client_api_name(api),
glGetString(GL_SHADING_LANGUAGE_VERSION));
}
// Report OpenGL extensions
// Report client API extensions
if (list)
list_extensions(major, minor);
list_extensions(api, major, minor);
glfwTerminate();
exit(EXIT_SUCCESS);