Added client API window hint.

This is cherry-picked from the EGL branch in preparation for the EGL backend.
This commit is contained in:
Camilla Berglund 2012-09-30 15:32:50 +02:00
parent 410a4e29e1
commit 38cad9aff0
9 changed files with 250 additions and 153 deletions

View File

@ -404,14 +404,19 @@ extern "C" {
/* The following constants are used with both glfwGetWindowParam /* The following constants are used with both glfwGetWindowParam
* and glfwWindowHint * and glfwWindowHint
*/ */
#define GLFW_OPENGL_VERSION_MAJOR 0x00022000 #define GLFW_CLIENT_API 0x00022000
#define GLFW_OPENGL_VERSION_MINOR 0x00022001 #define GLFW_OPENGL_VERSION_MAJOR 0x00022001
#define GLFW_OPENGL_FORWARD_COMPAT 0x00022002 #define GLFW_OPENGL_VERSION_MINOR 0x00022002
#define GLFW_OPENGL_DEBUG_CONTEXT 0x00022003 #define GLFW_OPENGL_FORWARD_COMPAT 0x00022003
#define GLFW_OPENGL_PROFILE 0x00022004 #define GLFW_OPENGL_DEBUG_CONTEXT 0x00022004
#define GLFW_OPENGL_ROBUSTNESS 0x00022005 #define GLFW_OPENGL_PROFILE 0x00022005
#define GLFW_RESIZABLE 0x00022006 #define GLFW_OPENGL_ROBUSTNESS 0x00022006
#define GLFW_VISIBLE 0x00022007 #define GLFW_RESIZABLE 0x00022007
#define GLFW_VISIBLE 0x00022008
/* GLFW_CLIENT_API tokens */
#define GLFW_OPENGL_API 0x00000001
#define GLFW_OPENGL_ES_API 0x00000002
/* GLFW_OPENGL_ROBUSTNESS mode tokens */ /* GLFW_OPENGL_ROBUSTNESS mode tokens */
#define GLFW_OPENGL_NO_ROBUSTNESS 0x00000000 #define GLFW_OPENGL_NO_ROBUSTNESS 0x00000000
@ -422,7 +427,6 @@ extern "C" {
#define GLFW_OPENGL_NO_PROFILE 0x00000000 #define GLFW_OPENGL_NO_PROFILE 0x00000000
#define GLFW_OPENGL_CORE_PROFILE 0x00000001 #define GLFW_OPENGL_CORE_PROFILE 0x00000001
#define GLFW_OPENGL_COMPAT_PROFILE 0x00000002 #define GLFW_OPENGL_COMPAT_PROFILE 0x00000002
#define GLFW_OPENGL_ES2_PROFILE 0x00000004
/* glfwGetInputMode/glfwSetInputMode tokens */ /* glfwGetInputMode/glfwSetInputMode tokens */
#define GLFW_CURSOR_MODE 0x00030001 #define GLFW_CURSOR_MODE 0x00030001

View File

@ -279,7 +279,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>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>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>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>, <code>GLFW_OPENGL_API</code> and <code>GLFW_OPENGL_ES_API</code> for selecting client API</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_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_OPENGL_REVISION</code> window parameter to make up for removal of <code>glfwGetGLVersion</code></li>
<li>Added <code>GLFW_INCLUDE_GLCOREARB</code> macro for including <code>glcorearb.h</code> instead of <code>gl.h</code></li> <li>Added <code>GLFW_INCLUDE_GLCOREARB</code> macro for including <code>glcorearb.h</code> instead of <code>gl.h</code></li>

View File

@ -729,6 +729,13 @@ static GLboolean createContext(_GLFWwindow* window,
else if (colorBits < 15) else if (colorBits < 15)
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 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
// Fail if any OpenGL version above 2.1 other than 3.2 was requested // Fail if any OpenGL version above 2.1 other than 3.2 was requested
if (wndconfig->glMajor > 3 || if (wndconfig->glMajor > 3 ||

View File

@ -100,6 +100,7 @@ struct _GLFWhints
GLboolean resizable; GLboolean resizable;
GLboolean visible; GLboolean visible;
int samples; int samples;
int clientAPI;
int glMajor; int glMajor;
int glMinor; int glMinor;
GLboolean glForward; GLboolean glForward;
@ -122,6 +123,7 @@ struct _GLFWwndconfig
int refreshRate; int refreshRate;
GLboolean resizable; GLboolean resizable;
GLboolean visible; GLboolean visible;
int clientAPI;
int glMajor; int glMajor;
int glMinor; int glMinor;
GLboolean glForward; GLboolean glForward;
@ -188,6 +190,7 @@ struct _GLFWwindow
char key[GLFW_KEY_LAST + 1]; char key[GLFW_KEY_LAST + 1];
// OpenGL extensions and context attributes // OpenGL extensions and context attributes
int clientAPI;
int glMajor, glMinor, glRevision; int glMajor, glMinor, glRevision;
GLboolean glForward, glDebug; GLboolean glForward, glDebug;
int glProfile; int glProfile;

View File

@ -36,15 +36,17 @@
//======================================================================== //========================================================================
// Parses the OpenGL version string and extracts the version number // Parses the client API version string and extracts the version number
//======================================================================== //========================================================================
static GLboolean parseGLVersion(int* major, int* minor, int* rev) static GLboolean parseGLVersion(int* api, int* major, int* minor, int* rev)
{ {
int i, _major, _minor = 0, _rev = 0; int i, _api = GLFW_OPENGL_API, _major, _minor = 0, _rev = 0;
const char* version; const char* version;
const char* prefixes[] = const char* prefixes[] =
{ {
"OpenGL ES-CM ",
"OpenGL ES-CL ",
"OpenGL ES ", "OpenGL ES ",
NULL NULL
}; };
@ -63,6 +65,7 @@ static GLboolean parseGLVersion(int* major, int* minor, int* rev)
if (strncmp(version, prefixes[i], length) == 0) if (strncmp(version, prefixes[i], length) == 0)
{ {
version += length; version += length;
_api = GLFW_OPENGL_ES_API;
break; break;
} }
} }
@ -73,6 +76,7 @@ static GLboolean parseGLVersion(int* major, int* minor, int* rev)
return GL_FALSE; return GL_FALSE;
} }
*api = _api;
*major = _major; *major = _major;
*minor = _minor; *minor = _minor;
*rev = _rev; *rev = _rev;
@ -248,6 +252,16 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
//======================================================================== //========================================================================
GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig) GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig)
{
if (wndconfig->clientAPI != GLFW_OPENGL_API &&
wndconfig->clientAPI != GLFW_OPENGL_ES_API)
{
_glfwSetError(GLFW_INVALID_ENUM,
"glfwCreateWindow: Invalid client API requested");
return GL_FALSE;
}
if (wndconfig->clientAPI == GLFW_OPENGL_API)
{ {
if (wndconfig->glMajor < 1 || wndconfig->glMinor < 0) if (wndconfig->glMajor < 1 || wndconfig->glMinor < 0)
{ {
@ -282,21 +296,7 @@ GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig)
// For now, let everything else through // For now, let everything else through
} }
if (wndconfig->glProfile == GLFW_OPENGL_ES2_PROFILE) if (wndconfig->glProfile)
{
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,
"glfwCreateWindow: Invalid OpenGL ES 2.x version requested");
return GL_FALSE;
}
}
else if (wndconfig->glProfile)
{ {
if (wndconfig->glProfile != GLFW_OPENGL_CORE_PROFILE && if (wndconfig->glProfile != GLFW_OPENGL_CORE_PROFILE &&
wndconfig->glProfile != GLFW_OPENGL_COMPAT_PROFILE) wndconfig->glProfile != GLFW_OPENGL_COMPAT_PROFILE)
@ -323,10 +323,50 @@ GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig)
{ {
// Forward-compatible contexts are only defined for OpenGL version 3.0 and above // Forward-compatible contexts are only defined for OpenGL version 3.0 and above
_glfwSetError(GLFW_INVALID_VALUE, _glfwSetError(GLFW_INVALID_VALUE,
"glfwCreateWindow: Forward compatibility only exist for " "glfwCreateWindow: Forward compatibility only exist "
"OpenGL version 3.0 and above"); "for OpenGL version 3.0 and above");
return GL_FALSE; return GL_FALSE;
} }
}
else if (wndconfig->clientAPI == GLFW_OPENGL_ES_API)
{
if (wndconfig->glMajor < 1 || wndconfig->glMinor < 0)
{
// OpenGL ES 1.0 is the smallest valid version
_glfwSetError(GLFW_INVALID_VALUE,
"glfwCreateWindow: 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,
"glfwCreateWindow: 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,
"glfwCreateWindow: 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,
"glfwCreateWindow: Forward compatibility is not "
"supported by OpenGL ES");
return GL_FALSE;
}
}
if (wndconfig->glRobustness) if (wndconfig->glRobustness)
{ {
@ -334,7 +374,8 @@ GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig)
wndconfig->glRobustness != GLFW_OPENGL_LOSE_CONTEXT_ON_RESET) wndconfig->glRobustness != GLFW_OPENGL_LOSE_CONTEXT_ON_RESET)
{ {
_glfwSetError(GLFW_INVALID_VALUE, _glfwSetError(GLFW_INVALID_VALUE,
"glfwCreateWindow: Invalid OpenGL robustness mode requested"); "glfwCreateWindow: Invalid OpenGL robustness mode "
"requested");
return GL_FALSE; return GL_FALSE;
} }
} }
@ -352,7 +393,8 @@ GLboolean _glfwRefreshContextParams(void)
{ {
_GLFWwindow* window = _glfwPlatformGetCurrentContext(); _GLFWwindow* window = _glfwPlatformGetCurrentContext();
if (!parseGLVersion(&window->glMajor, if (!parseGLVersion(&window->clientAPI,
&window->glMajor,
&window->glMinor, &window->glMinor,
&window->glRevision)) &window->glRevision))
{ {
@ -378,7 +420,7 @@ GLboolean _glfwRefreshContextParams(void)
{ {
window->glForward = GL_FALSE; window->glForward = GL_FALSE;
if (window->glMajor >= 3) if (window->clientAPI == GLFW_OPENGL_API && window->glMajor >= 3)
{ {
GLint flags; GLint flags;
glGetIntegerv(GL_CONTEXT_FLAGS, &flags); glGetIntegerv(GL_CONTEXT_FLAGS, &flags);

View File

@ -356,6 +356,21 @@ static GLboolean createContext(_GLFWwindow* window,
attribs[i++] = wndconfig->glMinor; 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) if (wndconfig->glForward || wndconfig->glDebug || wndconfig->glRobustness)
{ {
int flags = 0; int flags = 0;
@ -385,21 +400,10 @@ static GLboolean createContext(_GLFWwindow* window,
return GL_FALSE; return GL_FALSE;
} }
if (wndconfig->glProfile == GLFW_OPENGL_ES2_PROFILE &&
!window->WGL.EXT_create_context_es2_profile)
{
_glfwSetError(GLFW_VERSION_UNAVAILABLE,
"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) if (wndconfig->glProfile == GLFW_OPENGL_CORE_PROFILE)
flags = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; flags = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
else if (wndconfig->glProfile == GLFW_OPENGL_COMPAT_PROFILE) else if (wndconfig->glProfile == GLFW_OPENGL_COMPAT_PROFILE)
flags = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; 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++] = WGL_CONTEXT_PROFILE_MASK_ARB;
attribs[i++] = flags; attribs[i++] = flags;

View File

@ -77,6 +77,7 @@ void _glfwSetDefaultWindowHints(void)
memset(&_glfwLibrary.hints, 0, sizeof(_glfwLibrary.hints)); memset(&_glfwLibrary.hints, 0, sizeof(_glfwLibrary.hints));
// The default minimum OpenGL version is 1.0 // The default minimum OpenGL version is 1.0
_glfwLibrary.hints.clientAPI = GLFW_OPENGL_API;
_glfwLibrary.hints.glMajor = 1; _glfwLibrary.hints.glMajor = 1;
_glfwLibrary.hints.glMinor = 0; _glfwLibrary.hints.glMinor = 0;
@ -262,6 +263,7 @@ GLFWAPI GLFWwindow glfwCreateWindow(int width, int height,
wndconfig.refreshRate = Max(_glfwLibrary.hints.refreshRate, 0); wndconfig.refreshRate = Max(_glfwLibrary.hints.refreshRate, 0);
wndconfig.resizable = _glfwLibrary.hints.resizable ? GL_TRUE : GL_FALSE; wndconfig.resizable = _glfwLibrary.hints.resizable ? GL_TRUE : GL_FALSE;
wndconfig.visible = _glfwLibrary.hints.visible ? GL_TRUE : GL_FALSE; wndconfig.visible = _glfwLibrary.hints.visible ? GL_TRUE : GL_FALSE;
wndconfig.clientAPI = _glfwLibrary.hints.clientAPI;
wndconfig.glMajor = _glfwLibrary.hints.glMajor; wndconfig.glMajor = _glfwLibrary.hints.glMajor;
wndconfig.glMinor = _glfwLibrary.hints.glMinor; wndconfig.glMinor = _glfwLibrary.hints.glMinor;
wndconfig.glForward = _glfwLibrary.hints.glForward ? GL_TRUE : GL_FALSE; wndconfig.glForward = _glfwLibrary.hints.glForward ? GL_TRUE : GL_FALSE;
@ -436,6 +438,9 @@ GLFWAPI void glfwWindowHint(int target, int hint)
case GLFW_FSAA_SAMPLES: case GLFW_FSAA_SAMPLES:
_glfwLibrary.hints.samples = hint; _glfwLibrary.hints.samples = hint;
break; break;
case GLFW_CLIENT_API:
_glfwLibrary.hints.clientAPI = hint;
break;
case GLFW_OPENGL_VERSION_MAJOR: case GLFW_OPENGL_VERSION_MAJOR:
_glfwLibrary.hints.glMajor = hint; _glfwLibrary.hints.glMajor = hint;
break; break;

View File

@ -295,6 +295,22 @@ static int createContext(_GLFWwindow* window,
setGLXattrib(attribs, index, GLX_CONTEXT_MINOR_VERSION_ARB, wndconfig->glMinor); 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,
"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) if (wndconfig->glForward || wndconfig->glDebug || wndconfig->glRobustness)
{ {
int flags = 0; int flags = 0;
@ -323,21 +339,10 @@ static int createContext(_GLFWwindow* window,
return GL_FALSE; return GL_FALSE;
} }
if (wndconfig->glProfile == GLFW_OPENGL_ES2_PROFILE &&
!_glfwLibrary.GLX.EXT_create_context_es2_profile)
{
_glfwSetError(GLFW_VERSION_UNAVAILABLE,
"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) if (wndconfig->glProfile == GLFW_OPENGL_CORE_PROFILE)
flags = GLX_CONTEXT_CORE_PROFILE_BIT_ARB; flags = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
else if (wndconfig->glProfile == GLFW_OPENGL_COMPAT_PROFILE) else if (wndconfig->glProfile == GLFW_OPENGL_COMPAT_PROFILE)
flags = GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; 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); setGLXattrib(attribs, index, GLX_CONTEXT_PROFILE_MASK_ARB, flags);
} }

View File

@ -42,17 +42,20 @@
#define strcasecmp(x, y) _stricmp(x, y) #define strcasecmp(x, y) _stricmp(x, y)
#endif #endif
#define API_OPENGL "gl"
#define API_OPENGL_ES "es"
#define PROFILE_NAME_CORE "core" #define PROFILE_NAME_CORE "core"
#define PROFILE_NAME_COMPAT "compat" #define PROFILE_NAME_COMPAT "compat"
#define PROFILE_NAME_ES2 "es2"
#define STRATEGY_NAME_NONE "none" #define STRATEGY_NAME_NONE "none"
#define STRATEGY_NAME_LOSE "lose" #define STRATEGY_NAME_LOSE "lose"
static void usage(void) static void usage(void)
{ {
printf("Usage: glfwinfo [-h] [-m MAJOR] [-n MINOR] [-d] [-l] [-f] [-p PROFILE] [-r STRATEGY]\n"); printf("Usage: glfwinfo [-h] [-a API] [-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("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"); printf("available strategies: " STRATEGY_NAME_NONE " " STRATEGY_NAME_LOSE "\n");
} }
@ -61,37 +64,35 @@ static void error_callback(int error, const char* description)
fprintf(stderr, "Error: %s in %s\n", glfwErrorString(error), description); fprintf(stderr, "Error: %s in %s\n", glfwErrorString(error), description);
} }
static const char* get_glfw_profile_name(int profile) static const char* get_client_api_name(int api)
{ {
if (profile == GLFW_OPENGL_COMPAT_PROFILE) if (api == GLFW_OPENGL_API)
return PROFILE_NAME_COMPAT; return "OpenGL";
else if (profile == GLFW_OPENGL_CORE_PROFILE) else if (api == GLFW_OPENGL_ES_API)
return PROFILE_NAME_CORE; return "OpenGL ES";
else if (profile == GLFW_OPENGL_ES2_PROFILE)
return PROFILE_NAME_ES2;
return "unknown"; return "Unknown API";
} }
static const char* get_profile_name(GLint mask) static const char* get_profile_name(GLint mask)
{ {
if (mask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) if (mask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT)
return PROFILE_NAME_COMPAT; return "compatibility";
if (mask & GL_CONTEXT_CORE_PROFILE_BIT) if (mask & GL_CONTEXT_CORE_PROFILE_BIT)
return PROFILE_NAME_CORE; return "core";
return "unknown"; return "unknown";
} }
static void list_extensions(int major, int minor) static void list_extensions(int api, int major, int minor)
{ {
int i; int i;
GLint count; GLint count;
const GLubyte* extensions; 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"); PFNGLGETSTRINGIPROC glGetStringi = (PFNGLGETSTRINGIPROC) glfwGetProcAddress("glGetStringi");
if (!glGetStringi) if (!glGetStringi)
@ -147,7 +148,7 @@ static GLboolean valid_version(void)
int main(int argc, char** argv) 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; GLboolean debug = GL_FALSE, forward = GL_FALSE, list = GL_FALSE;
GLint flags, mask; GLint flags, mask;
GLFWwindow window; GLFWwindow window;
@ -155,10 +156,20 @@ int main(int argc, char** argv)
if (!valid_version()) if (!valid_version())
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
while ((ch = getopt(argc, argv, "dfhlm:n:p:r:")) != -1) while ((ch = getopt(argc, argv, "a:dfhlm:n:p:r:")) != -1)
{ {
switch (ch) 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': case 'd':
debug = GL_TRUE; debug = GL_TRUE;
break; break;
@ -182,8 +193,6 @@ int main(int argc, char** argv)
profile = GLFW_OPENGL_CORE_PROFILE; profile = GLFW_OPENGL_CORE_PROFILE;
else if (strcasecmp(optarg, PROFILE_NAME_COMPAT) == 0) else if (strcasecmp(optarg, PROFILE_NAME_COMPAT) == 0)
profile = GLFW_OPENGL_COMPAT_PROFILE; profile = GLFW_OPENGL_COMPAT_PROFILE;
else if (strcasecmp(optarg, PROFILE_NAME_ES2) == 0)
profile = GLFW_OPENGL_ES2_PROFILE;
else else
{ {
usage(); usage();
@ -226,6 +235,9 @@ int main(int argc, char** argv)
glfwWindowHint(GLFW_OPENGL_VERSION_MINOR, minor); glfwWindowHint(GLFW_OPENGL_VERSION_MINOR, minor);
} }
if (api != 0)
glfwWindowHint(GLFW_CLIENT_API, api);
if (debug) if (debug)
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE); glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
@ -249,22 +261,29 @@ int main(int argc, char** argv)
glfwMakeContextCurrent(window); glfwMakeContextCurrent(window);
// Report OpenGL version // Report client API version
printf("OpenGL context version string: \"%s\"\n", glGetString(GL_VERSION));
api = glfwGetWindowParam(window, GLFW_CLIENT_API);
major = glfwGetWindowParam(window, GLFW_OPENGL_VERSION_MAJOR); major = glfwGetWindowParam(window, GLFW_OPENGL_VERSION_MAJOR);
minor = glfwGetWindowParam(window, GLFW_OPENGL_VERSION_MINOR); minor = glfwGetWindowParam(window, GLFW_OPENGL_VERSION_MINOR);
revision = glfwGetWindowParam(window, GLFW_OPENGL_REVISION); 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);
// Report client API context properties
if (api == GLFW_OPENGL_API)
{
if (major >= 3) if (major >= 3)
{ {
glGetIntegerv(GL_CONTEXT_FLAGS, &flags); glGetIntegerv(GL_CONTEXT_FLAGS, &flags);
printf("OpenGL context flags (0x%08x):", flags); printf("%s context flags (0x%08x):", get_client_api_name(api), flags);
if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
printf(" forward-compatible"); printf(" forward-compatible");
@ -272,7 +291,7 @@ int main(int argc, char** argv)
printf(" debug"); printf(" debug");
putchar('\n'); putchar('\n');
printf("OpenGL context flags parsed by GLFW:"); printf("%s context flags parsed by GLFW:", get_client_api_name(api));
if (glfwGetWindowParam(window, GLFW_OPENGL_FORWARD_COMPAT)) if (glfwGetWindowParam(window, GLFW_OPENGL_FORWARD_COMPAT))
printf(" forward-compatible"); printf(" forward-compatible");
@ -284,27 +303,35 @@ int main(int argc, char** argv)
if (major > 3 || (major == 3 && minor >= 2)) if (major > 3 || (major == 3 && minor >= 2))
{ {
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask); glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask);
printf("OpenGL profile mask (0x%08x): %s\n", mask, get_profile_name(mask)); printf("%s profile mask (0x%08x): %s\n",
get_client_api_name(api),
mask,
get_profile_name(mask));
printf("OpenGL profile mask parsed by GLFW: %s\n", printf("%s profile mask parsed by GLFW:\n", get_client_api_name(api));
get_glfw_profile_name(glfwGetWindowParam(window, GLFW_OPENGL_PROFILE)));
} }
}
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));
printf("OpenGL context debug flag saved by GLFW: %s\n", printf("OpenGL context debug flag saved by GLFW: %s\n",
glfwGetWindowParam(window, GLFW_OPENGL_DEBUG_CONTEXT) ? "true" : "false"); glfwGetWindowParam(window, GLFW_OPENGL_DEBUG_CONTEXT) ? "true" : "false");
printf("OpenGL context renderer string: \"%s\"\n", glGetString(GL_RENDERER));
printf("OpenGL context vendor string: \"%s\"\n", glGetString(GL_VENDOR));
if (major > 1) 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)); glGetString(GL_SHADING_LANGUAGE_VERSION));
} }
// Report OpenGL extensions // Report client API extensions
if (list) if (list)
list_extensions(major, minor); list_extensions(api, major, minor);
glfwTerminate(); glfwTerminate();
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);