Atlas - testgl.c

Home / ext / SDL / test Lines: 1 | Size: 13752 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Copyright (C) 1997-2025 Sam Lantinga <[email protected]> 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 <SDL3/SDL_test_common.h> 13#include <SDL3/SDL_main.h> 14 15#ifdef HAVE_OPENGL 16 17#include <stdlib.h> 18 19#include <SDL3/SDL_opengl.h> 20 21typedef struct GL_Context 22{ 23#define SDL_PROC(ret, func, params) ret (APIENTRY *func) params; 24#include "../src/render/opengl/SDL_glfuncs.h" 25#undef SDL_PROC 26} GL_Context; 27 28/* Undefine this if you want a flat cube instead of a rainbow cube */ 29#define SHADED_CUBE 30 31static SDLTest_CommonState *state; 32static SDL_GLContext context; 33static GL_Context ctx; 34static bool suspend_when_occluded; 35 36static bool LoadContext(GL_Context *data) 37{ 38#ifdef SDL_VIDEO_DRIVER_UIKIT 39#define __SDL_NOGETPROCADDR__ 40#elif defined(SDL_VIDEO_DRIVER_ANDROID) 41#define __SDL_NOGETPROCADDR__ 42#endif 43 44#if defined __SDL_NOGETPROCADDR__ 45#define SDL_PROC(ret, func, params) data->func = func; 46#else 47#define SDL_PROC(ret, func, params) \ 48 do { \ 49 data->func = (ret (APIENTRY *) params)SDL_GL_GetProcAddress(#func); \ 50 if (!data->func) { \ 51 return SDL_SetError("Couldn't load GL function %s: %s", #func, SDL_GetError()); \ 52 } \ 53 } while (0); 54#endif /* __SDL_NOGETPROCADDR__ */ 55 56#include "../src/render/opengl/SDL_glfuncs.h" 57#undef SDL_PROC 58 return true; 59} 60 61/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ 62static void quit(int rc) 63{ 64 if (context) { 65 /* SDL_GL_MakeCurrent(0, NULL); */ /* doesn't do anything */ 66 SDL_GL_DestroyContext(context); 67 } 68 SDLTest_CommonQuit(state); 69 /* Let 'main()' return normally */ 70 if (rc != 0) { 71 exit(rc); 72 } 73} 74 75static void Render(void) 76{ 77 static float color[8][3] = { 78 { 1.0, 1.0, 0.0 }, 79 { 1.0, 0.0, 0.0 }, 80 { 0.0, 0.0, 0.0 }, 81 { 0.0, 1.0, 0.0 }, 82 { 0.0, 1.0, 1.0 }, 83 { 1.0, 1.0, 1.0 }, 84 { 1.0, 0.0, 1.0 }, 85 { 0.0, 0.0, 1.0 } 86 }; 87 static float cube[8][3] = { 88 { 0.5, 0.5, -0.5 }, 89 { 0.5, -0.5, -0.5 }, 90 { -0.5, -0.5, -0.5 }, 91 { -0.5, 0.5, -0.5 }, 92 { -0.5, 0.5, 0.5 }, 93 { 0.5, 0.5, 0.5 }, 94 { 0.5, -0.5, 0.5 }, 95 { -0.5, -0.5, 0.5 } 96 }; 97 98 /* Do our drawing, too. */ 99 ctx.glClearColor(0.0, 0.0, 0.0, 0.0 /* used with --transparent */); 100 ctx.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 101 102 ctx.glBegin(GL_QUADS); 103 104#ifdef SHADED_CUBE 105 ctx.glColor3fv(color[0]); 106 ctx.glVertex3fv(cube[0]); 107 ctx.glColor3fv(color[1]); 108 ctx.glVertex3fv(cube[1]); 109 ctx.glColor3fv(color[2]); 110 ctx.glVertex3fv(cube[2]); 111 ctx.glColor3fv(color[3]); 112 ctx.glVertex3fv(cube[3]); 113 114 ctx.glColor3fv(color[3]); 115 ctx.glVertex3fv(cube[3]); 116 ctx.glColor3fv(color[4]); 117 ctx.glVertex3fv(cube[4]); 118 ctx.glColor3fv(color[7]); 119 ctx.glVertex3fv(cube[7]); 120 ctx.glColor3fv(color[2]); 121 ctx.glVertex3fv(cube[2]); 122 123 ctx.glColor3fv(color[0]); 124 ctx.glVertex3fv(cube[0]); 125 ctx.glColor3fv(color[5]); 126 ctx.glVertex3fv(cube[5]); 127 ctx.glColor3fv(color[6]); 128 ctx.glVertex3fv(cube[6]); 129 ctx.glColor3fv(color[1]); 130 ctx.glVertex3fv(cube[1]); 131 132 ctx.glColor3fv(color[5]); 133 ctx.glVertex3fv(cube[5]); 134 ctx.glColor3fv(color[4]); 135 ctx.glVertex3fv(cube[4]); 136 ctx.glColor3fv(color[7]); 137 ctx.glVertex3fv(cube[7]); 138 ctx.glColor3fv(color[6]); 139 ctx.glVertex3fv(cube[6]); 140 141 ctx.glColor3fv(color[5]); 142 ctx.glVertex3fv(cube[5]); 143 ctx.glColor3fv(color[0]); 144 ctx.glVertex3fv(cube[0]); 145 ctx.glColor3fv(color[3]); 146 ctx.glVertex3fv(cube[3]); 147 ctx.glColor3fv(color[4]); 148 ctx.glVertex3fv(cube[4]); 149 150 ctx.glColor3fv(color[6]); 151 ctx.glVertex3fv(cube[6]); 152 ctx.glColor3fv(color[1]); 153 ctx.glVertex3fv(cube[1]); 154 ctx.glColor3fv(color[2]); 155 ctx.glVertex3fv(cube[2]); 156 ctx.glColor3fv(color[7]); 157 ctx.glVertex3fv(cube[7]); 158#else /* flat cube */ 159 ctx.glColor3f(1.0, 0.0, 0.0); 160 ctx.glVertex3fv(cube[0]); 161 ctx.glVertex3fv(cube[1]); 162 ctx.glVertex3fv(cube[2]); 163 ctx.glVertex3fv(cube[3]); 164 165 ctx.glColor3f(0.0, 1.0, 0.0); 166 ctx.glVertex3fv(cube[3]); 167 ctx.glVertex3fv(cube[4]); 168 ctx.glVertex3fv(cube[7]); 169 ctx.glVertex3fv(cube[2]); 170 171 ctx.glColor3f(0.0, 0.0, 1.0); 172 ctx.glVertex3fv(cube[0]); 173 ctx.glVertex3fv(cube[5]); 174 ctx.glVertex3fv(cube[6]); 175 ctx.glVertex3fv(cube[1]); 176 177 ctx.glColor3f(0.0, 1.0, 1.0); 178 ctx.glVertex3fv(cube[5]); 179 ctx.glVertex3fv(cube[4]); 180 ctx.glVertex3fv(cube[7]); 181 ctx.glVertex3fv(cube[6]); 182 183 ctx.glColor3f(1.0, 1.0, 0.0); 184 ctx.glVertex3fv(cube[5]); 185 ctx.glVertex3fv(cube[0]); 186 ctx.glVertex3fv(cube[3]); 187 ctx.glVertex3fv(cube[4]); 188 189 ctx.glColor3f(1.0, 0.0, 1.0); 190 ctx.glVertex3fv(cube[6]); 191 ctx.glVertex3fv(cube[1]); 192 ctx.glVertex3fv(cube[2]); 193 ctx.glVertex3fv(cube[7]); 194#endif /* SHADED_CUBE */ 195 196 ctx.glEnd(); 197 198 ctx.glMatrixMode(GL_MODELVIEW); 199 ctx.glRotatef(5.0, 1.0, 1.0, 1.0); 200} 201 202static void LogSwapInterval(void) 203{ 204 int interval = 0; 205 if (SDL_GL_GetSwapInterval(&interval)) { 206 SDL_Log("Swap Interval : %d", interval); 207 } else { 208 SDL_Log("Swap Interval : %d error: %s", interval, SDL_GetError()); 209 } 210} 211 212int main(int argc, char *argv[]) 213{ 214 int fsaa, accel; 215 int value; 216 int i, done; 217 const SDL_DisplayMode *mode; 218 SDL_Event event; 219 Uint64 then, now; 220 Uint32 frames; 221 int dw, dh; 222 int swap_interval = 0; 223 224 /* Initialize parameters */ 225 fsaa = 0; 226 accel = -1; 227 228 /* Initialize test framework */ 229 state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); 230 if (!state) { 231 return 1; 232 } 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 = SDL_atoi(argv[i + 1]); 241 consumed = 2; 242 } else if (SDL_strcasecmp(argv[i], "--accel") == 0 && i + 1 < argc) { 243 accel = SDL_atoi(argv[i + 1]); 244 consumed = 2; 245 } else if(SDL_strcasecmp(argv[i], "--suspend-when-occluded") == 0) { 246 suspend_when_occluded = true; 247 consumed = 1; 248 } else { 249 consumed = -1; 250 } 251 } 252 if (consumed < 0) { 253 static const char *options[] = { "[--fsaa n]", "[--accel n]", "[--suspend-when-occluded]", NULL }; 254 SDLTest_CommonLogUsage(state, argv[0], options); 255 quit(1); 256 } 257 i += consumed; 258 } 259 260 /* Set OpenGL parameters */ 261 state->window_flags |= SDL_WINDOW_OPENGL; 262 state->gl_red_size = 5; 263 state->gl_green_size = 5; 264 state->gl_blue_size = 5; 265 state->gl_depth_size = 16; 266 /* For release_behavior to work, at least on Windows, you'll most likely need to set state->gl_major_version = 3 */ 267 /* state->gl_major_version = 3; */ 268 state->gl_release_behavior = 0; 269 state->gl_double_buffer = 1; 270 if (fsaa) { 271 state->gl_multisamplebuffers = 1; 272 state->gl_multisamplesamples = fsaa; 273 } 274 if (accel >= 0) { 275 state->gl_accelerated = accel; 276 } 277 278 if (!SDLTest_CommonInit(state)) { 279 quit(2); 280 } 281 282 /* Create OpenGL context */ 283 context = SDL_GL_CreateContext(state->windows[0]); 284 if (!context) { 285 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_GL_CreateContext(): %s", SDL_GetError()); 286 quit(2); 287 } 288 289 /* Important: call this *after* creating the context */ 290 if (!LoadContext(&ctx)) { 291 SDL_Log("Could not load GL functions"); 292 quit(2); 293 return 0; 294 } 295 296 SDL_GL_SetSwapInterval(state->render_vsync); 297 swap_interval = state->render_vsync; 298 299 mode = SDL_GetCurrentDisplayMode(SDL_GetPrimaryDisplay()); 300 if (mode) { 301 SDL_Log("Screen BPP : %d", SDL_BITSPERPIXEL(mode->format)); 302 } 303 304 LogSwapInterval(); 305 306 SDL_GetWindowSize(state->windows[0], &dw, &dh); 307 SDL_Log("Window Size : %d,%d", dw, dh); 308 SDL_GetWindowSizeInPixels(state->windows[0], &dw, &dh); 309 SDL_Log("Draw Size : %d,%d", dw, dh); 310 SDL_Log("%s", ""); 311 SDL_Log("Vendor : %s", ctx.glGetString(GL_VENDOR)); 312 SDL_Log("Renderer : %s", ctx.glGetString(GL_RENDERER)); 313 SDL_Log("Version : %s", ctx.glGetString(GL_VERSION)); 314 SDL_Log("Extensions : %s", ctx.glGetString(GL_EXTENSIONS)); 315 SDL_Log("%s", ""); 316 317 if (SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value)) { 318 SDL_Log("SDL_GL_RED_SIZE: requested %d, got %d", 5, value); 319 } else { 320 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_RED_SIZE: %s", SDL_GetError()); 321 } 322 if (SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &value)) { 323 SDL_Log("SDL_GL_GREEN_SIZE: requested %d, got %d", 5, value); 324 } else { 325 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_GREEN_SIZE: %s", SDL_GetError()); 326 } 327 if (SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &value)) { 328 SDL_Log("SDL_GL_BLUE_SIZE: requested %d, got %d", 5, value); 329 } else { 330 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_BLUE_SIZE: %s", SDL_GetError()); 331 } 332 if (SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &value)) { 333 SDL_Log("SDL_GL_DEPTH_SIZE: requested %d, got %d", 16, value); 334 } else { 335 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_DEPTH_SIZE: %s", SDL_GetError()); 336 } 337 if (SDL_GL_GetAttribute(SDL_GL_CONTEXT_RELEASE_BEHAVIOR, &value)) { 338 SDL_Log("SDL_GL_CONTEXT_RELEASE_BEHAVIOR: requested %d, got %d", 0, value); 339 } else { 340 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_CONTEXT_RELEASE_BEHAVIOR: %s", SDL_GetError()); 341 } 342 if (fsaa) { 343 if (SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &value)) { 344 SDL_Log("SDL_GL_MULTISAMPLEBUFFERS: requested 1, got %d", value); 345 } else { 346 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_MULTISAMPLEBUFFERS: %s", 347 SDL_GetError()); 348 } 349 if (SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &value)) { 350 SDL_Log("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d", fsaa, 351 value); 352 } else { 353 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_MULTISAMPLESAMPLES: %s", 354 SDL_GetError()); 355 } 356 } 357 if (accel >= 0) { 358 if (SDL_GL_GetAttribute(SDL_GL_ACCELERATED_VISUAL, &value)) { 359 SDL_Log("SDL_GL_ACCELERATED_VISUAL: requested %d, got %d", accel, 360 value); 361 } else { 362 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_ACCELERATED_VISUAL: %s", 363 SDL_GetError()); 364 } 365 } 366 367 /* Set rendering settings */ 368 ctx.glMatrixMode(GL_PROJECTION); 369 ctx.glLoadIdentity(); 370 ctx.glOrtho(-2.0, 2.0, -2.0, 2.0, -20.0, 20.0); 371 ctx.glMatrixMode(GL_MODELVIEW); 372 ctx.glLoadIdentity(); 373 ctx.glEnable(GL_DEPTH_TEST); 374 ctx.glDepthFunc(GL_LESS); 375 ctx.glShadeModel(GL_SMOOTH); 376 377 /* Main render loop */ 378 frames = 0; 379 then = SDL_GetTicks(); 380 done = 0; 381 while (!done) { 382 bool update_swap_interval = false; 383 int active_windows = 0; 384 385 /* Check for events */ 386 ++frames; 387 while (SDL_PollEvent(&event)) { 388 SDLTest_CommonEvent(state, &event, &done); 389 if (event.type == SDL_EVENT_KEY_DOWN) { 390 if (event.key.key == SDLK_O) { 391 swap_interval--; 392 update_swap_interval = true; 393 } else if (event.key.key == SDLK_P) { 394 swap_interval++; 395 update_swap_interval = true; 396 } 397 } 398 } 399 400 if (update_swap_interval) { 401 SDL_Log("Swap interval to be set to %d", swap_interval); 402 } 403 404 for (i = 0; i < state->num_windows; ++i) { 405 int w, h; 406 if (state->windows[i] == NULL || 407 (suspend_when_occluded && (SDL_GetWindowFlags(state->windows[i]) & SDL_WINDOW_OCCLUDED))) { 408 continue; 409 } 410 ++active_windows; 411 SDL_GL_MakeCurrent(state->windows[i], context); 412 if (update_swap_interval) { 413 SDL_GL_SetSwapInterval(swap_interval); 414 LogSwapInterval(); 415 } 416 SDL_GetWindowSizeInPixels(state->windows[i], &w, &h); 417 ctx.glViewport(0, 0, w, h); 418 Render(); 419 SDL_GL_SwapWindow(state->windows[i]); 420 } 421 422 /* If all windows are occluded, throttle event polling to 15hz. */ 423 if (!active_windows) { 424 SDL_DelayNS(SDL_NS_PER_SECOND / 15); 425 } 426 } 427 428 /* Print out some timing information */ 429 now = SDL_GetTicks(); 430 if (now > then) { 431 SDL_Log("%2.2f frames per second", 432 ((double)frames * 1000) / (now - then)); 433 } 434 quit(0); 435 return 0; 436} 437 438#else /* HAVE_OPENGL */ 439 440int main(int argc, char *argv[]) 441{ 442 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No OpenGL support on this system"); 443 return 1; 444} 445 446#endif /* HAVE_OPENGL */ 447
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.