| /* 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 <string.h> |
| #include <sys/time.h> |
| #include "waffle.h" |
| |
| #ifdef SAN_ANGELES_OBSERVATION_GLES |
| #define GL_API WAFFLE_CONTEXT_OPENGL_ES2 |
| #undef IMPORTGL_API |
| #undef IMPORTGL_FNPTRINIT |
| #include "importgl.h" |
| #else // SAN_ANGELES_OBSERVATION_GLES |
| #define GL_API WAFFLE_CONTEXT_OPENGL |
| #undef IMPORTVBO_API |
| #undef IMPORTVBO_FNPTRINIT |
| #include "importvbo.h" |
| #endif // SAN_ANGELES_OBSERVATION_GLES | !SAN_ANGELES_OBSERVATION_GLES |
| |
| #include "app.h" |
| |
| |
| int gAppAlive = 1; |
| static struct waffle_display *sDisplay; |
| static struct waffle_window *sWindow; |
| static struct waffle_config *sConfig; |
| static struct waffle_context *sContext; |
| static int sWindowWidth = WINDOW_DEFAULT_WIDTH; |
| static int sWindowHeight = WINDOW_DEFAULT_HEIGHT; |
| #ifdef SAN_ANGELES_OBSERVATION_GLES |
| static const char sAppName[] = |
| "San Angeles Observation OpenGL ES version example (Linux)"; |
| #else // !SAN_ANGELES_OBSERVATION_GLES |
| static const char sAppName[] = |
| "San Angeles Observation OpenGL version example (Linux)"; |
| #endif // SAN_ANGELES_OBSERVATION_GLES | !SAN_ANGELES_OBSERVATION_GLES |
| |
| static void checkGLErrors() |
| { |
| GLenum error = glGetError(); |
| if (error != GL_NO_ERROR) |
| fprintf(stderr, "Error: GL error code 0x%04x\n", (int)error); |
| } |
| |
| static int waffleError(void) |
| { |
| const struct waffle_error_info *info = waffle_error_get_info(); |
| const char *code = waffle_error_to_string(info->code); |
| |
| fprintf(stderr, "Error: %s", code); |
| if (info->message_length > 0) |
| fprintf(stderr, ": %s", info->message); |
| fprintf(stderr, "\n"); |
| return 0; |
| } |
| |
| // Initializes and opens both display and OpenGL/GLES. |
| static int initGraphics(int32_t platform) |
| { |
| int32_t configAttribs[] = |
| { |
| WAFFLE_CONTEXT_API, GL_API, |
| WAFFLE_RED_SIZE, 5, |
| WAFFLE_GREEN_SIZE, 5, |
| WAFFLE_BLUE_SIZE, 5, |
| WAFFLE_ALPHA_SIZE, 0, |
| WAFFLE_DEPTH_SIZE, 16, |
| WAFFLE_DOUBLE_BUFFERED, true, |
| 0 |
| }; |
| |
| int32_t initAttribs[] = |
| { |
| WAFFLE_PLATFORM, platform, |
| 0 |
| }; |
| |
| bool ok = waffle_init(initAttribs); |
| if (!ok) |
| return waffleError(); |
| |
| sDisplay = waffle_display_connect(NULL); |
| if (!sDisplay) |
| return waffleError(); |
| |
| sConfig = waffle_config_choose(sDisplay, configAttribs); |
| if (!sConfig) |
| return waffleError(); |
| |
| sContext = waffle_context_create(sConfig, NULL); |
| if (!sContext) |
| return waffleError(); |
| |
| sWindow = waffle_window_create(sConfig, sWindowWidth, sWindowHeight); |
| if (!sWindow) |
| return waffleError(); |
| |
| if (!waffle_window_show(sWindow)) |
| return waffleError(); |
| |
| ok = waffle_make_current(sDisplay, sWindow, sContext); |
| if (!ok) |
| return waffleError(); |
| |
| #ifdef SAN_ANGELES_OBSERVATION_GLES |
| #ifndef DISABLE_IMPORTGL |
| int importGLResult; |
| importGLResult = importGLInit(); |
| if (!importGLResult) |
| return 0; |
| #endif // !DISABLE_IMPORTGL |
| #endif // SAN_ANGELES_OBSERVATION_GLES |
| |
| glEnable(GL_DEPTH_TEST); |
| |
| int rt = 1; |
| #ifndef SAN_ANGELES_OBSERVATION_GLES |
| rt = loadVBOProcs(); |
| #endif // !SAN_ANGELES_OBSERVATION_GLES |
| return rt; |
| } |
| |
| static void deinitGraphics() |
| { |
| if (!waffle_make_current(sDisplay, NULL, NULL)) |
| waffleError(); |
| if (!waffle_window_destroy(sWindow)) |
| waffleError(); |
| if (!waffle_context_destroy(sContext)) |
| waffleError(); |
| if (!waffle_config_destroy(sConfig)) |
| waffleError(); |
| if (!waffle_display_disconnect(sDisplay)) |
| waffleError(); |
| } |
| |
| #define PLATFORM(x) { #x, WAFFLE_PLATFORM_##x } |
| |
| static struct platform_item { |
| const char *name; |
| int32_t value; |
| } platform_list[] = { |
| PLATFORM(GLX), |
| PLATFORM(X11_EGL), |
| PLATFORM(GBM), |
| PLATFORM(NULL), |
| { NULL, 0 } |
| }; |
| |
| int main(int argc, char *argv[]) |
| { |
| // TODO(fjhenigman): add waffle_to_string_to_enum to waffle then use it |
| // to parse the platform arg. |
| int32_t platform_value = WAFFLE_NONE; |
| struct platform_item *p = platform_list; |
| while (argc == 2 && p->name && platform_value == WAFFLE_NONE) { |
| if (!strcasecmp(argv[1], p->name)) |
| platform_value = p->value; |
| ++p; |
| } |
| |
| if (platform_value == WAFFLE_NONE) |
| { |
| fprintf(stderr, "Usage: SanOGLES <platform>\n"); |
| return EXIT_FAILURE; |
| } |
| |
| if (!initGraphics(platform_value)) |
| { |
| fprintf(stderr, "Error: Graphics initialization failed.\n"); |
| return EXIT_FAILURE; |
| } |
| |
| if (!appInit()) |
| { |
| fprintf(stderr, "Error: Application initialization failed.\n"); |
| return EXIT_FAILURE; |
| } |
| |
| double total_time = 0.0; |
| int num_frames = 0; |
| |
| while (1) |
| { |
| struct timeval timeNow, timeAfter; |
| |
| gettimeofday(&timeNow, NULL); |
| appRender(TIME_SPEEDUP * (timeNow.tv_sec * 1000 + |
| timeNow.tv_usec / 1000), |
| sWindowWidth, sWindowHeight); |
| gettimeofday(&timeAfter, NULL); |
| |
| #ifdef SAN_ANGELES_OBSERVATION_GLES |
| checkGLErrors(); |
| #endif |
| |
| if (!gAppAlive) |
| break; |
| |
| if (!waffle_window_swap_buffers(sWindow)) |
| waffleError(); |
| |
| #ifndef SAN_ANGELES_OBSERVATION_GLES |
| checkGLErrors(); |
| #endif |
| |
| total_time += (timeAfter.tv_sec - timeNow.tv_sec) + |
| (timeAfter.tv_usec - timeNow.tv_usec) / 1000000.0; |
| num_frames++; |
| } |
| |
| appDeinit(); |
| deinitGraphics(); |
| |
| fprintf(stdout, "frame_rate = %.1f\n", num_frames / total_time); |
| |
| return EXIT_SUCCESS; |
| } |
| |