diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h index 4951c0eb..2e9ba74f 100644 --- a/include/GL/glfw3.h +++ b/include/GL/glfw3.h @@ -400,14 +400,19 @@ extern "C" { /* The following constants are used with both glfwGetWindowParam * and glfwWindowHint */ -#define GLFW_OPENGL_VERSION_MAJOR 0x00022000 -#define GLFW_OPENGL_VERSION_MINOR 0x00022001 -#define GLFW_OPENGL_FORWARD_COMPAT 0x00022002 -#define GLFW_OPENGL_DEBUG_CONTEXT 0x00022003 -#define GLFW_OPENGL_PROFILE 0x00022004 -#define GLFW_OPENGL_ROBUSTNESS 0x00022005 -#define GLFW_RESIZABLE 0x00022006 -#define GLFW_VISIBLE 0x00022007 +#define GLFW_CLIENT_API 0x00022000 +#define GLFW_OPENGL_VERSION_MAJOR 0x00022001 +#define GLFW_OPENGL_VERSION_MINOR 0x00022002 +#define GLFW_OPENGL_FORWARD_COMPAT 0x00022003 +#define GLFW_OPENGL_DEBUG_CONTEXT 0x00022004 +#define GLFW_OPENGL_PROFILE 0x00022005 +#define GLFW_OPENGL_ROBUSTNESS 0x00022006 +#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 */ #define GLFW_OPENGL_NO_ROBUSTNESS 0x00000000 @@ -418,7 +423,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 diff --git a/readme.html b/readme.html index e240edd1..eea96c46 100644 --- a/readme.html +++ b/readme.html @@ -279,7 +279,7 @@ version of GLFW.

  • Added glfwGetClipboardString and glfwSetClipboardString functions for interacting with the system clipboard
  • Added glfwGetCurrentContext function for retrieving the window whose OpenGL context is current
  • Added glfwCopyContext function for copying OpenGL state categories between contexts
  • -
  • Added GLFW_OPENGL_ES2_PROFILE profile for creating OpenGL ES 2.0 contexts using the GLX_EXT_create_context_es2_profile and WGL_EXT_create_context_es2_profile extensions
  • +
  • Added GLFW_CLIENT_API, GLFW_OPENGL_API and GLFW_OPENGL_ES_API for selecting client API
  • Added GLFW_OPENGL_ROBUSTNESS window hint and associated strategy tokens for GL_ARB_robustness support
  • Added GLFW_OPENGL_REVISION window parameter to make up for removal of glfwGetGLVersion
  • Added GLFW_INCLUDE_GLCOREARB macro for including glcorearb.h instead of gl.h
  • diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 844175f6..23fd0257 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -729,6 +729,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 || diff --git a/src/internal.h b/src/internal.h index f2038306..3474e6c9 100755 --- a/src/internal.h +++ b/src/internal.h @@ -101,6 +101,7 @@ struct _GLFWhints GLboolean resizable; GLboolean visible; int samples; + int clientAPI; int glMajor; int glMinor; GLboolean glForward; @@ -122,6 +123,7 @@ struct _GLFWwndconfig int refreshRate; GLboolean resizable; GLboolean visible; + int clientAPI; int glMajor; int glMinor; GLboolean glForward; @@ -190,6 +192,7 @@ struct _GLFWwindow char key[GLFW_KEY_LAST + 1]; // OpenGL extensions and context attributes + int clientAPI; int glMajor, glMinor, glRevision; GLboolean glForward, glDebug; int glProfile; diff --git a/src/opengl.c b/src/opengl.c index 6f80fd7b..482db6ad 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -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* prefixes[] = { + "OpenGL ES-CM ", + "OpenGL ES-CL ", "OpenGL ES ", NULL }; @@ -63,6 +65,7 @@ static GLboolean parseGLVersion(int* major, int* minor, int* rev) if (strncmp(version, prefixes[i], length) == 0) { version += length; + _api = GLFW_OPENGL_ES_API; break; } } @@ -73,6 +76,7 @@ static GLboolean parseGLVersion(int* major, int* minor, int* rev) return GL_FALSE; } + *api = _api; *major = _major; *minor = _minor; *rev = _rev; @@ -249,83 +253,119 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, 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, - "glfwCreateWindow: Invalid OpenGL version requested"); + _glfwSetError(GLFW_INVALID_ENUM, + "glfwCreateWindow: 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, - "glfwCreateWindow: 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, - "glfwCreateWindow: 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, - "glfwCreateWindow: 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, - "glfwCreateWindow: Invalid OpenGL ES 2.x version requested"); + "glfwCreateWindow: 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, - "glfwCreateWindow: 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, - "glfwCreateWindow: Context profiles only exist for " - "OpenGL version 3.2 and above"); + "glfwCreateWindow: 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, + "glfwCreateWindow: 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, + "glfwCreateWindow: 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, + "glfwCreateWindow: 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, + "glfwCreateWindow: 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, + "glfwCreateWindow: 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, - "glfwCreateWindow: 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, + "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) @@ -334,7 +374,8 @@ GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig) wndconfig->glRobustness != GLFW_OPENGL_LOSE_CONTEXT_ON_RESET) { _glfwSetError(GLFW_INVALID_VALUE, - "glfwCreateWindow: Invalid OpenGL robustness mode requested"); + "glfwCreateWindow: Invalid OpenGL robustness mode " + "requested"); return GL_FALSE; } } @@ -352,7 +393,8 @@ GLboolean _glfwRefreshContextParams(void) { _GLFWwindow* window = _glfwPlatformGetCurrentContext(); - if (!parseGLVersion(&window->glMajor, + if (!parseGLVersion(&window->clientAPI, + &window->glMajor, &window->glMinor, &window->glRevision)) { @@ -378,7 +420,7 @@ GLboolean _glfwRefreshContextParams(void) { window->glForward = GL_FALSE; - if (window->glMajor >= 3) + if (window->clientAPI == GLFW_OPENGL_API && window->glMajor >= 3) { GLint flags; glGetIntegerv(GL_CONTEXT_FLAGS, &flags); diff --git a/src/win32_opengl.c b/src/win32_opengl.c index d6e1b490..0bcfe452 100644 --- a/src/win32_opengl.c +++ b/src/win32_opengl.c @@ -356,6 +356,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; @@ -385,21 +400,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, - "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; diff --git a/src/window.c b/src/window.c index f2bff21d..90f9dfc2 100644 --- a/src/window.c +++ b/src/window.c @@ -76,7 +76,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; @@ -84,11 +85,12 @@ void _glfwSetDefaultWindowHints(void) _glfwLibrary.hints.resizable = GL_TRUE; _glfwLibrary.hints.visible = GL_TRUE; - // The default is 24 bits of depth, 8 bits of color - _glfwLibrary.hints.depthBits = 24; - _glfwLibrary.hints.redBits = 8; - _glfwLibrary.hints.greenBits = 8; - _glfwLibrary.hints.blueBits = 8; + // The default is 24 bits of color, 24 bits of depth and 8 bits of stencil + _glfwLibrary.hints.redBits = 8; + _glfwLibrary.hints.greenBits = 8; + _glfwLibrary.hints.blueBits = 8; + _glfwLibrary.hints.depthBits = 24; + _glfwLibrary.hints.stencilBits = 8; } @@ -262,6 +264,7 @@ GLFWAPI GLFWwindow glfwCreateWindow(int width, int height, wndconfig.refreshRate = Max(_glfwLibrary.hints.refreshRate, 0); wndconfig.resizable = _glfwLibrary.hints.resizable ? GL_TRUE : GL_FALSE; wndconfig.visible = _glfwLibrary.hints.visible ? 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; @@ -430,6 +433,9 @@ GLFWAPI void glfwWindowHint(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; @@ -734,6 +740,8 @@ GLFWAPI int glfwGetWindowParam(GLFWwindow handle, int param) return window->resizable; case GLFW_VISIBLE: return window->visible; + case GLFW_CLIENT_API: + return window->clientAPI; case GLFW_OPENGL_VERSION_MAJOR: return window->glMajor; case GLFW_OPENGL_VERSION_MINOR: diff --git a/src/x11_opengl.c b/src/x11_opengl.c index af1e0ffb..19e04a4f 100644 --- a/src/x11_opengl.c +++ b/src/x11_opengl.c @@ -295,6 +295,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, + "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; @@ -323,21 +339,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, - "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); } diff --git a/tests/glfwinfo.c b/tests/glfwinfo.c index be899caf..c4b8fc66 100644 --- a/tests/glfwinfo.c +++ b/tests/glfwinfo.c @@ -42,56 +42,57 @@ #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"); } static void error_callback(int error, const char* description) { - fprintf(stderr, "Error: %s in %s\n", glfwErrorString(error), description); + fprintf(stderr, "Error: %s\n", 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) - return PROFILE_NAME_COMPAT; - else if (profile == GLFW_OPENGL_CORE_PROFILE) - return PROFILE_NAME_CORE; - else if (profile == GLFW_OPENGL_ES2_PROFILE) - return PROFILE_NAME_ES2; + if (api == GLFW_OPENGL_API) + return "OpenGL"; + else if (api == GLFW_OPENGL_ES_API) + return "OpenGL ES"; - return "unknown"; + return "Unknown API"; } 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) @@ -147,7 +148,7 @@ static GLboolean valid_version(void) 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; @@ -155,10 +156,20 @@ int main(int argc, char** argv) if (!valid_version()) 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) { + 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; @@ -182,8 +193,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(); @@ -226,6 +235,9 @@ int main(int argc, char** argv) glfwWindowHint(GLFW_OPENGL_VERSION_MINOR, minor); } + if (api != 0) + glfwWindowHint(GLFW_CLIENT_API, api); + if (debug) glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE); @@ -249,62 +261,77 @@ int main(int argc, char** argv) glfwMakeContextCurrent(window); - // 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 (0x%08x):", flags); + if (major >= 3) + { + glGetIntegerv(GL_CONTEXT_FLAGS, &flags); + printf("%s context flags (0x%08x):", get_client_api_name(api), flags); - if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) - printf(" forward-compatible"); - if (flags & 0) - printf(" debug"); - putchar('\n'); + if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) + printf(" forward-compatible"); + if (flags & 0) + printf(" debug"); + 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)) - printf(" forward-compatible"); - if (glfwGetWindowParam(window, GLFW_OPENGL_DEBUG_CONTEXT)) - printf(" debug"); - putchar('\n'); + if (glfwGetWindowParam(window, GLFW_OPENGL_FORWARD_COMPAT)) + printf(" forward-compatible"); + if (glfwGetWindowParam(window, GLFW_OPENGL_DEBUG_CONTEXT)) + printf(" debug"); + putchar('\n'); + } + + if (major > 3 || (major == 3 && minor >= 2)) + { + glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask); + printf("%s profile mask (0x%08x): %s\n", + get_client_api_name(api), + mask, + get_profile_name(mask)); + + printf("%s profile mask parsed by GLFW:\n", get_client_api_name(api)); + } } - if (major > 3 || (major == 3 && minor >= 2)) - { - glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask); - printf("OpenGL profile mask (0x%08x): %s\n", mask, get_profile_name(mask)); - - printf("OpenGL profile mask parsed by GLFW: %s\n", - 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", 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) { - 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);