1 /* San Angeles Observation OpenGL ES version example 2 * Copyright 2004-2005 Jetro Lauha 3 * All rights reserved. 4 * Web: http://iki.fi/jetro/ 5 * 6 * This source is free software; you can redistribute it and/or 7 * modify it under the terms of EITHER: 8 * (1) The GNU Lesser General Public License as published by the Free 9 * Software Foundation; either version 2.1 of the License, or (at 10 * your option) any later version. The text of the GNU Lesser 11 * General Public License is included with this source in the 12 * file LICENSE-LGPL.txt. 13 * (2) The BSD-style license that is included with this source in 14 * the file LICENSE-BSD.txt. 15 * 16 * This source is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files 19 * LICENSE-LGPL.txt and LICENSE-BSD.txt for more details. 20 * 21 * $Id: app-linux.c,v 1.4 2005/02/08 18:42:48 tonic Exp $ 22 * $Revision: 1.4 $ 23 * 24 * Parts of this source file is based on test/example code from 25 * GLESonGL implementation by David Blythe. Here is copy of the 26 * license notice from that source: 27 * 28 * Copyright (C) 2003 David Blythe All Rights Reserved. 29 * 30 * Permission is hereby granted, free of charge, to any person obtaining a 31 * copy of this software and associated documentation files (the "Software"), 32 * to deal in the Software without restriction, including without limitation 33 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 34 * and/or sell copies of the Software, and to permit persons to whom the 35 * Software is furnished to do so, subject to the following conditions: 36 * 37 * The above copyright notice and this permission notice shall be included 38 * in all copies or substantial portions of the Software. 39 * 40 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 41 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 42 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 43 * DAVID BLYTHE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 44 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 45 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 46 */ 47 48 #include <stdlib.h> 49 #include <stdio.h> 50 #include <sys/time.h> 51 52 #include <EGL/egl.h> 53 #include <GLES/gl.h> 54 55 #include <ui/FramebufferNativeWindow.h> 56 #include "EGLUtils.h" 57 58 using namespace android; 59 60 #include "app.h" 61 62 63 int gAppAlive = 1; 64 65 static const char sAppName[] = 66 "San Angeles Observation OpenGL ES version example (Linux)"; 67 68 static int sWindowWidth = WINDOW_DEFAULT_WIDTH; 69 static int sWindowHeight = WINDOW_DEFAULT_HEIGHT; 70 static EGLDisplay sEglDisplay = EGL_NO_DISPLAY; 71 static EGLContext sEglContext = EGL_NO_CONTEXT; 72 static EGLSurface sEglSurface = EGL_NO_SURFACE; 73 74 const char *egl_strerror(unsigned err) 75 { 76 switch(err){ 77 case EGL_SUCCESS: return "SUCCESS"; 78 case EGL_NOT_INITIALIZED: return "NOT INITIALIZED"; 79 case EGL_BAD_ACCESS: return "BAD ACCESS"; 80 case EGL_BAD_ALLOC: return "BAD ALLOC"; 81 case EGL_BAD_ATTRIBUTE: return "BAD_ATTRIBUTE"; 82 case EGL_BAD_CONFIG: return "BAD CONFIG"; 83 case EGL_BAD_CONTEXT: return "BAD CONTEXT"; 84 case EGL_BAD_CURRENT_SURFACE: return "BAD CURRENT SURFACE"; 85 case EGL_BAD_DISPLAY: return "BAD DISPLAY"; 86 case EGL_BAD_MATCH: return "BAD MATCH"; 87 case EGL_BAD_NATIVE_PIXMAP: return "BAD NATIVE PIXMAP"; 88 case EGL_BAD_NATIVE_WINDOW: return "BAD NATIVE WINDOW"; 89 case EGL_BAD_PARAMETER: return "BAD PARAMETER"; 90 case EGL_BAD_SURFACE: return "BAD_SURFACE"; 91 // case EGL_CONTEXT_LOST: return "CONTEXT LOST"; 92 default: return "UNKNOWN"; 93 } 94 } 95 96 void egl_error(const char *name) 97 { 98 unsigned err = eglGetError(); 99 if(err != EGL_SUCCESS) { 100 fprintf(stderr,"%s(): egl error 0x%x (%s)\n", 101 name, err, egl_strerror(err)); 102 } 103 } 104 105 static void checkGLErrors() 106 { 107 GLenum error = glGetError(); 108 if (error != GL_NO_ERROR) 109 fprintf(stderr, "GL Error: 0x%04x\n", (int)error); 110 } 111 112 113 static void checkEGLErrors() 114 { 115 EGLint error = eglGetError(); 116 // GLESonGL seems to be returning 0 when there is no errors? 117 if (error && error != EGL_SUCCESS) 118 fprintf(stderr, "EGL Error: 0x%04x\n", (int)error); 119 } 120 121 static int initGraphics(unsigned samples) 122 { 123 EGLint configAttribs[] = { 124 EGL_DEPTH_SIZE, 16, 125 EGL_SAMPLE_BUFFERS, samples ? 1 : 0, 126 EGL_SAMPLES, samples, 127 EGL_NONE 128 }; 129 130 EGLint majorVersion; 131 EGLint minorVersion; 132 EGLContext context; 133 EGLConfig config; 134 EGLSurface surface; 135 EGLint w, h; 136 EGLDisplay dpy; 137 138 EGLNativeWindowType window = android_createDisplaySurface(); 139 140 dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); 141 eglInitialize(dpy, &majorVersion, &minorVersion); 142 143 status_t err = EGLUtils::selectConfigForNativeWindow( 144 dpy, configAttribs, window, &config); 145 if (err) { 146 fprintf(stderr, "couldn't find an EGLConfig matching the screen format\n"); 147 return 0; 148 } 149 150 surface = eglCreateWindowSurface(dpy, config, window, NULL); 151 egl_error("eglCreateWindowSurface"); 152 153 fprintf(stderr,"surface = %p\n", surface); 154 155 context = eglCreateContext(dpy, config, NULL, NULL); 156 egl_error("eglCreateContext"); 157 fprintf(stderr,"context = %p\n", context); 158 159 eglMakeCurrent(dpy, surface, surface, context); 160 egl_error("eglMakeCurrent"); 161 162 eglQuerySurface(dpy, surface, EGL_WIDTH, &sWindowWidth); 163 eglQuerySurface(dpy, surface, EGL_HEIGHT, &sWindowHeight); 164 165 sEglDisplay = dpy; 166 sEglSurface = surface; 167 sEglContext = context; 168 169 if (samples == 0) { 170 // GL_MULTISAMPLE is enabled by default 171 glDisable(GL_MULTISAMPLE); 172 } 173 174 return EGL_TRUE; 175 } 176 177 178 static void deinitGraphics() 179 { 180 eglMakeCurrent(sEglDisplay, NULL, NULL, NULL); 181 eglDestroyContext(sEglDisplay, sEglContext); 182 eglDestroySurface(sEglDisplay, sEglSurface); 183 eglTerminate(sEglDisplay); 184 } 185 186 187 int main(int argc, char *argv[]) 188 { 189 unsigned samples = 0; 190 printf("usage: %s [samples]\n", argv[0]); 191 if (argc == 2) { 192 samples = atoi( argv[1] ); 193 printf("Multisample enabled: GL_SAMPLES = %u\n", samples); 194 } 195 196 if (!initGraphics(samples)) 197 { 198 fprintf(stderr, "Graphics initialization failed.\n"); 199 return EXIT_FAILURE; 200 } 201 202 appInit(); 203 204 struct timeval timeTemp; 205 int frameCount = 0; 206 gettimeofday(&timeTemp, NULL); 207 double totalTime = timeTemp.tv_usec/1000000.0 + timeTemp.tv_sec; 208 209 while (gAppAlive) 210 { 211 struct timeval timeNow; 212 213 gettimeofday(&timeNow, NULL); 214 appRender(timeNow.tv_sec * 1000 + timeNow.tv_usec / 1000, 215 sWindowWidth, sWindowHeight); 216 checkGLErrors(); 217 eglSwapBuffers(sEglDisplay, sEglSurface); 218 checkEGLErrors(); 219 frameCount++; 220 } 221 222 gettimeofday(&timeTemp, NULL); 223 224 appDeinit(); 225 deinitGraphics(); 226 227 totalTime = (timeTemp.tv_usec/1000000.0 + timeTemp.tv_sec) - totalTime; 228 printf("totalTime=%f s, frameCount=%d, %.2f fps\n", 229 totalTime, frameCount, frameCount/totalTime); 230 231 return EXIT_SUCCESS; 232 } 233