blob: c6a55d4fe40ca42f21005ecdcf59b36850671287 [file] [log] [blame]
/* 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;
}