Home | History | Annotate | Download | only in test
      1 /*
      2   Copyright (C) 1997-2014 Sam Lantinga <slouken (at) 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 
     38 static SDLTest_CommonState *state;
     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\n", #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 */
     76         SDL_GL_DeleteContext(context);
     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);
    108     ctx.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    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;
    216     SDL_DisplayMode mode;
    217     SDL_Event event;
    218     Uint32 then, now, frames;
    219     int status;
    220     int dw, dh;
    221 
    222     /* Enable standard application logging */
    223     SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
    224 
    225     /* Initialize parameters */
    226     fsaa = 0;
    227     accel = -1;
    228 
    229     /* Initialize test framework */
    230     state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
    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 */
    258     state->window_flags |= SDL_WINDOW_OPENGL;
    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 
    290     if (state->render_flags & SDL_RENDERER_PRESENTVSYNC) {
    291         /* try late-swap-tearing first. If not supported, try normal vsync. */
    292         if (SDL_GL_SetSwapInterval(-1) == -1) {
    293             SDL_GL_SetSwapInterval(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) {
    338         status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &value);
    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         }
    345         status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &value);
    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) {
    355         status = SDL_GL_GetAttribute(SDL_GL_ACCELERATED_VISUAL, &value);
    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 */
    417