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 <EGLUtils.h> 56#include <WindowSurface.h> 57 58using namespace android; 59 60#include "app.h" 61 62 63int gAppAlive = 1; 64 65static int sWindowWidth = WINDOW_DEFAULT_WIDTH; 66static int sWindowHeight = WINDOW_DEFAULT_HEIGHT; 67static EGLDisplay sEglDisplay = EGL_NO_DISPLAY; 68static EGLContext sEglContext = EGL_NO_CONTEXT; 69static EGLSurface sEglSurface = EGL_NO_SURFACE; 70 71const char *egl_strerror(unsigned err) 72{ 73 switch(err){ 74 case EGL_SUCCESS: return "SUCCESS"; 75 case EGL_NOT_INITIALIZED: return "NOT INITIALIZED"; 76 case EGL_BAD_ACCESS: return "BAD ACCESS"; 77 case EGL_BAD_ALLOC: return "BAD ALLOC"; 78 case EGL_BAD_ATTRIBUTE: return "BAD_ATTRIBUTE"; 79 case EGL_BAD_CONFIG: return "BAD CONFIG"; 80 case EGL_BAD_CONTEXT: return "BAD CONTEXT"; 81 case EGL_BAD_CURRENT_SURFACE: return "BAD CURRENT SURFACE"; 82 case EGL_BAD_DISPLAY: return "BAD DISPLAY"; 83 case EGL_BAD_MATCH: return "BAD MATCH"; 84 case EGL_BAD_NATIVE_PIXMAP: return "BAD NATIVE PIXMAP"; 85 case EGL_BAD_NATIVE_WINDOW: return "BAD NATIVE WINDOW"; 86 case EGL_BAD_PARAMETER: return "BAD PARAMETER"; 87 case EGL_BAD_SURFACE: return "BAD_SURFACE"; 88 // case EGL_CONTEXT_LOST: return "CONTEXT LOST"; 89 default: return "UNKNOWN"; 90 } 91} 92 93void egl_error(const char *name) 94{ 95 unsigned err = eglGetError(); 96 if(err != EGL_SUCCESS) { 97 fprintf(stderr,"%s(): egl error 0x%x (%s)\n", 98 name, err, egl_strerror(err)); 99 } 100} 101 102static void checkGLErrors() 103{ 104 GLenum error = glGetError(); 105 if (error != GL_NO_ERROR) 106 fprintf(stderr, "GL Error: 0x%04x\n", (int)error); 107} 108 109 110static void checkEGLErrors() 111{ 112 EGLint error = eglGetError(); 113 // GLESonGL seems to be returning 0 when there is no errors? 114 if (error && error != EGL_SUCCESS) 115 fprintf(stderr, "EGL Error: 0x%04x\n", (int)error); 116} 117 118static int initGraphics(EGLint samples, const WindowSurface& windowSurface) 119{ 120 EGLint configAttribs[] = { 121 EGL_DEPTH_SIZE, 16, 122 EGL_SAMPLE_BUFFERS, samples ? 1 : 0, 123 EGL_SAMPLES, samples, 124 EGL_NONE 125 }; 126 127 EGLint majorVersion; 128 EGLint minorVersion; 129 EGLContext context; 130 EGLConfig config; 131 EGLSurface surface; 132 EGLDisplay dpy; 133 134 EGLNativeWindowType window = windowSurface.getSurface(); 135 136 dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); 137 eglInitialize(dpy, &majorVersion, &minorVersion); 138 139 status_t err = EGLUtils::selectConfigForNativeWindow( 140 dpy, configAttribs, window, &config); 141 if (err) { 142 fprintf(stderr, "couldn't find an EGLConfig matching the screen format\n"); 143 return 0; 144 } 145 146 surface = eglCreateWindowSurface(dpy, config, window, NULL); 147 egl_error("eglCreateWindowSurface"); 148 149 fprintf(stderr,"surface = %p\n", surface); 150 151 context = eglCreateContext(dpy, config, NULL, NULL); 152 egl_error("eglCreateContext"); 153 fprintf(stderr,"context = %p\n", context); 154 155 eglMakeCurrent(dpy, surface, surface, context); 156 egl_error("eglMakeCurrent"); 157 158 eglQuerySurface(dpy, surface, EGL_WIDTH, &sWindowWidth); 159 eglQuerySurface(dpy, surface, EGL_HEIGHT, &sWindowHeight); 160 161 sEglDisplay = dpy; 162 sEglSurface = surface; 163 sEglContext = context; 164 165 if (samples == 0) { 166 // GL_MULTISAMPLE is enabled by default 167 glDisable(GL_MULTISAMPLE); 168 } 169 170 return EGL_TRUE; 171} 172 173 174static void deinitGraphics() 175{ 176 eglMakeCurrent(sEglDisplay, NULL, NULL, NULL); 177 eglDestroyContext(sEglDisplay, sEglContext); 178 eglDestroySurface(sEglDisplay, sEglSurface); 179 eglTerminate(sEglDisplay); 180} 181 182 183int main(int argc, char *argv[]) 184{ 185 unsigned samples = 0; 186 printf("usage: %s [samples]\n", argv[0]); 187 if (argc == 2) { 188 samples = atoi( argv[1] ); 189 printf("Multisample enabled: GL_SAMPLES = %u\n", samples); 190 } 191 192 WindowSurface windowSurface; 193 if (!initGraphics(samples, windowSurface)) 194 { 195 fprintf(stderr, "Graphics initialization failed.\n"); 196 return EXIT_FAILURE; 197 } 198 199 appInit(); 200 201 struct timeval timeTemp; 202 int frameCount = 0; 203 gettimeofday(&timeTemp, NULL); 204 double totalTime = timeTemp.tv_usec/1000000.0 + timeTemp.tv_sec; 205 206 while (gAppAlive) 207 { 208 struct timeval timeNow; 209 210 gettimeofday(&timeNow, NULL); 211 appRender(timeNow.tv_sec * 1000 + timeNow.tv_usec / 1000, 212 sWindowWidth, sWindowHeight); 213 checkGLErrors(); 214 eglSwapBuffers(sEglDisplay, sEglSurface); 215 checkEGLErrors(); 216 frameCount++; 217 } 218 219 gettimeofday(&timeTemp, NULL); 220 221 appDeinit(); 222 deinitGraphics(); 223 224 totalTime = (timeTemp.tv_usec/1000000.0 + timeTemp.tv_sec) - totalTime; 225 printf("totalTime=%f s, frameCount=%d, %.2f fps\n", 226 totalTime, frameCount, frameCount/totalTime); 227 228 return EXIT_SUCCESS; 229} 230