SDL  2.0
testgl2.c
Go to the documentation of this file.
1 /*
2  Copyright (C) 1997-2019 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 
27 typedef 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 
39 static SDL_GLContext context;
40 static GL_Context ctx;
41 
42 static 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", #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. */
71 static void
72 quit(int rc)
73 {
74  if (context) {
75  /* SDL_GL_MakeCurrent(0, NULL); *//* doesn't do anything */
77  }
78  SDLTest_CommonQuit(state);
79  exit(rc);
80 }
81 
82 static void
83 Render()
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);
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 
210 int
211 main(int argc, char *argv[])
212 {
213  int fsaa, accel;
214  int value;
215  int i, done;
218  Uint32 then, now, frames;
219  int status;
220  int dw, dh;
221  int swap_interval = 0;
222 
223  /* Enable standard application logging */
225 
226  /* Initialize parameters */
227  fsaa = 0;
228  accel = -1;
229 
230  /* Initialize test framework */
232  if (!state) {
233  return 1;
234  }
235  for (i = 1; i < argc;) {
236  int consumed;
237 
238  consumed = SDLTest_CommonArg(state, i);
239  if (consumed == 0) {
240  if (SDL_strcasecmp(argv[i], "--fsaa") == 0 && i+1 < argc) {
241  fsaa = atoi(argv[i+1]);
242  consumed = 2;
243  } else if (SDL_strcasecmp(argv[i], "--accel") == 0 && i+1 < argc) {
244  accel = atoi(argv[i+1]);
245  consumed = 2;
246  } else {
247  consumed = -1;
248  }
249  }
250  if (consumed < 0) {
251  static const char *options[] = { "[--fsaa n]", "[--accel n]", NULL };
252  SDLTest_CommonLogUsage(state, argv[0], options);
253  quit(1);
254  }
255  i += consumed;
256  }
257 
258  /* Set OpenGL parameters */
260  state->gl_red_size = 5;
261  state->gl_green_size = 5;
262  state->gl_blue_size = 5;
263  state->gl_depth_size = 16;
264  state->gl_double_buffer = 1;
265  if (fsaa) {
266  state->gl_multisamplebuffers = 1;
267  state->gl_multisamplesamples = fsaa;
268  }
269  if (accel >= 0) {
270  state->gl_accelerated = accel;
271  }
272 
273  if (!SDLTest_CommonInit(state)) {
274  quit(2);
275  }
276 
277  /* Create OpenGL context */
278  context = SDL_GL_CreateContext(state->windows[0]);
279  if (!context) {
280  SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_GL_CreateContext(): %s\n", SDL_GetError());
281  quit(2);
282  }
283 
284  /* Important: call this *after* creating the context */
285  if (LoadContext(&ctx) < 0) {
286  SDL_Log("Could not load GL functions\n");
287  quit(2);
288  return 0;
289  }
290 
292  /* try late-swap-tearing first. If not supported, try normal vsync. */
293  if (SDL_GL_SetSwapInterval(-1) == 0) {
294  swap_interval = -1;
295  } else {
297  swap_interval = 1;
298  }
299  } else {
300  SDL_GL_SetSwapInterval(0); /* disable vsync. */
301  swap_interval = 0;
302  }
303 
304  SDL_GetCurrentDisplayMode(0, &mode);
305  SDL_Log("Screen BPP : %d\n", SDL_BITSPERPIXEL(mode.format));
306  SDL_Log("Swap Interval : %d\n", SDL_GL_GetSwapInterval());
307  SDL_GetWindowSize(state->windows[0], &dw, &dh);
308  SDL_Log("Window Size : %d,%d\n", dw, dh);
309  SDL_GL_GetDrawableSize(state->windows[0], &dw, &dh);
310  SDL_Log("Draw Size : %d,%d\n", dw, dh);
311  SDL_Log("\n");
312  SDL_Log("Vendor : %s\n", ctx.glGetString(GL_VENDOR));
313  SDL_Log("Renderer : %s\n", ctx.glGetString(GL_RENDERER));
314  SDL_Log("Version : %s\n", ctx.glGetString(GL_VERSION));
315  SDL_Log("Extensions : %s\n", ctx.glGetString(GL_EXTENSIONS));
316  SDL_Log("\n");
317 
318  status = SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value);
319  if (!status) {
320  SDL_Log("SDL_GL_RED_SIZE: requested %d, got %d\n", 5, value);
321  } else {
322  SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_RED_SIZE: %s\n", SDL_GetError());
323  }
324  status = SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &value);
325  if (!status) {
326  SDL_Log("SDL_GL_GREEN_SIZE: requested %d, got %d\n", 5, value);
327  } else {
328  SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_GREEN_SIZE: %s\n", SDL_GetError());
329  }
330  status = SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &value);
331  if (!status) {
332  SDL_Log("SDL_GL_BLUE_SIZE: requested %d, got %d\n", 5, value);
333  } else {
334  SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_BLUE_SIZE: %s\n", SDL_GetError());
335  }
336  status = SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &value);
337  if (!status) {
338  SDL_Log("SDL_GL_DEPTH_SIZE: requested %d, got %d\n", 16, value);
339  } else {
340  SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_DEPTH_SIZE: %s\n", SDL_GetError());
341  }
342  if (fsaa) {
344  if (!status) {
345  SDL_Log("SDL_GL_MULTISAMPLEBUFFERS: requested 1, got %d\n", value);
346  } else {
347  SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_MULTISAMPLEBUFFERS: %s\n",
348  SDL_GetError());
349  }
351  if (!status) {
352  SDL_Log("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d\n", fsaa,
353  value);
354  } else {
355  SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_MULTISAMPLESAMPLES: %s\n",
356  SDL_GetError());
357  }
358  }
359  if (accel >= 0) {
361  if (!status) {
362  SDL_Log("SDL_GL_ACCELERATED_VISUAL: requested %d, got %d\n", accel,
363  value);
364  } else {
365  SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_ACCELERATED_VISUAL: %s\n",
366  SDL_GetError());
367  }
368  }
369 
370  /* Set rendering settings */
371  ctx.glMatrixMode(GL_PROJECTION);
372  ctx.glLoadIdentity();
373  ctx.glOrtho(-2.0, 2.0, -2.0, 2.0, -20.0, 20.0);
374  ctx.glMatrixMode(GL_MODELVIEW);
375  ctx.glLoadIdentity();
376  ctx.glEnable(GL_DEPTH_TEST);
377  ctx.glDepthFunc(GL_LESS);
378  ctx.glShadeModel(GL_SMOOTH);
379 
380  /* Main render loop */
381  frames = 0;
382  then = SDL_GetTicks();
383  done = 0;
384  while (!done) {
385  SDL_bool update_swap_interval = SDL_FALSE;
386 
387  /* Check for events */
388  ++frames;
389  while (SDL_PollEvent(&event)) {
390  SDLTest_CommonEvent(state, &event, &done);
391  if (event.type == SDL_KEYDOWN) {
392  if (event.key.keysym.sym == SDLK_o) {
393  swap_interval--;
394  update_swap_interval = SDL_TRUE;
395  } else if (event.key.keysym.sym == SDLK_p) {
396  swap_interval++;
397  update_swap_interval = SDL_TRUE;
398  }
399  }
400  }
401 
402  if (update_swap_interval) {
403  SDL_Log("Swap interval to be set to %d\n", swap_interval);
404  }
405 
406  for (i = 0; i < state->num_windows; ++i) {
407  int w, h;
408  if (state->windows[i] == NULL)
409  continue;
410  SDL_GL_MakeCurrent(state->windows[i], context);
411  if (update_swap_interval) {
412  SDL_GL_SetSwapInterval(swap_interval);
413  }
414  SDL_GL_GetDrawableSize(state->windows[i], &w, &h);
415  ctx.glViewport(0, 0, w, h);
416  Render();
417  SDL_GL_SwapWindow(state->windows[i]);
418  }
419  }
420 
421  /* Print out some timing information */
422  now = SDL_GetTicks();
423  if (now > then) {
424  SDL_Log("%2.2f frames per second\n",
425  ((double) frames * 1000) / (now - then));
426  }
427  quit(0);
428  return 0;
429 }
430 
431 #else /* HAVE_OPENGL */
432 
433 int
434 main(int argc, char *argv[])
435 {
436  SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No OpenGL support on this system\n");
437  return 1;
438 }
439 
440 #endif /* HAVE_OPENGL */
#define SDL_PollEvent
#define SDL_GetError
#define SDL_GL_CreateContext
#define GL_VENDOR
Definition: SDL_opengl.h:713
#define GL_PROJECTION
Definition: SDL_opengl.h:272
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.
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
#define GL_EXTENSIONS
Definition: SDL_opengl.h:716
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
#define GL_VERSION
Definition: SDL_opengl.h:715
#define SDL_strcasecmp
SDL_bool SDLTest_CommonInit(SDLTest_CommonState *state)
Open test window.
SDL_Window ** windows
#define SDL_LogError
#define SDL_GetWindowSize
#define SDL_Log
#define SDL_GL_GetDrawableSize
void * SDL_GLContext
An opaque handle to an OpenGL context.
Definition: SDL_video.h:193
#define SDL_GL_GetSwapInterval
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 SDLTest_CommonLogUsage(SDLTest_CommonState *state, const char *argv0, const char **options)
Logs command line usage info.
void quit(int rc)
Definition: teststreaming.c:64
struct _cl_event * event
#define SDL_GL_SetSwapInterval
int done
Definition: checkkeys.c:28
GLenum mode
GLubyte GLubyte GLubyte GLubyte w
GLsizei const GLfloat * value
#define GL_LESS
Definition: SDL_opengl.h:320
int main(int argc, char *argv[])
Definition: testgl2.c:434
SDL_Keysym keysym
Definition: SDL_events.h:220
#define GL_COLOR_BUFFER_BIT
Definition: SDL_opengl.h:742
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_LogSetPriority
#define NULL
Definition: begin_code.h:167
SDL_bool
Definition: SDL_stdinc.h:161
#define GL_MODELVIEW
Definition: SDL_opengl.h:271
#define GL_RENDERER
Definition: SDL_opengl.h:714
#define SDL_GL_MakeCurrent
SDL_KeyboardEvent key
Definition: SDL_events.h:563
uint32_t Uint32
Definition: SDL_stdinc.h:203
GLuint color
SDL_Keycode sym
Definition: SDL_keyboard.h:50
static Uint32 frames
Definition: testsprite2.c:40
General event structure.
Definition: SDL_events.h:557
#define GL_DEPTH_TEST
Definition: SDL_opengl.h:327
#define SDL_GL_GetAttribute
#define GL_SMOOTH
Definition: SDL_opengl.h:365
Uint32 format
Definition: SDL_video.h:55
#define SDL_GL_DeleteContext
#define SDL_GetCurrentDisplayMode
#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:79
#define GL_QUADS
Definition: SDL_opengl.h:223
Uint32 type
Definition: SDL_events.h:559
EGLContext ctx
Definition: eglext.h:208