| /* San Angeles Observation OpenGL ES version example |
| * Copyright 2004-2005 Jetro Lauha |
| * All rights reserved. |
| * Web: http://iki.fi/jetro/ |
| * |
| * This source is free software; you can redistribute it and/or |
| * modify it under the terms of EITHER: |
| * (1) The GNU Lesser General Public License as published by the Free |
| * Software Foundation; either version 2.1 of the License, or (at |
| * your option) any later version. The text of the GNU Lesser |
| * General Public License is included with this source in the |
| * file LICENSE-LGPL.txt. |
| * (2) The BSD-style license that is included with this source in |
| * the file LICENSE-BSD.txt. |
| * |
| * This source is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files |
| * LICENSE-LGPL.txt and LICENSE-BSD.txt for more details. |
| * |
| * $Id: app-linux.c,v 1.4 2005/02/08 18:42:48 tonic Exp $ |
| * $Revision: 1.4 $ |
| * |
| * Parts of this source file is based on test/example code from |
| * GLESonGL implementation by David Blythe. Here is copy of the |
| * license notice from that source: |
| * |
| * Copyright (C) 2003 David Blythe All Rights Reserved. |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
| * to deal in the Software without restriction, including without limitation |
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| * and/or sell copies of the Software, and to permit persons to whom the |
| * Software is furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included |
| * in all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| * DAVID BLYTHE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN |
| * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| */ |
| |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include <sys/time.h> |
| |
| #include <EGL/egl.h> |
| #include <GLES/gl.h> |
| |
| #include <EGLUtils.h> |
| #include <WindowSurface.h> |
| |
| using namespace android; |
| |
| #include "app.h" |
| |
| |
| int gAppAlive = 1; |
| |
| static int sWindowWidth = WINDOW_DEFAULT_WIDTH; |
| static int sWindowHeight = WINDOW_DEFAULT_HEIGHT; |
| static EGLDisplay sEglDisplay = EGL_NO_DISPLAY; |
| static EGLContext sEglContext = EGL_NO_CONTEXT; |
| static EGLSurface sEglSurface = EGL_NO_SURFACE; |
| |
| const char *egl_strerror(unsigned err) |
| { |
| switch(err){ |
| case EGL_SUCCESS: return "SUCCESS"; |
| case EGL_NOT_INITIALIZED: return "NOT INITIALIZED"; |
| case EGL_BAD_ACCESS: return "BAD ACCESS"; |
| case EGL_BAD_ALLOC: return "BAD ALLOC"; |
| case EGL_BAD_ATTRIBUTE: return "BAD_ATTRIBUTE"; |
| case EGL_BAD_CONFIG: return "BAD CONFIG"; |
| case EGL_BAD_CONTEXT: return "BAD CONTEXT"; |
| case EGL_BAD_CURRENT_SURFACE: return "BAD CURRENT SURFACE"; |
| case EGL_BAD_DISPLAY: return "BAD DISPLAY"; |
| case EGL_BAD_MATCH: return "BAD MATCH"; |
| case EGL_BAD_NATIVE_PIXMAP: return "BAD NATIVE PIXMAP"; |
| case EGL_BAD_NATIVE_WINDOW: return "BAD NATIVE WINDOW"; |
| case EGL_BAD_PARAMETER: return "BAD PARAMETER"; |
| case EGL_BAD_SURFACE: return "BAD_SURFACE"; |
| // case EGL_CONTEXT_LOST: return "CONTEXT LOST"; |
| default: return "UNKNOWN"; |
| } |
| } |
| |
| void egl_error(const char *name) |
| { |
| unsigned err = eglGetError(); |
| if(err != EGL_SUCCESS) { |
| fprintf(stderr,"%s(): egl error 0x%x (%s)\n", |
| name, err, egl_strerror(err)); |
| } |
| } |
| |
| static void checkGLErrors() |
| { |
| GLenum error = glGetError(); |
| if (error != GL_NO_ERROR) |
| fprintf(stderr, "GL Error: 0x%04x\n", (int)error); |
| } |
| |
| |
| static void checkEGLErrors() |
| { |
| EGLint error = eglGetError(); |
| // GLESonGL seems to be returning 0 when there is no errors? |
| if (error && error != EGL_SUCCESS) |
| fprintf(stderr, "EGL Error: 0x%04x\n", (int)error); |
| } |
| |
| static int initGraphics(EGLint samples, const WindowSurface& windowSurface) |
| { |
| EGLint configAttribs[] = { |
| EGL_DEPTH_SIZE, 16, |
| EGL_SAMPLE_BUFFERS, samples ? 1 : 0, |
| EGL_SAMPLES, samples, |
| EGL_NONE |
| }; |
| |
| EGLint majorVersion; |
| EGLint minorVersion; |
| EGLContext context; |
| EGLConfig config; |
| EGLSurface surface; |
| EGLDisplay dpy; |
| |
| EGLNativeWindowType window = windowSurface.getSurface(); |
| |
| dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
| eglInitialize(dpy, &majorVersion, &minorVersion); |
| |
| status_t err = EGLUtils::selectConfigForNativeWindow( |
| dpy, configAttribs, window, &config); |
| if (err) { |
| fprintf(stderr, "couldn't find an EGLConfig matching the screen format\n"); |
| return 0; |
| } |
| |
| surface = eglCreateWindowSurface(dpy, config, window, NULL); |
| egl_error("eglCreateWindowSurface"); |
| |
| fprintf(stderr,"surface = %p\n", surface); |
| |
| context = eglCreateContext(dpy, config, NULL, NULL); |
| egl_error("eglCreateContext"); |
| fprintf(stderr,"context = %p\n", context); |
| |
| eglMakeCurrent(dpy, surface, surface, context); |
| egl_error("eglMakeCurrent"); |
| |
| eglQuerySurface(dpy, surface, EGL_WIDTH, &sWindowWidth); |
| eglQuerySurface(dpy, surface, EGL_HEIGHT, &sWindowHeight); |
| |
| sEglDisplay = dpy; |
| sEglSurface = surface; |
| sEglContext = context; |
| |
| if (samples == 0) { |
| // GL_MULTISAMPLE is enabled by default |
| glDisable(GL_MULTISAMPLE); |
| } |
| |
| return EGL_TRUE; |
| } |
| |
| |
| static void deinitGraphics() |
| { |
| eglMakeCurrent(sEglDisplay, NULL, NULL, NULL); |
| eglDestroyContext(sEglDisplay, sEglContext); |
| eglDestroySurface(sEglDisplay, sEglSurface); |
| eglTerminate(sEglDisplay); |
| } |
| |
| |
| int main(int argc, char *argv[]) |
| { |
| unsigned samples = 0; |
| printf("usage: %s [samples]\n", argv[0]); |
| if (argc == 2) { |
| samples = atoi( argv[1] ); |
| printf("Multisample enabled: GL_SAMPLES = %u\n", samples); |
| } |
| |
| WindowSurface windowSurface; |
| if (!initGraphics(samples, windowSurface)) |
| { |
| fprintf(stderr, "Graphics initialization failed.\n"); |
| return EXIT_FAILURE; |
| } |
| |
| appInit(); |
| |
| struct timeval timeTemp; |
| int frameCount = 0; |
| gettimeofday(&timeTemp, NULL); |
| double totalTime = timeTemp.tv_usec/1000000.0 + timeTemp.tv_sec; |
| |
| while (gAppAlive) |
| { |
| struct timeval timeNow; |
| |
| gettimeofday(&timeNow, NULL); |
| appRender(timeNow.tv_sec * 1000 + timeNow.tv_usec / 1000, |
| sWindowWidth, sWindowHeight); |
| checkGLErrors(); |
| eglSwapBuffers(sEglDisplay, sEglSurface); |
| checkEGLErrors(); |
| frameCount++; |
| } |
| |
| gettimeofday(&timeTemp, NULL); |
| |
| appDeinit(); |
| deinitGraphics(); |
| |
| totalTime = (timeTemp.tv_usec/1000000.0 + timeTemp.tv_sec) - totalTime; |
| printf("totalTime=%f s, frameCount=%d, %.2f fps\n", |
| totalTime, frameCount, frameCount/totalTime); |
| |
| return EXIT_SUCCESS; |
| } |