// // Book: OpenGL(R) ES 2.0 Programming Guide // Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner // ISBN-10: 0321502795 // ISBN-13: 9780321502797 // Publisher: Addison-Wesley Professional // URLs: http://safari.informit.com/9780321563835 // http://www.opengles-book.com // // ESUtil.c // // A utility library for OpenGL ES. This library provides a // basic common framework for the example applications in the // OpenGL ES 2.0 Programming Guide. // /// // Includes // #include #include #if __APPLE__ #include #include #include #include #else #include #include #include #endif #include "esUtil.h" #if defined(_MSC_VER) #pragma warning(disable: 4204) // nonstandard extension used : non-constant aggregate initializer #endif /// // Extensions // PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR; PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR; PFNEGLPOSTSUBBUFFERNVPROC eglPostSubBufferNV; /*PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES; PFNGLDELETEFENCESNVPROC glDeleteFencesNV; PFNGLGENFENCESNVPROC glGenFencesNV; PFNGLGETFENCEIVNVPROC glGetFenceivNV; PFNGLISFENCENVPROC glIsFenceNV; PFNGLFINISHFENCENVPROC glFinishFenceNV; PFNGLSETFENCENVPROC glSetFenceNV; PFNGLTESTFENCENVPROC glTestFenceNV; */ /// // CreateEGLContext() // // Creates an EGL rendering context and all associated elements // EGLBoolean CreateEGLContext ( EGLNativeWindowType hWnd, EGLDisplay* eglDisplay, EGLContext* eglContext, EGLSurface* eglSurface, EGLint* configAttribList, EGLint* surfaceAttribList) { EGLint numConfigs; EGLint majorVersion; EGLint minorVersion; EGLDisplay display; EGLContext context; EGLSurface surface; EGLConfig config; EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE, EGL_NONE }; // Get Display display = eglGetDisplay(GetDC(hWnd)); if ( display == EGL_NO_DISPLAY ) { return EGL_FALSE; } // Initialize EGL if ( !eglInitialize(display, &majorVersion, &minorVersion) ) { return EGL_FALSE; } // Bind to extensions eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC) eglGetProcAddress("eglCreateImageKHR"); eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC) eglGetProcAddress("eglDestroyImageKHR"); eglPostSubBufferNV = (PFNEGLPOSTSUBBUFFERNVPROC) eglGetProcAddress("eglPostSubBufferNV"); /*glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) eglGetProcAddress("glEGLImageTargetTexture2DOES"); glDeleteFencesNV = (PFNGLDELETEFENCESNVPROC) eglGetProcAddress("glDeleteFencesNV"); glGenFencesNV = (PFNGLGENFENCESNVPROC) eglGetProcAddress("glGenFencesNV"); glGetFenceivNV = (PFNGLGETFENCEIVNVPROC) eglGetProcAddress("glGetFenceivNV"); glIsFenceNV = (PFNGLISFENCENVPROC) eglGetProcAddress("glIsFenceNV"); glFinishFenceNV = (PFNGLFINISHFENCENVPROC) eglGetProcAddress("glFinishFenceNV"); glSetFenceNV = (PFNGLSETFENCENVPROC) eglGetProcAddress("glSetFenceNV"); glTestFenceNV = (PFNGLTESTFENCENVPROC) eglGetProcAddress("glTestFenceNV"); */ // Get configs if ( !eglGetConfigs(display, NULL, 0, &numConfigs) ) { return EGL_FALSE; } // Choose config if ( !eglChooseConfig(display, configAttribList, &config, 1, &numConfigs) ) { return EGL_FALSE; } // Create a surface surface = eglCreateWindowSurface(display, config, (EGLNativeWindowType)hWnd, surfaceAttribList); if ( surface == EGL_NO_SURFACE ) { return EGL_FALSE; } // Create a GL context context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs ); if ( context == EGL_NO_CONTEXT ) { return EGL_FALSE; } // Make the context current if ( !eglMakeCurrent(display, surface, surface, context) ) { return EGL_FALSE; } *eglDisplay = display; *eglSurface = surface; *eglContext = context; return EGL_TRUE; } ////////////////////////////////////////////////////////////////// // // Public Functions // // /// // esInitContext() // // Initialize ES utility context. This must be called before calling any other // functions. // void ESUTIL_API esInitContext ( ESContext *esContext ) { if ( esContext != NULL ) { memset( esContext, 0, sizeof( ESContext) ); } } /// // esCreateWindow() // // title - name for title bar of window // width - width of window to create // height - height of window to create // flags - bitwise or of window creation flags // ES_WINDOW_ALPHA - specifies that the framebuffer should have alpha // ES_WINDOW_DEPTH - specifies that a depth buffer should be created // ES_WINDOW_STENCIL - specifies that a stencil buffer should be created // ES_WINDOW_MULTISAMPLE - specifies that a multi-sample buffer should be created // ES_WINDOW_POST_SUB_BUFFER_SUPPORTED - specifies that EGL_POST_SUB_BUFFER_NV is supported. // GLboolean ESUTIL_API esCreateWindow ( ESContext *esContext, LPCTSTR title, GLint width, GLint height, GLuint flags ) { /* EGLint configAttribList[] = { EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_ALPHA_SIZE, (flags & ES_WINDOW_ALPHA) ? 8 : EGL_DONT_CARE, EGL_DEPTH_SIZE, (flags & ES_WINDOW_DEPTH) ? 8 : EGL_DONT_CARE, EGL_STENCIL_SIZE, (flags & ES_WINDOW_STENCIL) ? 8 : EGL_DONT_CARE, EGL_SAMPLE_BUFFERS, (flags & ES_WINDOW_MULTISAMPLE) ? 1 : 0, EGL_NONE }; EGLint surfaceAttribList[] = { EGL_POST_SUB_BUFFER_SUPPORTED_NV, flags & (ES_WINDOW_POST_SUB_BUFFER_SUPPORTED) ? EGL_TRUE : EGL_FALSE, EGL_NONE, EGL_NONE }; if ( esContext == NULL ) { return GL_FALSE; } esContext->width = width; esContext->height = height; if ( !WinCreate ( esContext, title) ) { return GL_FALSE; } if ( !CreateEGLContext ( esContext->hWnd, &esContext->eglDisplay, &esContext->eglContext, &esContext->eglSurface, configAttribList, surfaceAttribList ) ) { return GL_FALSE; } */ return GL_TRUE; } /// // esCreateContext() // // title - name for title bar of window // width - width of window to create // height - height of window to create // flags - bitwise or of window creation flags // ES_WINDOW_ALPHA - specifies that the framebuffer should have alpha // ES_WINDOW_DEPTH - specifies that a depth buffer should be created // ES_WINDOW_STENCIL - specifies that a stencil buffer should be created // ES_WINDOW_MULTISAMPLE - specifies that a multi-sample buffer should be created // ES_WINDOW_POST_SUB_BUFFER_SUPPORTED - specifies that EGL_POST_SUB_BUFFER_NV is supported. // GLboolean ESUTIL_API esCreateContext ( ESContext *esContext, GLuint flags ) { EGLint configAttribList[] = { EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_ALPHA_SIZE, (flags & ES_WINDOW_ALPHA) ? 8 : EGL_DONT_CARE, EGL_DEPTH_SIZE, (flags & ES_WINDOW_DEPTH) ? 8 : EGL_DONT_CARE, EGL_STENCIL_SIZE, (flags & ES_WINDOW_STENCIL) ? 8 : EGL_DONT_CARE, EGL_SAMPLE_BUFFERS, (flags & ES_WINDOW_MULTISAMPLE) ? 1 : 0, //EGL_SAMPLES, 2, EGL_NONE }; EGLint surfaceAttribList[] = { EGL_POST_SUB_BUFFER_SUPPORTED_NV, flags & (ES_WINDOW_POST_SUB_BUFFER_SUPPORTED) ? EGL_TRUE : EGL_FALSE, EGL_NONE, EGL_NONE }; RECT wndRect; if ( esContext == NULL ) { return GL_FALSE; } GetClientRect( esContext->hWnd, &wndRect ); esContext->width = wndRect.right-wndRect.left; esContext->height = wndRect.bottom-wndRect.top; if ( !CreateEGLContext ( esContext->hWnd, &esContext->eglDisplay, &esContext->eglContext, &esContext->eglSurface, configAttribList, surfaceAttribList ) ) { return GL_FALSE; } return GL_TRUE; } /// // esRegisterDrawFunc() // void ESUTIL_API esRegisterDrawFunc ( ESContext *esContext, void (ESCALLBACK *drawFunc) (ESContext* ) ) { esContext->drawFunc = drawFunc; } /// // esRegisterUpdateFunc() // void ESUTIL_API esRegisterUpdateFunc ( ESContext *esContext, void (ESCALLBACK *updateFunc) ( ESContext*, float ) ) { esContext->updateFunc = updateFunc; } /// // esRegisterKeyFunc() // void ESUTIL_API esRegisterKeyFunc ( ESContext *esContext, void (ESCALLBACK *keyFunc) (ESContext*, unsigned char, int, int ) ) { esContext->keyFunc = keyFunc; } /// // esLogMessage() // // Log an error message to the debug output for the platform // void ESUTIL_API esLogMessage ( const char *formatStr, ... ) { va_list params; char buf[BUFSIZ]; va_start ( params, formatStr ); vsprintf_s ( buf, sizeof(buf), formatStr, params ); printf ( "%s", buf ); va_end ( params ); }