SDL  2.0
testgl2.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 #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 
222  /* Enable standard application logging */
224 
225  /* Initialize parameters */
226  fsaa = 0;
227  accel = -1;
228 
229  /* Initialize test framework */
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 */
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 
291  /* try late-swap-tearing first. If not supported, try normal vsync. */
292  if (SDL_GL_SetSwapInterval(-1) == -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) {
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  }
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) {
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 
409 int
410 main(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 */
#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
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.
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:175
#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 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:410
const char * SDLTest_CommonUsage(SDLTest_CommonState *state)
Returns common usage information.
#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:164
#define GL_MODELVIEW
Definition: SDL_opengl.h:271
#define GL_RENDERER
Definition: SDL_opengl.h:714
#define SDL_GL_MakeCurrent
GLuint color
General event structure.
Definition: SDL_events.h:525
#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:78
#define GL_QUADS
Definition: SDL_opengl.h:223
EGLContext ctx
Definition: eglext.h:208