sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

testgl2.c (12691B)


      1 /*
      2   Copyright (C) 1997-2020 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 
     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", #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     int swap_interval = 0;
    222 
    223     /* Enable standard application logging */
    224     SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
    225 
    226     /* Initialize parameters */
    227     fsaa = 0;
    228     accel = -1;
    229 
    230     /* Initialize test framework */
    231     state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
    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 */
    259     state->window_flags |= SDL_WINDOW_OPENGL;
    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 
    291     if (state->render_flags & SDL_RENDERER_PRESENTVSYNC) {
    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 {
    296             SDL_GL_SetSwapInterval(1);
    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) {
    343         status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &value);
    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         }
    350         status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &value);
    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) {
    360         status = SDL_GL_GetAttribute(SDL_GL_ACCELERATED_VISUAL, &value);
    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 */