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 <sys/time.h> 51 #include <X11/Xlib.h> 52 #include <X11/Xutil.h> 53 #include <X11/keysym.h> 54 55 #include "importgl.h" 56 57 #include "app.h" 58 59 60 int gAppAlive = 1; 61 62 static const char sAppName[] = 63 "San Angeles Observation OpenGL ES version example (Linux)"; 64 static Display *sDisplay; 65 static Window sWindow; 66 static int sWindowWidth = WINDOW_DEFAULT_WIDTH; 67 static int sWindowHeight = WINDOW_DEFAULT_HEIGHT; 68 static EGLDisplay sEglDisplay = EGL_NO_DISPLAY; 69 static EGLConfig sEglConfig; 70 static EGLContext sEglContext = EGL_NO_CONTEXT; 71 static EGLSurface sEglSurface = EGL_NO_SURFACE; 72 73 74 static void checkGLErrors() 75 { 76 GLenum error = glGetError(); 77 if (error != GL_NO_ERROR) 78 fprintf(stderr, "GL Error: 0x%04x\n", (int)error); 79 } 80 81 82 static void checkEGLErrors() 83 { 84 EGLint error = eglGetError(); 85 // GLESonGL seems to be returning 0 when there is no errors? 86 if (error && error != EGL_SUCCESS) 87 fprintf(stderr, "EGL Error: 0x%04x\n", (int)error); 88 } 89 90 91 // Initializes and opens both X11 display and OpenGL ES. 92 static int initGraphics() 93 { 94 static const EGLint configAttribs[] = 95 { 96 #if (WINDOW_BPP == 16) 97 EGL_RED_SIZE, 5, 98 EGL_GREEN_SIZE, 5, 99 EGL_BLUE_SIZE, 5, 100 #elif (WINDOW_BPP == 32) 101 EGL_RED_SIZE, 8, 102 EGL_GREEN_SIZE, 8, 103 EGL_BLUE_SIZE, 8, 104 #else 105 #error WINDOW_BPP must be 16 or 32 106 #endif 107 EGL_DEPTH_SIZE, 16, 108 EGL_ALPHA_SIZE, EGL_DONT_CARE, 109 EGL_STENCIL_SIZE, EGL_DONT_CARE, 110 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 111 EGL_NONE 112 }; 113 EGLBoolean success; 114 EGLint numConfigs; 115 EGLint majorVersion; 116 EGLint minorVersion; 117 118 int importGLResult; 119 importGLResult = importGLInit(); 120 if (!importGLResult) 121 return 0; 122 123 sDisplay = XOpenDisplay(NULL); 124 125 sEglDisplay = eglGetDisplay(sDisplay); 126 success = eglInitialize(sEglDisplay, &majorVersion, &minorVersion); 127 if (success != EGL_FALSE) 128 success = eglGetConfigs(sEglDisplay, NULL, 0, &numConfigs); 129 if (success != EGL_FALSE) 130 success = eglChooseConfig(sEglDisplay, configAttribs, 131 &sEglConfig, 1, &numConfigs); 132 if (success != EGL_FALSE) 133 { 134 sEglContext = eglCreateContext(sEglDisplay, sEglConfig, NULL, NULL); 135 if (sEglContext == EGL_NO_CONTEXT) 136 success = EGL_FALSE; 137 } 138 if (success != EGL_FALSE) 139 { 140 XSetWindowAttributes swa; 141 XVisualInfo *vi, tmp; 142 XSizeHints sh; 143 int n; 144 EGLint vid; 145 146 eglGetConfigAttrib(sEglDisplay, sEglConfig, 147 EGL_NATIVE_VISUAL_ID, &vid); 148 tmp.visualid = vid; 149 vi = XGetVisualInfo(sDisplay, VisualIDMask, &tmp, &n); 150 swa.colormap = XCreateColormap(sDisplay, 151 RootWindow(sDisplay, vi->screen), 152 vi->visual, AllocNone); 153 sh.flags = PMinSize | PMaxSize; 154 sh.min_width = sh.max_width = sWindowWidth; 155 sh.min_height = sh.max_height = sWindowHeight; 156 swa.border_pixel = 0; 157 swa.event_mask = ExposureMask | StructureNotifyMask | 158 KeyPressMask | ButtonPressMask | ButtonReleaseMask; 159 sWindow = XCreateWindow(sDisplay, RootWindow(sDisplay, vi->screen), 160 0, 0, sWindowWidth, sWindowHeight, 161 0, vi->depth, InputOutput, vi->visual, 162 CWBorderPixel | CWColormap | CWEventMask, 163 &swa); 164 XMapWindow(sDisplay, sWindow); 165 XSetStandardProperties(sDisplay, sWindow, sAppName, sAppName, 166 None, (void *)0, 0, &sh); 167 } 168 if (success != EGL_FALSE) 169 { 170 sEglSurface = eglCreateWindowSurface(sEglDisplay, sEglConfig, 171 (NativeWindowType)sWindow, NULL); 172 if (sEglSurface == EGL_NO_SURFACE) 173 success = EGL_FALSE; 174 } 175 if (success != EGL_FALSE) 176 success = eglMakeCurrent(sEglDisplay, sEglSurface, 177 sEglSurface, sEglContext); 178 179 if (success == EGL_FALSE) 180 checkEGLErrors(); 181 182 return success != EGL_FALSE; 183 } 184 185 186 static void deinitGraphics() 187 { 188 eglMakeCurrent(sEglDisplay, NULL, NULL, NULL); 189 eglDestroyContext(sEglDisplay, sEglContext); 190 eglDestroySurface(sEglDisplay, sEglSurface); 191 eglTerminate(sEglDisplay); 192 importGLDeinit(); 193 } 194 195 196 int main(int argc, char *argv[]) 197 { 198 // not referenced: 199 argc = argc; 200 argv = argv; 201 202 if (!initGraphics()) 203 { 204 fprintf(stderr, "Graphics initialization failed.\n"); 205 return EXIT_FAILURE; 206 } 207 208 appInit(); 209 210 while (gAppAlive) 211 { 212 struct timeval timeNow; 213 214 while (XPending(sDisplay)) 215 { 216 XEvent ev; 217 XNextEvent(sDisplay, &ev); 218 switch (ev.type) 219 { 220 case KeyPress: 221 { 222 unsigned int keycode, keysym; 223 keycode = ((XKeyEvent *)&ev)->keycode; 224 keysym = XKeycodeToKeysym(sDisplay, keycode, 0); 225 if (keysym == XK_Return || keysym == XK_Escape) 226 gAppAlive = 0; 227 } 228 break; 229 } 230 } 231 232 if (gAppAlive) 233 { 234 gettimeofday(&timeNow, NULL); 235 appRender(timeNow.tv_sec * 1000 + timeNow.tv_usec / 1000, 236 sWindowWidth, sWindowHeight); 237 checkGLErrors(); 238 eglSwapBuffers(sEglDisplay, sEglSurface); 239 checkEGLErrors(); 240 } 241 } 242 243 appDeinit(); 244 deinitGraphics(); 245 246 return EXIT_SUCCESS; 247 } 248