Home | History | Annotate | Download | only in Common
      1 //
      2 // Book:      OpenGL(R) ES 2.0 Programming Guide
      3 // Authors:   Aaftab Munshi, Dan Ginsburg, Dave Shreiner
      4 // ISBN-10:   0321502795
      5 // ISBN-13:   9780321502797
      6 // Publisher: Addison-Wesley Professional
      7 // URLs:      http://safari.informit.com/9780321563835
      8 //            http://www.opengles-book.com
      9 //
     10 
     11 // ESUtil.c
     12 //
     13 //    A utility library for OpenGL ES.  This library provides a
     14 //    basic common framework for the example applications in the
     15 //    OpenGL ES 2.0 Programming Guide.
     16 //
     17 
     18 ///
     19 //  Includes
     20 //
     21 #include <stdio.h>
     22 #include <stdlib.h>
     23 #include <GLES2/gl2.h>
     24 #include <EGL/egl.h>
     25 #include <EGL/eglext.h>
     26 #include "esUtil.h"
     27 #include "esUtil_win.h"
     28 
     29 #if defined(_MSC_VER)
     30 #pragma warning(disable: 4204) // nonstandard extension used : non-constant aggregate initializer
     31 #endif
     32 
     33 ///
     34 //  Extensions
     35 //
     36 
     37 PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;
     38 PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR;
     39 
     40 PFNEGLPOSTSUBBUFFERNVPROC eglPostSubBufferNV;
     41 
     42 PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES;
     43 
     44 PFNGLDELETEFENCESNVPROC glDeleteFencesNV;
     45 PFNGLGENFENCESNVPROC glGenFencesNV;
     46 PFNGLGETFENCEIVNVPROC glGetFenceivNV;
     47 PFNGLISFENCENVPROC glIsFenceNV;
     48 PFNGLFINISHFENCENVPROC glFinishFenceNV;
     49 PFNGLSETFENCENVPROC glSetFenceNV;
     50 PFNGLTESTFENCENVPROC glTestFenceNV;
     51 
     52 ///
     53 // CreateEGLContext()
     54 //
     55 //    Creates an EGL rendering context and all associated elements
     56 //
     57 EGLBoolean CreateEGLContext ( EGLNativeWindowType hWnd, EGLDisplay* eglDisplay,
     58                               EGLContext* eglContext, EGLSurface* eglSurface,
     59                               EGLint* configAttribList, EGLint* surfaceAttribList)
     60 {
     61    EGLint numConfigs;
     62    EGLint majorVersion;
     63    EGLint minorVersion;
     64    EGLDisplay display;
     65    EGLContext context;
     66    EGLSurface surface;
     67    EGLConfig config;
     68    EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE };
     69 
     70    // Get Display
     71    display = eglGetDisplay(GetDC(hWnd));
     72    if ( display == EGL_NO_DISPLAY )
     73    {
     74       return EGL_FALSE;
     75    }
     76 
     77    // Initialize EGL
     78    if ( !eglInitialize(display, &majorVersion, &minorVersion) )
     79    {
     80       return EGL_FALSE;
     81    }
     82 
     83    // Bind to extensions
     84    eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC) eglGetProcAddress("eglCreateImageKHR");
     85    eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC) eglGetProcAddress("eglDestroyImageKHR");
     86 
     87    eglPostSubBufferNV = (PFNEGLPOSTSUBBUFFERNVPROC) eglGetProcAddress("eglPostSubBufferNV");
     88 
     89    glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) eglGetProcAddress("glEGLImageTargetTexture2DOES");
     90 
     91    glDeleteFencesNV = (PFNGLDELETEFENCESNVPROC) eglGetProcAddress("glDeleteFencesNV");
     92    glGenFencesNV = (PFNGLGENFENCESNVPROC) eglGetProcAddress("glGenFencesNV");
     93    glGetFenceivNV = (PFNGLGETFENCEIVNVPROC) eglGetProcAddress("glGetFenceivNV");
     94    glIsFenceNV = (PFNGLISFENCENVPROC) eglGetProcAddress("glIsFenceNV");
     95    glFinishFenceNV = (PFNGLFINISHFENCENVPROC) eglGetProcAddress("glFinishFenceNV");
     96    glSetFenceNV = (PFNGLSETFENCENVPROC) eglGetProcAddress("glSetFenceNV");
     97    glTestFenceNV = (PFNGLTESTFENCENVPROC) eglGetProcAddress("glTestFenceNV");
     98 
     99    // Get configs
    100    if ( !eglGetConfigs(display, NULL, 0, &numConfigs) )
    101    {
    102       return EGL_FALSE;
    103    }
    104 
    105    // Choose config
    106    if ( !eglChooseConfig(display, configAttribList, &config, 1, &numConfigs) )
    107    {
    108       return EGL_FALSE;
    109    }
    110 
    111    // Create a surface
    112    surface = eglCreateWindowSurface(display, config, (EGLNativeWindowType)hWnd, surfaceAttribList);
    113    if ( surface == EGL_NO_SURFACE )
    114    {
    115       return EGL_FALSE;
    116    }
    117 
    118    // Create a GL context
    119    context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs );
    120    if ( context == EGL_NO_CONTEXT )
    121    {
    122       return EGL_FALSE;
    123    }
    124 
    125    // Make the context current
    126    if ( !eglMakeCurrent(display, surface, surface, context) )
    127    {
    128       return EGL_FALSE;
    129    }
    130 
    131    *eglDisplay = display;
    132    *eglSurface = surface;
    133    *eglContext = context;
    134    return EGL_TRUE;
    135 }
    136 
    137 //////////////////////////////////////////////////////////////////
    138 //
    139 //  Public Functions
    140 //
    141 //
    142 
    143 ///
    144 //  esInitContext()
    145 //
    146 //      Initialize ES utility context.  This must be called before calling any other
    147 //      functions.
    148 //
    149 void ESUTIL_API esInitContext ( ESContext *esContext )
    150 {
    151    if ( esContext != NULL )
    152    {
    153       memset( esContext, 0, sizeof( ESContext) );
    154    }
    155 }
    156 
    157 ///
    158 //  esCreateWindow()
    159 //
    160 //      title - name for title bar of window
    161 //      width - width of window to create
    162 //      height - height of window to create
    163 //      flags  - bitwise or of window creation flags
    164 //          ES_WINDOW_ALPHA       - specifies that the framebuffer should have alpha
    165 //          ES_WINDOW_DEPTH       - specifies that a depth buffer should be created
    166 //          ES_WINDOW_STENCIL     - specifies that a stencil buffer should be created
    167 //          ES_WINDOW_MULTISAMPLE - specifies that a multi-sample buffer should be created
    168 //          ES_WINDOW_POST_SUB_BUFFER_SUPPORTED - specifies that EGL_POST_SUB_BUFFER_NV is supported.
    169 //
    170 GLboolean ESUTIL_API esCreateWindow ( ESContext *esContext, LPCTSTR title, GLint width, GLint height, GLuint flags )
    171 {
    172    EGLint configAttribList[] =
    173    {
    174        EGL_RED_SIZE,       5,
    175        EGL_GREEN_SIZE,     6,
    176        EGL_BLUE_SIZE,      5,
    177        EGL_ALPHA_SIZE,     (flags & ES_WINDOW_ALPHA) ? 8 : EGL_DONT_CARE,
    178        EGL_DEPTH_SIZE,     (flags & ES_WINDOW_DEPTH) ? 8 : EGL_DONT_CARE,
    179        EGL_STENCIL_SIZE,   (flags & ES_WINDOW_STENCIL) ? 8 : EGL_DONT_CARE,
    180        EGL_SAMPLE_BUFFERS, (flags & ES_WINDOW_MULTISAMPLE) ? 1 : 0,
    181        EGL_NONE
    182    };
    183    EGLint surfaceAttribList[] =
    184    {
    185        EGL_POST_SUB_BUFFER_SUPPORTED_NV, flags & (ES_WINDOW_POST_SUB_BUFFER_SUPPORTED) ? EGL_TRUE : EGL_FALSE,
    186        EGL_NONE, EGL_NONE
    187    };
    188 
    189    if ( esContext == NULL )
    190    {
    191       return GL_FALSE;
    192    }
    193 
    194    esContext->width = width;
    195    esContext->height = height;
    196 
    197    if ( !WinCreate ( esContext, title) )
    198    {
    199       return GL_FALSE;
    200    }
    201 
    202 
    203    if ( !CreateEGLContext ( esContext->hWnd,
    204                             &esContext->eglDisplay,
    205                             &esContext->eglContext,
    206                             &esContext->eglSurface,
    207                             configAttribList,
    208                             surfaceAttribList ) )
    209    {
    210       return GL_FALSE;
    211    }
    212 
    213 
    214    return GL_TRUE;
    215 }
    216 
    217 ///
    218 //  esMainLoop()
    219 //
    220 //    Start the main loop for the OpenGL ES application
    221 //
    222 void ESUTIL_API esMainLoop ( ESContext *esContext )
    223 {
    224    WinLoop ( esContext );
    225 }
    226 
    227 
    228 ///
    229 //  esRegisterDrawFunc()
    230 //
    231 void ESUTIL_API esRegisterDrawFunc ( ESContext *esContext, void (ESCALLBACK *drawFunc) (ESContext* ) )
    232 {
    233    esContext->drawFunc = drawFunc;
    234 }
    235 
    236 
    237 ///
    238 //  esRegisterUpdateFunc()
    239 //
    240 void ESUTIL_API esRegisterUpdateFunc ( ESContext *esContext, void (ESCALLBACK *updateFunc) ( ESContext*, float ) )
    241 {
    242    esContext->updateFunc = updateFunc;
    243 }
    244 
    245 
    246 ///
    247 //  esRegisterKeyFunc()
    248 //
    249 void ESUTIL_API esRegisterKeyFunc ( ESContext *esContext,
    250                                     void (ESCALLBACK *keyFunc) (ESContext*, unsigned char, int, int ) )
    251 {
    252    esContext->keyFunc = keyFunc;
    253 }
    254 
    255 
    256 ///
    257 // esLogMessage()
    258 //
    259 //    Log an error message to the debug output for the platform
    260 //
    261 void ESUTIL_API esLogMessage ( const char *formatStr, ... )
    262 {
    263     va_list params;
    264     char buf[BUFSIZ];
    265 
    266     va_start ( params, formatStr );
    267     vsprintf_s ( buf, sizeof(buf),  formatStr, params );
    268 
    269     printf ( "%s", buf );
    270 
    271     va_end ( params );
    272 }
    273 
    274 
    275 ///
    276 // esLoadTGA()
    277 //
    278 //    Loads a 24-bit TGA image from a file
    279 //
    280 char* ESUTIL_API esLoadTGA ( char *fileName, int *width, int *height )
    281 {
    282    char *buffer;
    283 
    284    if ( WinTGALoad ( fileName, &buffer, width, height ) )
    285    {
    286       return buffer;
    287    }
    288 
    289    return NULL;
    290 }
    291