testgl2.c (11873B)
1/* 2 Copyright (C) 1997-2014 Sam Lantinga <slouken@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#ifdef __MACOS__ 20#define HAVE_OPENGL 21#endif 22 23#ifdef HAVE_OPENGL 24 25#include "SDL_opengl.h" 26 27typedef struct GL_Context 28{ 29#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params; 30#include "../src/render/opengl/SDL_glfuncs.h" 31#undef SDL_PROC 32} GL_Context; 33 34 35/* Undefine this if you want a flat cube instead of a rainbow cube */ 36#define SHADED_CUBE 37 38static SDLTest_CommonState *state; 39static SDL_GLContext context; 40static GL_Context ctx; 41 42static int LoadContext(GL_Context * data) 43{ 44#if SDL_VIDEO_DRIVER_UIKIT 45#define __SDL_NOGETPROCADDR__ 46#elif SDL_VIDEO_DRIVER_ANDROID 47#define __SDL_NOGETPROCADDR__ 48#elif SDL_VIDEO_DRIVER_PANDORA 49#define __SDL_NOGETPROCADDR__ 50#endif 51 52#if defined __SDL_NOGETPROCADDR__ 53#define SDL_PROC(ret,func,params) data->func=func; 54#else 55#define SDL_PROC(ret,func,params) \ 56 do { \ 57 data->func = SDL_GL_GetProcAddress(#func); \ 58 if ( ! data->func ) { \ 59 return SDL_SetError("Couldn't load GL function %s: %s\n", #func, SDL_GetError()); \ 60 } \ 61 } while ( 0 ); 62#endif /* _SDL_NOGETPROCADDR_ */ 63 64#include "../src/render/opengl/SDL_glfuncs.h" 65#undef SDL_PROC 66 return 0; 67} 68 69 70/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ 71static void 72quit(int rc) 73{ 74 if (context) { 75 /* SDL_GL_MakeCurrent(0, NULL); *//* doesn't do anything */ 76 SDL_GL_DeleteContext(context); 77 } 78 SDLTest_CommonQuit(state); 79 exit(rc); 80} 81 82static void 83Render() 84{ 85 static float color[8][3] = { 86 {1.0, 1.0, 0.0}, 87 {1.0, 0.0, 0.0}, 88 {0.0, 0.0, 0.0}, 89 {0.0, 1.0, 0.0}, 90 {0.0, 1.0, 1.0}, 91 {1.0, 1.0, 1.0}, 92 {1.0, 0.0, 1.0}, 93 {0.0, 0.0, 1.0} 94 }; 95 static float cube[8][3] = { 96 {0.5, 0.5, -0.5}, 97 {0.5, -0.5, -0.5}, 98 {-0.5, -0.5, -0.5}, 99 {-0.5, 0.5, -0.5}, 100 {-0.5, 0.5, 0.5}, 101 {0.5, 0.5, 0.5}, 102 {0.5, -0.5, 0.5}, 103 {-0.5, -0.5, 0.5} 104 }; 105 106 /* Do our drawing, too. */ 107 ctx.glClearColor(0.0, 0.0, 0.0, 1.0); 108 ctx.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 109 110 ctx.glBegin(GL_QUADS); 111 112#ifdef SHADED_CUBE 113 ctx.glColor3fv(color[0]); 114 ctx.glVertex3fv(cube[0]); 115 ctx.glColor3fv(color[1]); 116 ctx.glVertex3fv(cube[1]); 117 ctx.glColor3fv(color[2]); 118 ctx.glVertex3fv(cube[2]); 119 ctx.glColor3fv(color[3]); 120 ctx.glVertex3fv(cube[3]); 121 122 ctx.glColor3fv(color[3]); 123 ctx.glVertex3fv(cube[3]); 124 ctx.glColor3fv(color[4]); 125 ctx.glVertex3fv(cube[4]); 126 ctx.glColor3fv(color[7]); 127 ctx.glVertex3fv(cube[7]); 128 ctx.glColor3fv(color[2]); 129 ctx.glVertex3fv(cube[2]); 130 131 ctx.glColor3fv(color[0]); 132 ctx.glVertex3fv(cube[0]); 133 ctx.glColor3fv(color[5]); 134 ctx.glVertex3fv(cube[5]); 135 ctx.glColor3fv(color[6]); 136 ctx.glVertex3fv(cube[6]); 137 ctx.glColor3fv(color[1]); 138 ctx.glVertex3fv(cube[1]); 139 140 ctx.glColor3fv(color[5]); 141 ctx.glVertex3fv(cube[5]); 142 ctx.glColor3fv(color[4]); 143 ctx.glVertex3fv(cube[4]); 144 ctx.glColor3fv(color[7]); 145 ctx.glVertex3fv(cube[7]); 146 ctx.glColor3fv(color[6]); 147 ctx.glVertex3fv(cube[6]); 148 149 ctx.glColor3fv(color[5]); 150 ctx.glVertex3fv(cube[5]); 151 ctx.glColor3fv(color[0]); 152 ctx.glVertex3fv(cube[0]); 153 ctx.glColor3fv(color[3]); 154 ctx.glVertex3fv(cube[3]); 155 ctx.glColor3fv(color[4]); 156 ctx.glVertex3fv(cube[4]); 157 158 ctx.glColor3fv(color[6]); 159 ctx.glVertex3fv(cube[6]); 160 ctx.glColor3fv(color[1]); 161 ctx.glVertex3fv(cube[1]); 162 ctx.glColor3fv(color[2]); 163 ctx.glVertex3fv(cube[2]); 164 ctx.glColor3fv(color[7]); 165 ctx.glVertex3fv(cube[7]); 166#else /* flat cube */ 167 ctx.glColor3f(1.0, 0.0, 0.0); 168 ctx.glVertex3fv(cube[0]); 169 ctx.glVertex3fv(cube[1]); 170 ctx.glVertex3fv(cube[2]); 171 ctx.glVertex3fv(cube[3]); 172 173 ctx.glColor3f(0.0, 1.0, 0.0); 174 ctx.glVertex3fv(cube[3]); 175 ctx.glVertex3fv(cube[4]); 176 ctx.glVertex3fv(cube[7]); 177 ctx.glVertex3fv(cube[2]); 178 179 ctx.glColor3f(0.0, 0.0, 1.0); 180 ctx.glVertex3fv(cube[0]); 181 ctx.glVertex3fv(cube[5]); 182 ctx.glVertex3fv(cube[6]); 183 ctx.glVertex3fv(cube[1]); 184 185 ctx.glColor3f(0.0, 1.0, 1.0); 186 ctx.glVertex3fv(cube[5]); 187 ctx.glVertex3fv(cube[4]); 188 ctx.glVertex3fv(cube[7]); 189 ctx.glVertex3fv(cube[6]); 190 191 ctx.glColor3f(1.0, 1.0, 0.0); 192 ctx.glVertex3fv(cube[5]); 193 ctx.glVertex3fv(cube[0]); 194 ctx.glVertex3fv(cube[3]); 195 ctx.glVertex3fv(cube[4]); 196 197 ctx.glColor3f(1.0, 0.0, 1.0); 198 ctx.glVertex3fv(cube[6]); 199 ctx.glVertex3fv(cube[1]); 200 ctx.glVertex3fv(cube[2]); 201 ctx.glVertex3fv(cube[7]); 202#endif /* SHADED_CUBE */ 203 204 ctx.glEnd(); 205 206 ctx.glMatrixMode(GL_MODELVIEW); 207 ctx.glRotatef(5.0, 1.0, 1.0, 1.0); 208} 209 210int 211main(int argc, char *argv[]) 212{ 213 int fsaa, accel; 214 int value; 215 int i, done; 216 SDL_DisplayMode mode; 217 SDL_Event event; 218 Uint32 then, now, frames; 219 int status; 220 int dw, dh; 221 222 /* Enable standard application logging */ 223 SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); 224 225 /* Initialize parameters */ 226 fsaa = 0; 227 accel = -1; 228 229 /* Initialize test framework */ 230 state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); 231 if (!state) { 232 return 1; 233 } 234 for (i = 1; i < argc;) { 235 int consumed; 236 237 consumed = SDLTest_CommonArg(state, i); 238 if (consumed == 0) { 239 if (SDL_strcasecmp(argv[i], "--fsaa") == 0 && i+1 < argc) { 240 fsaa = atoi(argv[i+1]); 241 consumed = 2; 242 } else if (SDL_strcasecmp(argv[i], "--accel") == 0 && i+1 < argc) { 243 accel = atoi(argv[i+1]); 244 consumed = 2; 245 } else { 246 consumed = -1; 247 } 248 } 249 if (consumed < 0) { 250 SDL_Log("Usage: %s %s [--fsaa n] [--accel n]\n", argv[0], 251 SDLTest_CommonUsage(state)); 252 quit(1); 253 } 254 i += consumed; 255 } 256 257 /* Set OpenGL parameters */ 258 state->window_flags |= SDL_WINDOW_OPENGL; 259 state->gl_red_size = 5; 260 state->gl_green_size = 5; 261 state->gl_blue_size = 5; 262 state->gl_depth_size = 16; 263 state->gl_double_buffer = 1; 264 if (fsaa) { 265 state->gl_multisamplebuffers = 1; 266 state->gl_multisamplesamples = fsaa; 267 } 268 if (accel >= 0) { 269 state->gl_accelerated = accel; 270 } 271 272 if (!SDLTest_CommonInit(state)) { 273 quit(2); 274 } 275 276 /* Create OpenGL context */ 277 context = SDL_GL_CreateContext(state->windows[0]); 278 if (!context) { 279 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_GL_CreateContext(): %s\n", SDL_GetError()); 280 quit(2); 281 } 282 283 /* Important: call this *after* creating the context */ 284 if (LoadContext(&ctx) < 0) { 285 SDL_Log("Could not load GL functions\n"); 286 quit(2); 287 return 0; 288 } 289 290 if (state->render_flags & SDL_RENDERER_PRESENTVSYNC) { 291 /* try late-swap-tearing first. If not supported, try normal vsync. */ 292 if (SDL_GL_SetSwapInterval(-1) == -1) { 293 SDL_GL_SetSwapInterval(1); 294 } 295 } else { 296 SDL_GL_SetSwapInterval(0); /* disable vsync. */ 297 } 298 299 SDL_GetCurrentDisplayMode(0, &mode); 300 SDL_Log("Screen BPP : %d\n", SDL_BITSPERPIXEL(mode.format)); 301 SDL_Log("Swap Interval : %d\n", SDL_GL_GetSwapInterval()); 302 SDL_GetWindowSize(state->windows[0], &dw, &dh); 303 SDL_Log("Window Size : %d,%d\n", dw, dh); 304 SDL_GL_GetDrawableSize(state->windows[0], &dw, &dh); 305 SDL_Log("Draw Size : %d,%d\n", dw, dh); 306 SDL_Log("\n"); 307 SDL_Log("Vendor : %s\n", ctx.glGetString(GL_VENDOR)); 308 SDL_Log("Renderer : %s\n", ctx.glGetString(GL_RENDERER)); 309 SDL_Log("Version : %s\n", ctx.glGetString(GL_VERSION)); 310 SDL_Log("Extensions : %s\n", ctx.glGetString(GL_EXTENSIONS)); 311 SDL_Log("\n"); 312 313 status = SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value); 314 if (!status) { 315 SDL_Log("SDL_GL_RED_SIZE: requested %d, got %d\n", 5, value); 316 } else { 317 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_RED_SIZE: %s\n", SDL_GetError()); 318 } 319 status = SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &value); 320 if (!status) { 321 SDL_Log("SDL_GL_GREEN_SIZE: requested %d, got %d\n", 5, value); 322 } else { 323 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_GREEN_SIZE: %s\n", SDL_GetError()); 324 } 325 status = SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &value); 326 if (!status) { 327 SDL_Log("SDL_GL_BLUE_SIZE: requested %d, got %d\n", 5, value); 328 } else { 329 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_BLUE_SIZE: %s\n", SDL_GetError()); 330 } 331 status = SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &value); 332 if (!status) { 333 SDL_Log("SDL_GL_DEPTH_SIZE: requested %d, got %d\n", 16, value); 334 } else { 335 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_DEPTH_SIZE: %s\n", SDL_GetError()); 336 } 337 if (fsaa) { 338 status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &value); 339 if (!status) { 340 SDL_Log("SDL_GL_MULTISAMPLEBUFFERS: requested 1, got %d\n", value); 341 } else { 342 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_MULTISAMPLEBUFFERS: %s\n", 343 SDL_GetError()); 344 } 345 status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &value); 346 if (!status) { 347 SDL_Log("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d\n", fsaa, 348 value); 349 } else { 350 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_MULTISAMPLESAMPLES: %s\n", 351 SDL_GetError()); 352 } 353 } 354 if (accel >= 0) { 355 status = SDL_GL_GetAttribute(SDL_GL_ACCELERATED_VISUAL, &value); 356 if (!status) { 357 SDL_Log("SDL_GL_ACCELERATED_VISUAL: requested %d, got %d\n", accel, 358 value); 359 } else { 360 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_ACCELERATED_VISUAL: %s\n", 361 SDL_GetError()); 362 } 363 } 364 365 /* Set rendering settings */ 366 ctx.glMatrixMode(GL_PROJECTION); 367 ctx.glLoadIdentity(); 368 ctx.glOrtho(-2.0, 2.0, -2.0, 2.0, -20.0, 20.0); 369 ctx.glMatrixMode(GL_MODELVIEW); 370 ctx.glLoadIdentity(); 371 ctx.glEnable(GL_DEPTH_TEST); 372 ctx.glDepthFunc(GL_LESS); 373 ctx.glShadeModel(GL_SMOOTH); 374 375 /* Main render loop */ 376 frames = 0; 377 then = SDL_GetTicks(); 378 done = 0; 379 while (!done) { 380 /* Check for events */ 381 ++frames; 382 while (SDL_PollEvent(&event)) { 383 SDLTest_CommonEvent(state, &event, &done); 384 } 385 for (i = 0; i < state->num_windows; ++i) { 386 int w, h; 387 if (state->windows[i] == NULL) 388 continue; 389 SDL_GL_MakeCurrent(state->windows[i], context); 390 SDL_GL_GetDrawableSize(state->windows[i], &w, &h); 391 ctx.glViewport(0, 0, w, h); 392 Render(); 393 SDL_GL_SwapWindow(state->windows[i]); 394 } 395 } 396 397 /* Print out some timing information */ 398 now = SDL_GetTicks(); 399 if (now > then) { 400 SDL_Log("%2.2f frames per second\n", 401 ((double) frames * 1000) / (now - then)); 402 } 403 quit(0); 404 return 0; 405} 406 407#else /* HAVE_OPENGL */ 408 409int 410main(int argc, char *argv[]) 411{ 412 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No OpenGL support on this system\n"); 413 return 1; 414} 415 416#endif /* HAVE_OPENGL */