• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 //
CreateEGLContext(EGLNativeWindowType hWnd,EGLDisplay * eglDisplay,EGLContext * eglContext,EGLSurface * eglSurface,EGLint * configAttribList,EGLint * surfaceAttribList)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 //
esInitContext(ESContext * esContext)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 //
esCreateWindow(ESContext * esContext,LPCTSTR title,GLint width,GLint height,GLuint flags)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 //
esMainLoop(ESContext * esContext)222 void ESUTIL_API esMainLoop ( ESContext *esContext )
223 {
224    WinLoop ( esContext );
225 }
226 
227 
228 ///
229 //  esRegisterDrawFunc()
230 //
esRegisterDrawFunc(ESContext * esContext,void (ESCALLBACK * drawFunc)(ESContext *))231 void ESUTIL_API esRegisterDrawFunc ( ESContext *esContext, void (ESCALLBACK *drawFunc) (ESContext* ) )
232 {
233    esContext->drawFunc = drawFunc;
234 }
235 
236 
237 ///
238 //  esRegisterUpdateFunc()
239 //
esRegisterUpdateFunc(ESContext * esContext,void (ESCALLBACK * updateFunc)(ESContext *,float))240 void ESUTIL_API esRegisterUpdateFunc ( ESContext *esContext, void (ESCALLBACK *updateFunc) ( ESContext*, float ) )
241 {
242    esContext->updateFunc = updateFunc;
243 }
244 
245 
246 ///
247 //  esRegisterKeyFunc()
248 //
esRegisterKeyFunc(ESContext * esContext,void (ESCALLBACK * keyFunc)(ESContext *,unsigned char,int,int))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 //
esLogMessage(const char * formatStr,...)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 //
esLoadTGA(char * fileName,int * width,int * height)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