Atlas - testgles2.c

Home / ext / SDL2 / test Lines: 32 | Size: 20544 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Copyright (C) 1997-2018 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 <stdlib.h> 13#include <stdio.h> 14#include <string.h> 15#include <math.h> 16 17#ifdef __EMSCRIPTEN__ 18#include <emscripten/emscripten.h> 19#endif 20 21#include "SDL_test_common.h" 22 23#if defined(__IPHONEOS__) || defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__NACL__) \ 24 || defined(__WINDOWS__) || defined(__LINUX__) 25#define HAVE_OPENGLES2 26#endif 27 28#ifdef HAVE_OPENGLES2 29 30#include "SDL_opengles2.h" 31 32typedef struct GLES2_Context 33{ 34#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params; 35#include "../src/render/opengles2/SDL_gles2funcs.h" 36#undef SDL_PROC 37} GLES2_Context; 38 39 40static SDLTest_CommonState *state; 41static SDL_GLContext *context = NULL; 42static int depth = 16; 43static GLES2_Context ctx; 44 45static int LoadContext(GLES2_Context * data) 46{ 47#if SDL_VIDEO_DRIVER_UIKIT 48#define __SDL_NOGETPROCADDR__ 49#elif SDL_VIDEO_DRIVER_ANDROID 50#define __SDL_NOGETPROCADDR__ 51#elif SDL_VIDEO_DRIVER_PANDORA 52#define __SDL_NOGETPROCADDR__ 53#endif 54 55#if defined __SDL_NOGETPROCADDR__ 56#define SDL_PROC(ret,func,params) data->func=func; 57#else 58#define SDL_PROC(ret,func,params) \ 59 do { \ 60 data->func = SDL_GL_GetProcAddress(#func); \ 61 if ( ! data->func ) { \ 62 return SDL_SetError("Couldn't load GLES2 function %s: %s", #func, SDL_GetError()); \ 63 } \ 64 } while ( 0 ); 65#endif /* __SDL_NOGETPROCADDR__ */ 66 67#include "../src/render/opengles2/SDL_gles2funcs.h" 68#undef SDL_PROC 69 return 0; 70} 71 72/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ 73static void 74quit(int rc) 75{ 76 int i; 77 78 if (context != NULL) { 79 for (i = 0; i < state->num_windows; i++) { 80 if (context[i]) { 81 SDL_GL_DeleteContext(context[i]); 82 } 83 } 84 85 SDL_free(context); 86 } 87 88 SDLTest_CommonQuit(state); 89 exit(rc); 90} 91 92#define GL_CHECK(x) \ 93 x; \ 94 { \ 95 GLenum glError = ctx.glGetError(); \ 96 if(glError != GL_NO_ERROR) { \ 97 SDL_Log("glGetError() = %i (0x%.8x) at line %i\n", glError, glError, __LINE__); \ 98 quit(1); \ 99 } \ 100 } 101 102/* 103 * Simulates desktop's glRotatef. The matrix is returned in column-major 104 * order. 105 */ 106static void 107rotate_matrix(float angle, float x, float y, float z, float *r) 108{ 109 float radians, c, s, c1, u[3], length; 110 int i, j; 111 112 radians = (float)(angle * M_PI) / 180.0f; 113 114 c = SDL_cosf(radians); 115 s = SDL_sinf(radians); 116 117 c1 = 1.0f - SDL_cosf(radians); 118 119 length = (float)SDL_sqrt(x * x + y * y + z * z); 120 121 u[0] = x / length; 122 u[1] = y / length; 123 u[2] = z / length; 124 125 for (i = 0; i < 16; i++) { 126 r[i] = 0.0; 127 } 128 129 r[15] = 1.0; 130 131 for (i = 0; i < 3; i++) { 132 r[i * 4 + (i + 1) % 3] = u[(i + 2) % 3] * s; 133 r[i * 4 + (i + 2) % 3] = -u[(i + 1) % 3] * s; 134 } 135 136 for (i = 0; i < 3; i++) { 137 for (j = 0; j < 3; j++) { 138 r[i * 4 + j] += c1 * u[i] * u[j] + (i == j ? c : 0.0f); 139 } 140 } 141} 142 143/* 144 * Simulates gluPerspectiveMatrix 145 */ 146static void 147perspective_matrix(float fovy, float aspect, float znear, float zfar, float *r) 148{ 149 int i; 150 float f; 151 152 f = 1.0f/SDL_tanf(fovy * 0.5f); 153 154 for (i = 0; i < 16; i++) { 155 r[i] = 0.0; 156 } 157 158 r[0] = f / aspect; 159 r[5] = f; 160 r[10] = (znear + zfar) / (znear - zfar); 161 r[11] = -1.0f; 162 r[14] = (2.0f * znear * zfar) / (znear - zfar); 163 r[15] = 0.0f; 164} 165 166/* 167 * Multiplies lhs by rhs and writes out to r. All matrices are 4x4 and column 168 * major. In-place multiplication is supported. 169 */ 170static void 171multiply_matrix(float *lhs, float *rhs, float *r) 172{ 173 int i, j, k; 174 float tmp[16]; 175 176 for (i = 0; i < 4; i++) { 177 for (j = 0; j < 4; j++) { 178 tmp[j * 4 + i] = 0.0; 179 180 for (k = 0; k < 4; k++) { 181 tmp[j * 4 + i] += lhs[k * 4 + i] * rhs[j * 4 + k]; 182 } 183 } 184 } 185 186 for (i = 0; i < 16; i++) { 187 r[i] = tmp[i]; 188 } 189} 190 191/* 192 * Create shader, load in source, compile, dump debug as necessary. 193 * 194 * shader: Pointer to return created shader ID. 195 * source: Passed-in shader source code. 196 * shader_type: Passed to GL, e.g. GL_VERTEX_SHADER. 197 */ 198void 199process_shader(GLuint *shader, const char * source, GLint shader_type) 200{ 201 GLint status = GL_FALSE; 202 const char *shaders[1] = { NULL }; 203 char buffer[1024]; 204 GLsizei length; 205 206 /* Create shader and load into GL. */ 207 *shader = GL_CHECK(ctx.glCreateShader(shader_type)); 208 209 shaders[0] = source; 210 211 GL_CHECK(ctx.glShaderSource(*shader, 1, shaders, NULL)); 212 213 /* Clean up shader source. */ 214 shaders[0] = NULL; 215 216 /* Try compiling the shader. */ 217 GL_CHECK(ctx.glCompileShader(*shader)); 218 GL_CHECK(ctx.glGetShaderiv(*shader, GL_COMPILE_STATUS, &status)); 219 220 /* Dump debug info (source and log) if compilation failed. */ 221 if(status != GL_TRUE) { 222 ctx.glGetProgramInfoLog(*shader, sizeof(buffer), &length, &buffer[0]); 223 buffer[length] = '\0'; 224 SDL_Log("Shader compilation failed: %s", buffer);fflush(stderr); 225 quit(-1); 226 } 227} 228 229/* 3D data. Vertex range -0.5..0.5 in all axes. 230* Z -0.5 is near, 0.5 is far. */ 231const float _vertices[] = 232{ 233 /* Front face. */ 234 /* Bottom left */ 235 -0.5, 0.5, -0.5, 236 0.5, -0.5, -0.5, 237 -0.5, -0.5, -0.5, 238 /* Top right */ 239 -0.5, 0.5, -0.5, 240 0.5, 0.5, -0.5, 241 0.5, -0.5, -0.5, 242 /* Left face */ 243 /* Bottom left */ 244 -0.5, 0.5, 0.5, 245 -0.5, -0.5, -0.5, 246 -0.5, -0.5, 0.5, 247 /* Top right */ 248 -0.5, 0.5, 0.5, 249 -0.5, 0.5, -0.5, 250 -0.5, -0.5, -0.5, 251 /* Top face */ 252 /* Bottom left */ 253 -0.5, 0.5, 0.5, 254 0.5, 0.5, -0.5, 255 -0.5, 0.5, -0.5, 256 /* Top right */ 257 -0.5, 0.5, 0.5, 258 0.5, 0.5, 0.5, 259 0.5, 0.5, -0.5, 260 /* Right face */ 261 /* Bottom left */ 262 0.5, 0.5, -0.5, 263 0.5, -0.5, 0.5, 264 0.5, -0.5, -0.5, 265 /* Top right */ 266 0.5, 0.5, -0.5, 267 0.5, 0.5, 0.5, 268 0.5, -0.5, 0.5, 269 /* Back face */ 270 /* Bottom left */ 271 0.5, 0.5, 0.5, 272 -0.5, -0.5, 0.5, 273 0.5, -0.5, 0.5, 274 /* Top right */ 275 0.5, 0.5, 0.5, 276 -0.5, 0.5, 0.5, 277 -0.5, -0.5, 0.5, 278 /* Bottom face */ 279 /* Bottom left */ 280 -0.5, -0.5, -0.5, 281 0.5, -0.5, 0.5, 282 -0.5, -0.5, 0.5, 283 /* Top right */ 284 -0.5, -0.5, -0.5, 285 0.5, -0.5, -0.5, 286 0.5, -0.5, 0.5, 287}; 288 289const float _colors[] = 290{ 291 /* Front face */ 292 /* Bottom left */ 293 1.0, 0.0, 0.0, /* red */ 294 0.0, 0.0, 1.0, /* blue */ 295 0.0, 1.0, 0.0, /* green */ 296 /* Top right */ 297 1.0, 0.0, 0.0, /* red */ 298 1.0, 1.0, 0.0, /* yellow */ 299 0.0, 0.0, 1.0, /* blue */ 300 /* Left face */ 301 /* Bottom left */ 302 1.0, 1.0, 1.0, /* white */ 303 0.0, 1.0, 0.0, /* green */ 304 0.0, 1.0, 1.0, /* cyan */ 305 /* Top right */ 306 1.0, 1.0, 1.0, /* white */ 307 1.0, 0.0, 0.0, /* red */ 308 0.0, 1.0, 0.0, /* green */ 309 /* Top face */ 310 /* Bottom left */ 311 1.0, 1.0, 1.0, /* white */ 312 1.0, 1.0, 0.0, /* yellow */ 313 1.0, 0.0, 0.0, /* red */ 314 /* Top right */ 315 1.0, 1.0, 1.0, /* white */ 316 0.0, 0.0, 0.0, /* black */ 317 1.0, 1.0, 0.0, /* yellow */ 318 /* Right face */ 319 /* Bottom left */ 320 1.0, 1.0, 0.0, /* yellow */ 321 1.0, 0.0, 1.0, /* magenta */ 322 0.0, 0.0, 1.0, /* blue */ 323 /* Top right */ 324 1.0, 1.0, 0.0, /* yellow */ 325 0.0, 0.0, 0.0, /* black */ 326 1.0, 0.0, 1.0, /* magenta */ 327 /* Back face */ 328 /* Bottom left */ 329 0.0, 0.0, 0.0, /* black */ 330 0.0, 1.0, 1.0, /* cyan */ 331 1.0, 0.0, 1.0, /* magenta */ 332 /* Top right */ 333 0.0, 0.0, 0.0, /* black */ 334 1.0, 1.0, 1.0, /* white */ 335 0.0, 1.0, 1.0, /* cyan */ 336 /* Bottom face */ 337 /* Bottom left */ 338 0.0, 1.0, 0.0, /* green */ 339 1.0, 0.0, 1.0, /* magenta */ 340 0.0, 1.0, 1.0, /* cyan */ 341 /* Top right */ 342 0.0, 1.0, 0.0, /* green */ 343 0.0, 0.0, 1.0, /* blue */ 344 1.0, 0.0, 1.0, /* magenta */ 345}; 346 347const char* _shader_vert_src = 348" attribute vec4 av4position; " 349" attribute vec3 av3color; " 350" uniform mat4 mvp; " 351" varying vec3 vv3color; " 352" void main() { " 353" vv3color = av3color; " 354" gl_Position = mvp * av4position; " 355" } "; 356 357const char* _shader_frag_src = 358" precision lowp float; " 359" varying vec3 vv3color; " 360" void main() { " 361" gl_FragColor = vec4(vv3color, 1.0); " 362" } "; 363 364typedef struct shader_data 365{ 366 GLuint shader_program, shader_frag, shader_vert; 367 368 GLint attr_position; 369 GLint attr_color, attr_mvp; 370 371 int angle_x, angle_y, angle_z; 372 373} shader_data; 374 375static void 376Render(unsigned int width, unsigned int height, shader_data* data) 377{ 378 float matrix_rotate[16], matrix_modelview[16], matrix_perspective[16], matrix_mvp[16]; 379 380 /* 381 * Do some rotation with Euler angles. It is not a fixed axis as 382 * quaterions would be, but the effect is cool. 383 */ 384 rotate_matrix((float)data->angle_x, 1.0f, 0.0f, 0.0f, matrix_modelview); 385 rotate_matrix((float)data->angle_y, 0.0f, 1.0f, 0.0f, matrix_rotate); 386 387 multiply_matrix(matrix_rotate, matrix_modelview, matrix_modelview); 388 389 rotate_matrix((float)data->angle_z, 0.0f, 1.0f, 0.0f, matrix_rotate); 390 391 multiply_matrix(matrix_rotate, matrix_modelview, matrix_modelview); 392 393 /* Pull the camera back from the cube */ 394 matrix_modelview[14] -= 2.5; 395 396 perspective_matrix(45.0f, (float)width/height, 0.01f, 100.0f, matrix_perspective); 397 multiply_matrix(matrix_perspective, matrix_modelview, matrix_mvp); 398 399 GL_CHECK(ctx.glUniformMatrix4fv(data->attr_mvp, 1, GL_FALSE, matrix_mvp)); 400 401 data->angle_x += 3; 402 data->angle_y += 2; 403 data->angle_z += 1; 404 405 if(data->angle_x >= 360) data->angle_x -= 360; 406 if(data->angle_x < 0) data->angle_x += 360; 407 if(data->angle_y >= 360) data->angle_y -= 360; 408 if(data->angle_y < 0) data->angle_y += 360; 409 if(data->angle_z >= 360) data->angle_z -= 360; 410 if(data->angle_z < 0) data->angle_z += 360; 411 412 GL_CHECK(ctx.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)); 413 GL_CHECK(ctx.glDrawArrays(GL_TRIANGLES, 0, 36)); 414} 415 416int done; 417Uint32 frames; 418shader_data *datas; 419 420void loop() 421{ 422 SDL_Event event; 423 int i; 424 int status; 425 426 /* Check for events */ 427 ++frames; 428 while (SDL_PollEvent(&event) && !done) { 429 switch (event.type) { 430 case SDL_WINDOWEVENT: 431 switch (event.window.event) { 432 case SDL_WINDOWEVENT_RESIZED: 433 for (i = 0; i < state->num_windows; ++i) { 434 if (event.window.windowID == SDL_GetWindowID(state->windows[i])) { 435 int w, h; 436 status = SDL_GL_MakeCurrent(state->windows[i], context[i]); 437 if (status) { 438 SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError()); 439 break; 440 } 441 /* Change view port to the new window dimensions */ 442 SDL_GL_GetDrawableSize(state->windows[i], &w, &h); 443 ctx.glViewport(0, 0, w, h); 444 state->window_w = event.window.data1; 445 state->window_h = event.window.data2; 446 /* Update window content */ 447 Render(event.window.data1, event.window.data2, &datas[i]); 448 SDL_GL_SwapWindow(state->windows[i]); 449 break; 450 } 451 } 452 break; 453 } 454 } 455 SDLTest_CommonEvent(state, &event, &done); 456 } 457 if (!done) { 458 for (i = 0; i < state->num_windows; ++i) { 459 status = SDL_GL_MakeCurrent(state->windows[i], context[i]); 460 if (status) { 461 SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError()); 462 463 /* Continue for next window */ 464 continue; 465 } 466 Render(state->window_w, state->window_h, &datas[i]); 467 SDL_GL_SwapWindow(state->windows[i]); 468 } 469 } 470#ifdef __EMSCRIPTEN__ 471 else { 472 emscripten_cancel_main_loop(); 473 } 474#endif 475} 476 477int 478main(int argc, char *argv[]) 479{ 480 int fsaa, accel; 481 int value; 482 int i; 483 SDL_DisplayMode mode; 484 Uint32 then, now; 485 int status; 486 shader_data *data; 487 488 /* Initialize parameters */ 489 fsaa = 0; 490 accel = 0; 491 492 /* Initialize test framework */ 493 state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); 494 if (!state) { 495 return 1; 496 } 497 for (i = 1; i < argc;) { 498 int consumed; 499 500 consumed = SDLTest_CommonArg(state, i); 501 if (consumed == 0) { 502 if (SDL_strcasecmp(argv[i], "--fsaa") == 0) { 503 ++fsaa; 504 consumed = 1; 505 } else if (SDL_strcasecmp(argv[i], "--accel") == 0) { 506 ++accel; 507 consumed = 1; 508 } else if (SDL_strcasecmp(argv[i], "--zdepth") == 0) { 509 i++; 510 if (!argv[i]) { 511 consumed = -1; 512 } else { 513 depth = SDL_atoi(argv[i]); 514 consumed = 1; 515 } 516 } else { 517 consumed = -1; 518 } 519 } 520 if (consumed < 0) { 521 SDL_Log ("Usage: %s %s [--fsaa] [--accel] [--zdepth %%d]\n", argv[0], 522 SDLTest_CommonUsage(state)); 523 quit(1); 524 } 525 i += consumed; 526 } 527 528 /* Set OpenGL parameters */ 529 state->window_flags |= SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS; 530 state->gl_red_size = 5; 531 state->gl_green_size = 5; 532 state->gl_blue_size = 5; 533 state->gl_depth_size = depth; 534 state->gl_major_version = 2; 535 state->gl_minor_version = 0; 536 state->gl_profile_mask = SDL_GL_CONTEXT_PROFILE_ES; 537 538 if (fsaa) { 539 state->gl_multisamplebuffers=1; 540 state->gl_multisamplesamples=fsaa; 541 } 542 if (accel) { 543 state->gl_accelerated=1; 544 } 545 if (!SDLTest_CommonInit(state)) { 546 quit(2); 547 return 0; 548 } 549 550 context = (SDL_GLContext *)SDL_calloc(state->num_windows, sizeof(context)); 551 if (context == NULL) { 552 SDL_Log("Out of memory!\n"); 553 quit(2); 554 } 555 556 /* Create OpenGL ES contexts */ 557 for (i = 0; i < state->num_windows; i++) { 558 context[i] = SDL_GL_CreateContext(state->windows[i]); 559 if (!context[i]) { 560 SDL_Log("SDL_GL_CreateContext(): %s\n", SDL_GetError()); 561 quit(2); 562 } 563 } 564 565 /* Important: call this *after* creating the context */ 566 if (LoadContext(&ctx) < 0) { 567 SDL_Log("Could not load GLES2 functions\n"); 568 quit(2); 569 return 0; 570 } 571 572 573 574 if (state->render_flags & SDL_RENDERER_PRESENTVSYNC) { 575 SDL_GL_SetSwapInterval(1); 576 } else { 577 SDL_GL_SetSwapInterval(0); 578 } 579 580 SDL_GetCurrentDisplayMode(0, &mode); 581 SDL_Log("Screen bpp: %d\n", SDL_BITSPERPIXEL(mode.format)); 582 SDL_Log("\n"); 583 SDL_Log("Vendor : %s\n", ctx.glGetString(GL_VENDOR)); 584 SDL_Log("Renderer : %s\n", ctx.glGetString(GL_RENDERER)); 585 SDL_Log("Version : %s\n", ctx.glGetString(GL_VERSION)); 586 SDL_Log("Extensions : %s\n", ctx.glGetString(GL_EXTENSIONS)); 587 SDL_Log("\n"); 588 589 status = SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value); 590 if (!status) { 591 SDL_Log("SDL_GL_RED_SIZE: requested %d, got %d\n", 5, value); 592 } else { 593 SDL_Log( "Failed to get SDL_GL_RED_SIZE: %s\n", 594 SDL_GetError()); 595 } 596 status = SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &value); 597 if (!status) { 598 SDL_Log("SDL_GL_GREEN_SIZE: requested %d, got %d\n", 5, value); 599 } else { 600 SDL_Log( "Failed to get SDL_GL_GREEN_SIZE: %s\n", 601 SDL_GetError()); 602 } 603 status = SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &value); 604 if (!status) { 605 SDL_Log("SDL_GL_BLUE_SIZE: requested %d, got %d\n", 5, value); 606 } else { 607 SDL_Log( "Failed to get SDL_GL_BLUE_SIZE: %s\n", 608 SDL_GetError()); 609 } 610 status = SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &value); 611 if (!status) { 612 SDL_Log("SDL_GL_DEPTH_SIZE: requested %d, got %d\n", depth, value); 613 } else { 614 SDL_Log( "Failed to get SDL_GL_DEPTH_SIZE: %s\n", 615 SDL_GetError()); 616 } 617 if (fsaa) { 618 status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &value); 619 if (!status) { 620 SDL_Log("SDL_GL_MULTISAMPLEBUFFERS: requested 1, got %d\n", value); 621 } else { 622 SDL_Log( "Failed to get SDL_GL_MULTISAMPLEBUFFERS: %s\n", 623 SDL_GetError()); 624 } 625 status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &value); 626 if (!status) { 627 SDL_Log("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d\n", fsaa, 628 value); 629 } else { 630 SDL_Log( "Failed to get SDL_GL_MULTISAMPLESAMPLES: %s\n", 631 SDL_GetError()); 632 } 633 } 634 if (accel) { 635 status = SDL_GL_GetAttribute(SDL_GL_ACCELERATED_VISUAL, &value); 636 if (!status) { 637 SDL_Log("SDL_GL_ACCELERATED_VISUAL: requested 1, got %d\n", value); 638 } else { 639 SDL_Log( "Failed to get SDL_GL_ACCELERATED_VISUAL: %s\n", 640 SDL_GetError()); 641 } 642 } 643 644 datas = (shader_data *)SDL_calloc(state->num_windows, sizeof(shader_data)); 645 646 /* Set rendering settings for each context */ 647 for (i = 0; i < state->num_windows; ++i) { 648 649 int w, h; 650 status = SDL_GL_MakeCurrent(state->windows[i], context[i]); 651 if (status) { 652 SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError()); 653 654 /* Continue for next window */ 655 continue; 656 } 657 SDL_GL_GetDrawableSize(state->windows[i], &w, &h); 658 ctx.glViewport(0, 0, w, h); 659 660 data = &datas[i]; 661 data->angle_x = 0; data->angle_y = 0; data->angle_z = 0; 662 663 /* Shader Initialization */ 664 process_shader(&data->shader_vert, _shader_vert_src, GL_VERTEX_SHADER); 665 process_shader(&data->shader_frag, _shader_frag_src, GL_FRAGMENT_SHADER); 666 667 /* Create shader_program (ready to attach shaders) */ 668 data->shader_program = GL_CHECK(ctx.glCreateProgram()); 669 670 /* Attach shaders and link shader_program */ 671 GL_CHECK(ctx.glAttachShader(data->shader_program, data->shader_vert)); 672 GL_CHECK(ctx.glAttachShader(data->shader_program, data->shader_frag)); 673 GL_CHECK(ctx.glLinkProgram(data->shader_program)); 674 675 /* Get attribute locations of non-fixed attributes like color and texture coordinates. */ 676 data->attr_position = GL_CHECK(ctx.glGetAttribLocation(data->shader_program, "av4position")); 677 data->attr_color = GL_CHECK(ctx.glGetAttribLocation(data->shader_program, "av3color")); 678 679 /* Get uniform locations */ 680 data->attr_mvp = GL_CHECK(ctx.glGetUniformLocation(data->shader_program, "mvp")); 681 682 GL_CHECK(ctx.glUseProgram(data->shader_program)); 683 684 /* Enable attributes for position, color and texture coordinates etc. */ 685 GL_CHECK(ctx.glEnableVertexAttribArray(data->attr_position)); 686 GL_CHECK(ctx.glEnableVertexAttribArray(data->attr_color)); 687 688 /* Populate attributes for position, color and texture coordinates etc. */ 689 GL_CHECK(ctx.glVertexAttribPointer(data->attr_position, 3, GL_FLOAT, GL_FALSE, 0, _vertices)); 690 GL_CHECK(ctx.glVertexAttribPointer(data->attr_color, 3, GL_FLOAT, GL_FALSE, 0, _colors)); 691 692 GL_CHECK(ctx.glEnable(GL_CULL_FACE)); 693 GL_CHECK(ctx.glEnable(GL_DEPTH_TEST)); 694 } 695 696 /* Main render loop */ 697 frames = 0; 698 then = SDL_GetTicks(); 699 done = 0; 700 701#ifdef __EMSCRIPTEN__ 702 emscripten_set_main_loop(loop, 0, 1); 703#else 704 while (!done) { 705 loop(); 706 } 707#endif 708 709 /* Print out some timing information */ 710 now = SDL_GetTicks(); 711 if (now > then) { 712 SDL_Log("%2.2f frames per second\n", 713 ((double) frames * 1000) / (now - then)); 714 } 715#if !defined(__ANDROID__) && !defined(__NACL__) 716 quit(0); 717#endif 718 return 0; 719} 720 721#else /* HAVE_OPENGLES2 */ 722 723int 724main(int argc, char *argv[]) 725{ 726 SDL_Log("No OpenGL ES support on this system\n"); 727 return 1; 728} 729 730#endif /* HAVE_OPENGLES2 */ 731 732/* vi: set ts=4 sw=4 expandtab: */ 733
[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.