Added support for OpenGL ES 2.0.

This commit is contained in:
Camilla Berglund 2010-11-15 19:28:06 +01:00
parent 36e5409224
commit 88194055bb
9 changed files with 104 additions and 15 deletions

View File

@ -338,6 +338,7 @@ extern "C" {
/* GLFW_OPENGL_PROFILE tokens */ /* GLFW_OPENGL_PROFILE tokens */
#define GLFW_OPENGL_CORE_PROFILE 0x00050001 #define GLFW_OPENGL_CORE_PROFILE 0x00050001
#define GLFW_OPENGL_COMPAT_PROFILE 0x00050002 #define GLFW_OPENGL_COMPAT_PROFILE 0x00050002
#define GLFW_OPENGL_ES2_PROFILE 0x00050004
/* glfwEnable/glfwDisable tokens */ /* glfwEnable/glfwDisable tokens */
#define GLFW_MOUSE_CURSOR 0x00030001 #define GLFW_MOUSE_CURSOR 0x00030001

View File

@ -271,6 +271,7 @@ version of GLFW.</p>
<li>Added <code>glfwSetWindowFocusCallback</code> function and <code>GLFWwindowfocusfun</code> type for receiving window focus events</li> <li>Added <code>glfwSetWindowFocusCallback</code> function and <code>GLFWwindowfocusfun</code> type for receiving window focus events</li>
<li>Added <code>glfwSetWindowIconifyCallback</code> function and <code>GLFWwindowiconifyfun</code> type for receiving window iconification events</li> <li>Added <code>glfwSetWindowIconifyCallback</code> function and <code>GLFWwindowiconifyfun</code> type for receiving window iconification events</li>
<li>Added <code>glfwGetCurrentWindow</code> function for retrieving the window whose OpenGL context is current</li> <li>Added <code>glfwGetCurrentWindow</code> function for retrieving the window whose OpenGL context is current</li>
<li>Added <code>GLFW_OPENGL_ES2_PROFILE</code> profile for creating OpenGL ES 2.0 contexts</li>
<li>Added <code>windows</code> simple multi-window test program</li> <li>Added <code>windows</code> simple multi-window test program</li>
<li>Added <code>sharing</code> simple OpenGL object sharing test program</li> <li>Added <code>sharing</code> simple OpenGL object sharing test program</li>
<li>Added a parameter to <code>glfwOpenWindow</code> for specifying a context the new window's context will share objects with</li> <li>Added a parameter to <code>glfwOpenWindow</code> for specifying a context the new window's context will share objects with</li>

View File

@ -51,12 +51,21 @@ void _glfwParseGLVersion(int* major, int* minor, int* rev)
GLuint _major, _minor = 0, _rev = 0; GLuint _major, _minor = 0, _rev = 0;
const GLubyte* version; const GLubyte* version;
const GLubyte* ptr; const GLubyte* ptr;
const char* glesPrefix = "OpenGL ES ";
// Get OpenGL version string // Get OpenGL version string
version = glGetString(GL_VERSION); version = glGetString(GL_VERSION);
if (!version) if (!version)
return; return;
if (strncmp(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 string // Parse string
ptr = version; ptr = version;
for (_major = 0; *ptr >= '0' && *ptr <= '9'; ptr++) for (_major = 0; *ptr >= '0' && *ptr <= '9'; ptr++)

View File

@ -241,6 +241,8 @@ typedef struct _GLFWcontextWGL
GLboolean has_WGL_ARB_multisample; GLboolean has_WGL_ARB_multisample;
GLboolean has_WGL_ARB_pixel_format; GLboolean has_WGL_ARB_pixel_format;
GLboolean has_WGL_ARB_create_context; GLboolean has_WGL_ARB_create_context;
GLboolean has_WGL_ARB_create_context_profile;
GLboolean has_WGL_EXT_create_context_es2_profile;
} _GLFWcontextWGL; } _GLFWcontextWGL;

View File

@ -316,7 +316,7 @@ static GLboolean createContext(_GLFWwindow* window,
int pixelFormat) int pixelFormat)
{ {
PIXELFORMATDESCRIPTOR pfd; PIXELFORMATDESCRIPTOR pfd;
int flags, i = 0, attribs[7]; int i = 0, attribs[7];
HGLRC share = NULL; HGLRC share = NULL;
if (wndconfig->share) if (wndconfig->share)
@ -350,7 +350,7 @@ static GLboolean createContext(_GLFWwindow* window,
if (wndconfig->glForward || wndconfig->glDebug) if (wndconfig->glForward || wndconfig->glDebug)
{ {
flags = 0; int flags = 0;
if (wndconfig->glForward) if (wndconfig->glForward)
flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
@ -364,10 +364,27 @@ static GLboolean createContext(_GLFWwindow* window,
if (wndconfig->glProfile) if (wndconfig->glProfile)
{ {
int flags = 0;
if (!window->WGL.has_WGL_ARB_create_context_profile)
{
_glfwSetError(GLFW_VERSION_UNAVAILABLE);
return GL_FALSE;
}
if (wndconfig->glProfile == GLFW_OPENGL_ES2_PROFILE &&
!window->WGL.has_WGL_EXT_create_context_es2_profile)
{
_glfwSetError(GLFW_VERSION_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 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;
@ -1008,6 +1025,7 @@ static void initWGLExtensions(_GLFWwindow* window)
window->WGL.has_WGL_ARB_pixel_format = GL_FALSE; window->WGL.has_WGL_ARB_pixel_format = GL_FALSE;
window->WGL.has_WGL_ARB_multisample = GL_FALSE; window->WGL.has_WGL_ARB_multisample = GL_FALSE;
window->WGL.has_WGL_ARB_create_context = GL_FALSE; window->WGL.has_WGL_ARB_create_context = GL_FALSE;
window->WGL.has_WGL_ARB_create_context_profile = GL_FALSE;
window->WGL.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC) window->WGL.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)
wglGetProcAddress("wglGetExtensionsStringEXT"); wglGetProcAddress("wglGetExtensionsStringEXT");
@ -1031,6 +1049,19 @@ static void initWGLExtensions(_GLFWwindow* window)
window->WGL.has_WGL_ARB_create_context = GL_TRUE; window->WGL.has_WGL_ARB_create_context = GL_TRUE;
} }
if (window->WGL.has_WGL_ARB_create_context)
{
if (_glfwPlatformExtensionSupported("WGL_ARB_create_context_profile"))
window->WGL.has_WGL_ARB_create_context_profile = GL_TRUE;
}
if (window->WGL.has_WGL_ARB_create_context &&
window->WGL.has_WGL_ARB_create_context_profile)
{
if (_glfwPlatformExtensionSupported("WGL_EXT_create_context_es2_profile"))
window->WGL.has_WGL_EXT_create_context_es2_profile = GL_TRUE;
}
if (_glfwPlatformExtensionSupported("WGL_EXT_swap_control")) if (_glfwPlatformExtensionSupported("WGL_EXT_swap_control"))
{ {
window->WGL.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) window->WGL.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)

View File

@ -490,14 +490,31 @@ GLFWAPI GLFWwindow glfwOpenWindow(int width, int height,
// For now, let everything else through // For now, let everything else through
} }
if (wndconfig.glProfile && if (wndconfig.glProfile == GLFW_OPENGL_ES2_PROFILE)
(wndconfig.glMajor < 3 || (wndconfig.glMajor == 3 && wndconfig.glMinor < 2)))
{ {
// Context profiles are only defined for OpenGL version 3.2 and above if (wndconfig.glMajor != 2 || wndconfig.glMinor < 0)
{
// The OpenGL ES 2.0 profile is currently only defined for version
// 2.0, but for compatibility with future updates to OpenGL ES, we
// allow everything 2.x and let the driver report invalid versions
glfwCloseWindow(window); glfwCloseWindow(window);
_glfwSetError(GLFW_INVALID_VALUE); _glfwSetError(GLFW_INVALID_VALUE);
return GL_FALSE; return GL_FALSE;
} }
}
else if (wndconfig.glProfile)
{
if (wndconfig.glMajor < 3 || (wndconfig.glMajor == 3 && wndconfig.glMinor < 2))
{
// Desktop OpenGL context profiles are only defined for version 3.2
// and above
glfwCloseWindow(window);
_glfwSetError(GLFW_INVALID_VALUE);
return GL_FALSE;
}
}
if (wndconfig.glForward && wndconfig.glMajor < 3) if (wndconfig.glForward && wndconfig.glMajor < 3)
{ {

View File

@ -110,6 +110,7 @@ typedef struct _GLFWcontextGLX
GLboolean has_GLX_ARB_multisample; GLboolean has_GLX_ARB_multisample;
GLboolean has_GLX_ARB_create_context; GLboolean has_GLX_ARB_create_context;
GLboolean has_GLX_ARB_create_context_profile; GLboolean has_GLX_ARB_create_context_profile;
GLboolean has_GLX_EXT_create_context_es2_profile;
} _GLFWcontextGLX; } _GLFWcontextGLX;

View File

@ -490,7 +490,7 @@ static int createContext(_GLFWwindow* window,
GLXFBConfigID fbconfigID) GLXFBConfigID fbconfigID)
{ {
int attribs[40]; int attribs[40];
int flags, dummy, index; int dummy, index;
GLXFBConfig* fbconfig; GLXFBConfig* fbconfig;
GLXContext share = NULL; GLXContext share = NULL;
@ -562,7 +562,7 @@ static int createContext(_GLFWwindow* window,
if (wndconfig->glForward || wndconfig->glDebug) if (wndconfig->glForward || wndconfig->glDebug)
{ {
flags = 0; int flags = 0;
if (wndconfig->glForward) if (wndconfig->glForward)
flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
@ -575,6 +575,8 @@ static int createContext(_GLFWwindow* window,
if (wndconfig->glProfile) if (wndconfig->glProfile)
{ {
int flags = 0;
if (!window->GLX.has_GLX_ARB_create_context_profile) if (!window->GLX.has_GLX_ARB_create_context_profile)
{ {
fprintf(stderr, "OpenGL profile requested but GLX_ARB_create_context_profile " fprintf(stderr, "OpenGL profile requested but GLX_ARB_create_context_profile "
@ -583,10 +585,21 @@ static int createContext(_GLFWwindow* window,
return GL_FALSE; return GL_FALSE;
} }
if (wndconfig->glProfile == GLFW_OPENGL_ES2_PROFILE &&
!window->GLX.has_GLX_EXT_create_context_es2_profile)
{
fprintf(stderr, "OpenGL ES2 profile requested but "
"GLX_EXT_create_context_es2_profile is unavailable\n");
_glfwSetError(GLFW_VERSION_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 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);
} }
@ -695,8 +708,18 @@ static void initGLXExtensions(_GLFWwindow* window)
window->GLX.has_GLX_ARB_create_context = GL_TRUE; window->GLX.has_GLX_ARB_create_context = GL_TRUE;
} }
if (window->GLX.has_GLX_ARB_create_context)
{
if (_glfwPlatformExtensionSupported("GLX_ARB_create_context_profile")) if (_glfwPlatformExtensionSupported("GLX_ARB_create_context_profile"))
window->GLX.has_GLX_ARB_create_context_profile = GL_TRUE; window->GLX.has_GLX_ARB_create_context_profile = GL_TRUE;
}
if (window->GLX.has_GLX_ARB_create_context &&
window->GLX.has_GLX_ARB_create_context_profile)
{
if (_glfwPlatformExtensionSupported("GLX_EXT_create_context_es2_profile"))
window->GLX.has_GLX_EXT_create_context_es2_profile = GL_TRUE;
}
} }

View File

@ -45,7 +45,7 @@
static void usage(void) static void usage(void)
{ {
printf("Usage: version [-h] [-m MAJOR] [-n MINOR] [-d] [-l] [-f] [-p PROFILE]\n"); printf("Usage: version [-h] [-m MAJOR] [-n MINOR] [-d] [-l] [-f] [-p PROFILE]\n");
printf("available profiles: core compat\n"); printf("available profiles: core compat es2\n");
} }
static const char* get_glfw_profile_name(int profile) static const char* get_glfw_profile_name(int profile)
@ -54,6 +54,8 @@ static const char* get_glfw_profile_name(int profile)
return "compatibility"; return "compatibility";
else if (profile == GLFW_OPENGL_CORE_PROFILE) else if (profile == GLFW_OPENGL_CORE_PROFILE)
return "core"; return "core";
else if (profile == GLFW_OPENGL_ES2_PROFILE)
return "es2";
return "unknown"; return "unknown";
} }
@ -141,6 +143,8 @@ int main(int argc, char** argv)
profile = GLFW_OPENGL_CORE_PROFILE; profile = GLFW_OPENGL_CORE_PROFILE;
else if (strcasecmp(optarg, "compat") == 0) else if (strcasecmp(optarg, "compat") == 0)
profile = GLFW_OPENGL_COMPAT_PROFILE; profile = GLFW_OPENGL_COMPAT_PROFILE;
else if (strcasecmp(optarg, "es2") == 0)
profile = GLFW_OPENGL_ES2_PROFILE;
else else
{ {
usage(); usage();