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