1 /* 2 Copyright (C) 1997-2014 Sam Lantinga <slouken (at) libsdl.org> 3 4 This software is provided 'as-is', without any express or implied 5 warranty. In no event will the authors be held liable for any damages 6 arising from the use of this software. 7 8 Permission is granted to anyone to use this software for any purpose, 9 including commercial applications, and to alter it and redistribute it 10 freely. 11 */ 12 #include <stdlib.h> 13 #include <stdio.h> 14 #include <string.h> 15 #include <math.h> 16 17 #include "SDL_test_common.h" 18 19 #if defined(__IPHONEOS__) || defined(__ANDROID__) 20 #define HAVE_OPENGLES 21 #endif 22 23 #ifdef HAVE_OPENGLES 24 25 #include "SDL_opengles.h" 26 27 static SDLTest_CommonState *state; 28 static SDL_GLContext *context = NULL; 29 static int depth = 16; 30 31 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ 32 static void 33 quit(int rc) 34 { 35 int i; 36 37 if (context != NULL) { 38 for (i = 0; i < state->num_windows; i++) { 39 if (context[i]) { 40 SDL_GL_DeleteContext(context[i]); 41 } 42 } 43 44 SDL_free(context); 45 } 46 47 SDLTest_CommonQuit(state); 48 exit(rc); 49 } 50 51 static void 52 Render() 53 { 54 static GLubyte color[8][4] = { {255, 0, 0, 0}, 55 {255, 0, 0, 255}, 56 {0, 255, 0, 255}, 57 {0, 255, 0, 255}, 58 {0, 255, 0, 255}, 59 {255, 255, 255, 255}, 60 {255, 0, 255, 255}, 61 {0, 0, 255, 255} 62 }; 63 static GLfloat cube[8][3] = { {0.5, 0.5, -0.5}, 64 {0.5f, -0.5f, -0.5f}, 65 {-0.5f, -0.5f, -0.5f}, 66 {-0.5f, 0.5f, -0.5f}, 67 {-0.5f, 0.5f, 0.5f}, 68 {0.5f, 0.5f, 0.5f}, 69 {0.5f, -0.5f, 0.5f}, 70 {-0.5f, -0.5f, 0.5f} 71 }; 72 static GLubyte indices[36] = { 0, 3, 4, 73 4, 5, 0, 74 0, 5, 6, 75 6, 1, 0, 76 6, 7, 2, 77 2, 1, 6, 78 7, 4, 3, 79 3, 2, 7, 80 5, 4, 7, 81 7, 6, 5, 82 2, 3, 1, 83 3, 0, 1 84 }; 85 86 87 /* Do our drawing, too. */ 88 glClearColor(0.0, 0.0, 0.0, 1.0); 89 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 90 91 /* Draw the cube */ 92 glColorPointer(4, GL_UNSIGNED_BYTE, 0, color); 93 glEnableClientState(GL_COLOR_ARRAY); 94 glVertexPointer(3, GL_FLOAT, 0, cube); 95 glEnableClientState(GL_VERTEX_ARRAY); 96 glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, indices); 97 98 glMatrixMode(GL_MODELVIEW); 99 glRotatef(5.0, 1.0, 1.0, 1.0); 100 } 101 102 int 103 main(int argc, char *argv[]) 104 { 105 int fsaa, accel; 106 int value; 107 int i, done; 108 SDL_DisplayMode mode; 109 SDL_Event event; 110 Uint32 then, now, frames; 111 int status; 112 113 /* Enable standard application logging */ 114 SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); 115 116 /* Initialize parameters */ 117 fsaa = 0; 118 accel = 0; 119 120 /* Initialize test framework */ 121 state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); 122 if (!state) { 123 return 1; 124 } 125 for (i = 1; i < argc;) { 126 int consumed; 127 128 consumed = SDLTest_CommonArg(state, i); 129 if (consumed == 0) { 130 if (SDL_strcasecmp(argv[i], "--fsaa") == 0) { 131 ++fsaa; 132 consumed = 1; 133 } else if (SDL_strcasecmp(argv[i], "--accel") == 0) { 134 ++accel; 135 consumed = 1; 136 } else if (SDL_strcasecmp(argv[i], "--zdepth") == 0) { 137 i++; 138 if (!argv[i]) { 139 consumed = -1; 140 } else { 141 depth = SDL_atoi(argv[i]); 142 consumed = 1; 143 } 144 } else { 145 consumed = -1; 146 } 147 } 148 if (consumed < 0) { 149 SDL_Log("Usage: %s %s [--fsaa] [--accel] [--zdepth %%d]\n", argv[0], 150 SDLTest_CommonUsage(state)); 151 quit(1); 152 } 153 i += consumed; 154 } 155 156 /* Set OpenGL parameters */ 157 state->window_flags |= SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS; 158 state->gl_red_size = 5; 159 state->gl_green_size = 5; 160 state->gl_blue_size = 5; 161 state->gl_depth_size = depth; 162 state->gl_major_version = 1; 163 state->gl_minor_version = 1; 164 state->gl_profile_mask = SDL_GL_CONTEXT_PROFILE_ES; 165 if (fsaa) { 166 state->gl_multisamplebuffers=1; 167 state->gl_multisamplesamples=fsaa; 168 } 169 if (accel) { 170 state->gl_accelerated=1; 171 } 172 if (!SDLTest_CommonInit(state)) { 173 quit(2); 174 } 175 176 context = SDL_calloc(state->num_windows, sizeof(context)); 177 if (context == NULL) { 178 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory!\n"); 179 quit(2); 180 } 181 182 /* Create OpenGL ES contexts */ 183 for (i = 0; i < state->num_windows; i++) { 184 context[i] = SDL_GL_CreateContext(state->windows[i]); 185 if (!context[i]) { 186 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_GL_CreateContext(): %s\n", SDL_GetError()); 187 quit(2); 188 } 189 } 190 191 if (state->render_flags & SDL_RENDERER_PRESENTVSYNC) { 192 SDL_GL_SetSwapInterval(1); 193 } else { 194 SDL_GL_SetSwapInterval(0); 195 } 196 197 SDL_GetCurrentDisplayMode(0, &mode); 198 SDL_Log("Screen bpp: %d\n", SDL_BITSPERPIXEL(mode.format)); 199 SDL_Log("\n"); 200 SDL_Log("Vendor : %s\n", glGetString(GL_VENDOR)); 201 SDL_Log("Renderer : %s\n", glGetString(GL_RENDERER)); 202 SDL_Log("Version : %s\n", glGetString(GL_VERSION)); 203 SDL_Log("Extensions : %s\n", glGetString(GL_EXTENSIONS)); 204 SDL_Log("\n"); 205 206 status = SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value); 207 if (!status) { 208 SDL_Log("SDL_GL_RED_SIZE: requested %d, got %d\n", 5, value); 209 } else { 210 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_RED_SIZE: %s\n", 211 SDL_GetError()); 212 } 213 status = SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &value); 214 if (!status) { 215 SDL_Log("SDL_GL_GREEN_SIZE: requested %d, got %d\n", 5, value); 216 } else { 217 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_GREEN_SIZE: %s\n", 218 SDL_GetError()); 219 } 220 status = SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &value); 221 if (!status) { 222 SDL_Log("SDL_GL_BLUE_SIZE: requested %d, got %d\n", 5, value); 223 } else { 224 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_BLUE_SIZE: %s\n", 225 SDL_GetError()); 226 } 227 status = SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &value); 228 if (!status) { 229 SDL_Log("SDL_GL_DEPTH_SIZE: requested %d, got %d\n", depth, value); 230 } else { 231 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_DEPTH_SIZE: %s\n", 232 SDL_GetError()); 233 } 234 if (fsaa) { 235 status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &value); 236 if (!status) { 237 SDL_Log("SDL_GL_MULTISAMPLEBUFFERS: requested 1, got %d\n", value); 238 } else { 239 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_MULTISAMPLEBUFFERS: %s\n", 240 SDL_GetError()); 241 } 242 status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &value); 243 if (!status) { 244 SDL_Log("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d\n", fsaa, 245 value); 246 } else { 247 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_MULTISAMPLESAMPLES: %s\n", 248 SDL_GetError()); 249 } 250 } 251 if (accel) { 252 status = SDL_GL_GetAttribute(SDL_GL_ACCELERATED_VISUAL, &value); 253 if (!status) { 254 SDL_Log("SDL_GL_ACCELERATED_VISUAL: requested 1, got %d\n", value); 255 } else { 256 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_ACCELERATED_VISUAL: %s\n", 257 SDL_GetError()); 258 } 259 } 260 261 /* Set rendering settings for each context */ 262 for (i = 0; i < state->num_windows; ++i) { 263 float aspectAdjust; 264 265 status = SDL_GL_MakeCurrent(state->windows[i], context[i]); 266 if (status) { 267 SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError()); 268 269 /* Continue for next window */ 270 continue; 271 } 272 273 aspectAdjust = (4.0f / 3.0f) / ((float)state->window_w / state->window_h); 274 glViewport(0, 0, state->window_w, state->window_h); 275 glMatrixMode(GL_PROJECTION); 276 glLoadIdentity(); 277 glOrthof(-2.0, 2.0, -2.0 * aspectAdjust, 2.0 * aspectAdjust, -20.0, 20.0); 278 glMatrixMode(GL_MODELVIEW); 279 glLoadIdentity(); 280 glEnable(GL_DEPTH_TEST); 281 glDepthFunc(GL_LESS); 282 glShadeModel(GL_SMOOTH); 283 } 284 285 /* Main render loop */ 286 frames = 0; 287 then = SDL_GetTicks(); 288 done = 0; 289 while (!done) { 290 /* Check for events */ 291 ++frames; 292 while (SDL_PollEvent(&event)) { 293 switch (event.type) { 294 case SDL_WINDOWEVENT: 295 switch (event.window.event) { 296 case SDL_WINDOWEVENT_RESIZED: 297 for (i = 0; i < state->num_windows; ++i) { 298 if (event.window.windowID == SDL_GetWindowID(state->windows[i])) { 299 status = SDL_GL_MakeCurrent(state->windows[i], context[i]); 300 if (status) { 301 SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError()); 302 break; 303 } 304 /* Change view port to the new window dimensions */ 305 glViewport(0, 0, event.window.data1, event.window.data2); 306 /* Update window content */ 307 Render(); 308 SDL_GL_SwapWindow(state->windows[i]); 309 break; 310 } 311 } 312 break; 313 } 314 } 315 SDLTest_CommonEvent(state, &event, &done); 316 } 317 for (i = 0; i < state->num_windows; ++i) { 318 if (state->windows[i] == NULL) 319 continue; 320 status = SDL_GL_MakeCurrent(state->windows[i], context[i]); 321 if (status) { 322 SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError()); 323 324 /* Continue for next window */ 325 continue; 326 } 327 Render(); 328 SDL_GL_SwapWindow(state->windows[i]); 329 } 330 } 331 332 /* Print out some timing information */ 333 now = SDL_GetTicks(); 334 if (now > then) { 335 SDL_Log("%2.2f frames per second\n", 336 ((double) frames * 1000) / (now - then)); 337 } 338 #if !defined(__ANDROID__) 339 quit(0); 340 #endif 341 return 0; 342 } 343 344 #else /* HAVE_OPENGLES */ 345 346 int 347 main(int argc, char *argv[]) 348 { 349 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No OpenGL ES support on this system\n"); 350 return 1; 351 } 352 353 #endif /* HAVE_OPENGLES */ 354 355 /* vi: set ts=4 sw=4 expandtab: */ 356