SDL  2.0
testgles2.c
Go to the documentation of this file.
1 /*
2  Copyright (C) 1997-2018 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 #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 
32 typedef 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 
41 static SDL_GLContext *context = NULL;
42 static int depth = 16;
43 static GLES2_Context ctx;
44 
45 static 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. */
73 static void
74 quit(int rc)
75 {
76  int i;
77 
78  if (context != NULL) {
79  for (i = 0; i < state->num_windows; i++) {
80  if (context[i]) {
82  }
83  }
84 
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  */
106 static void
107 rotate_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  */
146 static void
147 perspective_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  */
170 static void
171 multiply_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  */
198 void
199 process_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. */
231 const 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 
289 const 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 
347 const 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 
357 const char* _shader_frag_src =
358 " precision lowp float; "
359 " varying vec3 vv3color; "
360 " void main() { "
361 " gl_FragColor = vec4(vv3color, 1.0); "
362 " } ";
363 
364 typedef 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 
375 static void
376 Render(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 
413  GL_CHECK(ctx.glDrawArrays(GL_TRIANGLES, 0, 36));
414 }
415 
416 int done;
417 Uint32 frames;
418 shader_data *datas;
419 
420 void loop()
421 {
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) {
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 
477 int
478 main(int argc, char *argv[])
479 {
480  int fsaa, accel;
481  int value;
482  int i;
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 */
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 */
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;
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 
576  } else {
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) {
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  }
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) {
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 
723 int
724 main(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: */
void loop()
Definition: checkkeys.c:152
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
#define GL_FALSE
Definition: SDL_opengl.h:199
#define SDL_PollEvent
#define GL_VERTEX_SHADER
#define SDL_GetError
GLdouble GLdouble z
#define SDL_sinf
GLdouble s
Definition: SDL_opengl.h:2063
#define SDL_GL_CreateContext
#define GL_VENDOR
Definition: SDL_opengl.h:713
#define SDL_GetWindowID
#define GL_STENCIL_BUFFER_BIT
Definition: SDL_opengl.h:738
#define GL_TRUE
Definition: SDL_opengl.h:200
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
#define GL_COMPILE_STATUS
SDLTest_CommonState * SDLTest_CommonCreateState(char **argv, Uint32 flags)
Parse command line parameters and create common state.
GLfloat GLfloat GLfloat GLfloat h
struct xkb_state * state
int SDLTest_CommonArg(SDLTest_CommonState *state, int index)
Process one common argument.
int GLint
Definition: SDL_opengl.h:182
static screen_context_t context
Definition: video.c:25
The structure that defines a display mode.
Definition: SDL_video.h:53
#define GL_DEPTH_BUFFER_BIT
Definition: SDL_opengl.h:736
GLfloat f
#define GL_EXTENSIONS
Definition: SDL_opengl.h:716
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
GLsizei GLsizei GLuint * shaders
uint32_t Uint32
Definition: SDL_stdinc.h:181
#define GL_VERSION
Definition: SDL_opengl.h:715
#define SDL_strcasecmp
SDL_bool SDLTest_CommonInit(SDLTest_CommonState *state)
Open test window.
GLint GLint GLsizei width
Definition: SDL_opengl.h:1572
SDL_Window ** windows
SDL_WindowEvent window
Definition: SDL_events.h:529
#define SDL_Log
#define SDL_GL_GetDrawableSize
void * SDL_GLContext
An opaque handle to an OpenGL context.
Definition: SDL_video.h:175
void SDLTest_CommonEvent(SDLTest_CommonState *state, SDL_Event *event, int *done)
Common event handler for test windows.
Uint32 SDL_GetTicks(void)
Get the number of milliseconds since the SDL library initialization.
void quit(int rc)
Definition: teststreaming.c:64
#define SDL_free
struct _cl_event * event
#define SDL_GL_SetSwapInterval
int done
Definition: checkkeys.c:28
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int in j)
Definition: SDL_x11sym.h:50
#define GL_FRAGMENT_SHADER
#define GL_FLOAT
Definition: SDL_opengl.h:209
const GLubyte * c
GLenum mode
GLubyte GLubyte GLubyte GLubyte w
GLsizei const GLfloat * value
GLsizei GLsizei GLchar * source
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
const char * SDLTest_CommonUsage(SDLTest_CommonState *state)
Returns common usage information.
#define GL_COLOR_BUFFER_BIT
Definition: SDL_opengl.h:742
int main(int argc, char *argv[])
Definition: testgles2.c:724
#define SDL_atoi
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
#define SDL_cosf
#define NULL
Definition: begin_code.h:164
GLuint buffer
#define GL_CULL_FACE
Definition: SDL_opengl.h:302
GLint GLint GLsizei GLsizei GLsizei depth
Definition: SDL_opengl.h:1572
unsigned int GLuint
Definition: SDL_opengl.h:185
#define GL_RENDERER
Definition: SDL_opengl.h:714
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1572
#define SDL_calloc
#define SDL_GL_MakeCurrent
#define SDL_sqrt
GLfloat angle
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int int return Display Window Cursor return Display Window return Display Drawable GC int int unsigned int unsigned int return Display Drawable GC int int _Xconst char int return Display Drawable GC int int unsigned int unsigned int return Display return Display Cursor return Display GC return XModifierKeymap return char Display Window int return Display return Display Atom return Display Window XWindowAttributes return Display Window return Display XEvent Bool(*) XPointer return Display Window Bool unsigned int int int Window Cursor Time return Display Window int return KeySym return Display _Xconst char Bool return Display _Xconst char return XKeyEvent char int KeySym XComposeStatus return Display int int int XVisualInfo return Display Window int int return _Xconst char return Display XEvent return Display Drawable GC XImage int int int int unsigned int unsigned int return Display Window Window Window int int int int unsigned int return Display Window Window int int return Display Window unsigned int unsigned int return Display Window Bool long XEvent return Display GC unsigned long return Display Window int Time return Display Window Window return Display Window unsigned long return Display Window XSizeHints Display Colormap XColor int return char int XTextProperty return XFontStruct _Xconst char int int int int XCharStruct return Display Window return Display Time return Display Colormap return Display Window Window int int unsigned int unsigned int int int return Display Window int return XExtensionInfo Display char XExtensionHooks int XPointer return XExtensionInfo XExtensionInfo Display return Display return Display unsigned long Display GC Display char long Display xReply int Bool return Display Bool return Display int SDL_X11_XESetEventToWireRetType return Display Window Window Window Window unsigned int return Display XShmSegmentInfo return Display Drawable GC XImage int int int int unsigned int unsigned int Boo k)
Definition: SDL_x11sym.h:213
General event structure.
Definition: SDL_events.h:525
#define GL_DEPTH_TEST
Definition: SDL_opengl.h:327
#define SDL_GL_GetAttribute
int GLsizei
Definition: SDL_opengl.h:186
Uint32 format
Definition: SDL_video.h:55
#define SDL_GL_DeleteContext
GLuint GLsizei GLsizei * length
#define SDL_tanf
#define SDL_GetCurrentDisplayMode
#define GL_TRIANGLES
Definition: SDL_opengl.h:220
#define SDL_BITSPERPIXEL(X)
Definition: SDL_pixels.h:127
#define SDL_GL_SwapWindow
void SDLTest_CommonQuit(SDLTest_CommonState *state)
Close test window.
#define SDL_INIT_VIDEO
Definition: SDL.h:78
GLuint shader
Uint32 type
Definition: SDL_events.h:527
EGLContext ctx
Definition: eglext.h:208