| /* 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 <X11/Xlib.h> |
| #include <X11/Xutil.h> |
| #include <X11/keysym.h> |
| |
| #include "importgl.h" |
| |
| #include "app.h" |
| |
| |
| int gAppAlive = 1; |
| |
| static const char sAppName[] = |
| "San Angeles Observation OpenGL ES version example (Linux)"; |
| static Display *sDisplay; |
| static Window sWindow; |
| static int sWindowWidth = WINDOW_DEFAULT_WIDTH; |
| static int sWindowHeight = WINDOW_DEFAULT_HEIGHT; |
| static EGLDisplay sEglDisplay = EGL_NO_DISPLAY; |
| static EGLConfig sEglConfig; |
| static EGLContext sEglContext = EGL_NO_CONTEXT; |
| static EGLSurface sEglSurface = EGL_NO_SURFACE; |
| |
| |
| 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); |
| } |
| |
| |
| // Initializes and opens both X11 display and OpenGL ES. |
| static int initGraphics() |
| { |
| static const EGLint configAttribs[] = |
| { |
| #if (WINDOW_BPP == 16) |
| EGL_RED_SIZE, 5, |
| EGL_GREEN_SIZE, 5, |
| EGL_BLUE_SIZE, 5, |
| #elif (WINDOW_BPP == 32) |
| EGL_RED_SIZE, 8, |
| EGL_GREEN_SIZE, 8, |
| EGL_BLUE_SIZE, 8, |
| #else |
| #error WINDOW_BPP must be 16 or 32 |
| #endif |
| EGL_DEPTH_SIZE, 16, |
| EGL_ALPHA_SIZE, EGL_DONT_CARE, |
| EGL_STENCIL_SIZE, EGL_DONT_CARE, |
| EGL_SURFACE_TYPE, EGL_WINDOW_BIT, |
| EGL_NONE |
| }; |
| EGLBoolean success; |
| EGLint numConfigs; |
| EGLint majorVersion; |
| EGLint minorVersion; |
| |
| int importGLResult; |
| importGLResult = importGLInit(); |
| if (!importGLResult) |
| return 0; |
| |
| sDisplay = XOpenDisplay(NULL); |
| |
| sEglDisplay = eglGetDisplay(sDisplay); |
| success = eglInitialize(sEglDisplay, &majorVersion, &minorVersion); |
| if (success != EGL_FALSE) |
| success = eglGetConfigs(sEglDisplay, NULL, 0, &numConfigs); |
| if (success != EGL_FALSE) |
| success = eglChooseConfig(sEglDisplay, configAttribs, |
| &sEglConfig, 1, &numConfigs); |
| if (success != EGL_FALSE) |
| { |
| sEglContext = eglCreateContext(sEglDisplay, sEglConfig, NULL, NULL); |
| if (sEglContext == EGL_NO_CONTEXT) |
| success = EGL_FALSE; |
| } |
| if (success != EGL_FALSE) |
| { |
| XSetWindowAttributes swa; |
| XVisualInfo *vi, tmp; |
| XSizeHints sh; |
| int n; |
| EGLint vid; |
| |
| eglGetConfigAttrib(sEglDisplay, sEglConfig, |
| EGL_NATIVE_VISUAL_ID, &vid); |
| tmp.visualid = vid; |
| vi = XGetVisualInfo(sDisplay, VisualIDMask, &tmp, &n); |
| swa.colormap = XCreateColormap(sDisplay, |
| RootWindow(sDisplay, vi->screen), |
| vi->visual, AllocNone); |
| sh.flags = PMinSize | PMaxSize; |
| sh.min_width = sh.max_width = sWindowWidth; |
| sh.min_height = sh.max_height = sWindowHeight; |
| swa.border_pixel = 0; |
| swa.event_mask = ExposureMask | StructureNotifyMask | |
| KeyPressMask | ButtonPressMask | ButtonReleaseMask; |
| sWindow = XCreateWindow(sDisplay, RootWindow(sDisplay, vi->screen), |
| 0, 0, sWindowWidth, sWindowHeight, |
| 0, vi->depth, InputOutput, vi->visual, |
| CWBorderPixel | CWColormap | CWEventMask, |
| &swa); |
| XMapWindow(sDisplay, sWindow); |
| XSetStandardProperties(sDisplay, sWindow, sAppName, sAppName, |
| None, (void *)0, 0, &sh); |
| } |
| if (success != EGL_FALSE) |
| { |
| sEglSurface = eglCreateWindowSurface(sEglDisplay, sEglConfig, |
| (NativeWindowType)sWindow, NULL); |
| if (sEglSurface == EGL_NO_SURFACE) |
| success = EGL_FALSE; |
| } |
| if (success != EGL_FALSE) |
| success = eglMakeCurrent(sEglDisplay, sEglSurface, |
| sEglSurface, sEglContext); |
| |
| if (success == EGL_FALSE) |
| checkEGLErrors(); |
| |
| return success != EGL_FALSE; |
| } |
| |
| |
| static void deinitGraphics() |
| { |
| eglMakeCurrent(sEglDisplay, NULL, NULL, NULL); |
| eglDestroyContext(sEglDisplay, sEglContext); |
| eglDestroySurface(sEglDisplay, sEglSurface); |
| eglTerminate(sEglDisplay); |
| importGLDeinit(); |
| } |
| |
| |
| int main(int argc, char *argv[]) |
| { |
| // not referenced: |
| argc = argc; |
| argv = argv; |
| |
| if (!initGraphics()) |
| { |
| fprintf(stderr, "Graphics initialization failed.\n"); |
| return EXIT_FAILURE; |
| } |
| |
| appInit(); |
| |
| while (gAppAlive) |
| { |
| struct timeval timeNow; |
| |
| while (XPending(sDisplay)) |
| { |
| XEvent ev; |
| XNextEvent(sDisplay, &ev); |
| switch (ev.type) |
| { |
| case KeyPress: |
| { |
| unsigned int keycode, keysym; |
| keycode = ((XKeyEvent *)&ev)->keycode; |
| keysym = XKeycodeToKeysym(sDisplay, keycode, 0); |
| if (keysym == XK_Return || keysym == XK_Escape) |
| gAppAlive = 0; |
| } |
| break; |
| } |
| } |
| |
| if (gAppAlive) |
| { |
| gettimeofday(&timeNow, NULL); |
| appRender(timeNow.tv_sec * 1000 + timeNow.tv_usec / 1000, |
| sWindowWidth, sWindowHeight); |
| checkGLErrors(); |
| eglSwapBuffers(sEglDisplay, sEglSurface); |
| checkEGLErrors(); |
| } |
| } |
| |
| appDeinit(); |
| deinitGraphics(); |
| |
| return EXIT_SUCCESS; |
| } |