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 <string.h> 51 #include <sys/time.h> 52 #include "waffle.h" 53 54 #ifdef SAN_ANGELES_OBSERVATION_GLES 55 #define GL_API WAFFLE_CONTEXT_OPENGL_ES2 56 #undef IMPORTGL_API 57 #undef IMPORTGL_FNPTRINIT 58 #include "importgl.h" 59 #else // SAN_ANGELES_OBSERVATION_GLES 60 #define GL_API WAFFLE_CONTEXT_OPENGL 61 #undef IMPORTVBO_API 62 #undef IMPORTVBO_FNPTRINIT 63 #include "importvbo.h" 64 #endif // SAN_ANGELES_OBSERVATION_GLES | !SAN_ANGELES_OBSERVATION_GLES 65 66 #include "app.h" 67 68 69 int gAppAlive = 1; 70 static struct waffle_display *sDisplay; 71 static struct waffle_window *sWindow; 72 static struct waffle_config *sConfig; 73 static struct waffle_context *sContext; 74 static int sWindowWidth = WINDOW_DEFAULT_WIDTH; 75 static int sWindowHeight = WINDOW_DEFAULT_HEIGHT; 76 #ifdef SAN_ANGELES_OBSERVATION_GLES 77 static const char sAppName[] = 78 "San Angeles Observation OpenGL ES version example (Linux)"; 79 #else // !SAN_ANGELES_OBSERVATION_GLES 80 static const char sAppName[] = 81 "San Angeles Observation OpenGL version example (Linux)"; 82 #endif // SAN_ANGELES_OBSERVATION_GLES | !SAN_ANGELES_OBSERVATION_GLES 83 84 static void checkGLErrors() 85 { 86 GLenum error = glGetError(); 87 if (error != GL_NO_ERROR) 88 fprintf(stderr, "Error: GL error code 0x%04x\n", (int)error); 89 } 90 91 static int waffleError(void) 92 { 93 const struct waffle_error_info *info = waffle_error_get_info(); 94 const char *code = waffle_error_to_string(info->code); 95 96 fprintf(stderr, "Error: %s", code); 97 if (info->message_length > 0) 98 fprintf(stderr, ": %s", info->message); 99 fprintf(stderr, "\n"); 100 return 0; 101 } 102 103 // Initializes and opens both display and OpenGL/GLES. 104 static int initGraphics(int32_t platform) 105 { 106 int32_t configAttribs[] = 107 { 108 WAFFLE_CONTEXT_API, GL_API, 109 WAFFLE_RED_SIZE, 5, 110 WAFFLE_GREEN_SIZE, 5, 111 WAFFLE_BLUE_SIZE, 5, 112 WAFFLE_ALPHA_SIZE, 0, 113 WAFFLE_DEPTH_SIZE, 16, 114 WAFFLE_DOUBLE_BUFFERED, true, 115 0 116 }; 117 118 int32_t initAttribs[] = 119 { 120 WAFFLE_PLATFORM, platform, 121 0 122 }; 123 124 bool ok = waffle_init(initAttribs); 125 if (!ok) 126 return waffleError(); 127 128 sDisplay = waffle_display_connect(NULL); 129 if (!sDisplay) 130 return waffleError(); 131 132 sConfig = waffle_config_choose(sDisplay, configAttribs); 133 if (!sConfig) 134 return waffleError(); 135 136 sContext = waffle_context_create(sConfig, NULL); 137 if (!sContext) 138 return waffleError(); 139 140 sWindow = waffle_window_create(sConfig, sWindowWidth, sWindowHeight); 141 if (!sWindow) 142 return waffleError(); 143 144 if (!waffle_window_show(sWindow)) 145 return waffleError(); 146 147 ok = waffle_make_current(sDisplay, sWindow, sContext); 148 if (!ok) 149 return waffleError(); 150 151 #ifdef SAN_ANGELES_OBSERVATION_GLES 152 #ifndef DISABLE_IMPORTGL 153 int importGLResult; 154 importGLResult = importGLInit(); 155 if (!importGLResult) 156 return 0; 157 #endif // !DISABLE_IMPORTGL 158 #endif // SAN_ANGELES_OBSERVATION_GLES 159 160 glEnable(GL_DEPTH_TEST); 161 162 int rt = 1; 163 #ifndef SAN_ANGELES_OBSERVATION_GLES 164 rt = loadVBOProcs(); 165 #endif // !SAN_ANGELES_OBSERVATION_GLES 166 return rt; 167 } 168 169 static void deinitGraphics() 170 { 171 if (!waffle_make_current(sDisplay, NULL, NULL)) 172 waffleError(); 173 if (!waffle_window_destroy(sWindow)) 174 waffleError(); 175 if (!waffle_context_destroy(sContext)) 176 waffleError(); 177 if (!waffle_config_destroy(sConfig)) 178 waffleError(); 179 if (!waffle_display_disconnect(sDisplay)) 180 waffleError(); 181 } 182 183 #define PLATFORM(x) { #x, WAFFLE_PLATFORM_##x } 184 185 static struct platform_item { 186 const char *name; 187 int32_t value; 188 } platform_list[] = { 189 PLATFORM(GLX), 190 PLATFORM(X11_EGL), 191 PLATFORM(GBM), 192 PLATFORM(NULL), 193 { NULL, 0 } 194 }; 195 196 int main(int argc, char *argv[]) 197 { 198 // TODO(fjhenigman): add waffle_to_string_to_enum to waffle then use it 199 // to parse the platform arg. 200 int32_t platform_value = WAFFLE_NONE; 201 struct platform_item *p = platform_list; 202 while (argc == 2 && p->name && platform_value == WAFFLE_NONE) { 203 if (!strcasecmp(argv[1], p->name)) 204 platform_value = p->value; 205 ++p; 206 } 207 208 if (platform_value == WAFFLE_NONE) 209 { 210 fprintf(stderr, "Usage: SanOGLES <platform>\n"); 211 return EXIT_FAILURE; 212 } 213 214 if (!initGraphics(platform_value)) 215 { 216 fprintf(stderr, "Error: Graphics initialization failed.\n"); 217 return EXIT_FAILURE; 218 } 219 220 if (!appInit()) 221 { 222 fprintf(stderr, "Error: Application initialization failed.\n"); 223 return EXIT_FAILURE; 224 } 225 226 double total_time = 0.0; 227 int num_frames = 0; 228 229 while (1) 230 { 231 struct timeval timeNow, timeAfter; 232 233 gettimeofday(&timeNow, NULL); 234 appRender(TIME_SPEEDUP * (timeNow.tv_sec * 1000 + 235 timeNow.tv_usec / 1000), 236 sWindowWidth, sWindowHeight); 237 gettimeofday(&timeAfter, NULL); 238 239 #ifdef SAN_ANGELES_OBSERVATION_GLES 240 checkGLErrors(); 241 #endif 242 243 if (!gAppAlive) 244 break; 245 246 if (!waffle_window_swap_buffers(sWindow)) 247 waffleError(); 248 249 #ifndef SAN_ANGELES_OBSERVATION_GLES 250 checkGLErrors(); 251 #endif 252 253 total_time += (timeAfter.tv_sec - timeNow.tv_sec) + 254 (timeAfter.tv_usec - timeNow.tv_usec) / 1000000.0; 255 num_frames++; 256 } 257 258 appDeinit(); 259 deinitGraphics(); 260 261 fprintf(stdout, "frame_rate = %.1f\n", num_frames / total_time); 262 263 return EXIT_SUCCESS; 264 } 265 266