test/testintersections.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 07 Dec 2017 16:08:09 -0800
changeset 11730 ac6c607e065c
parent 10737 3406a0f8b041
child 11811 5d94cb6b24d3
permissions -rw-r--r--
Enable building the Metal renderer by default, and weak link the Metal framework so the SDL library is safe to use on older Macs
Also generate iOS versions of the Metal shaders
     1 /*
     2   Copyright (C) 1997-2017 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 
    13 /* Simple program:  draw as many random objects on the screen as possible */
    14 
    15 #include <stdlib.h>
    16 #include <stdio.h>
    17 #include <time.h>
    18 
    19 #ifdef __EMSCRIPTEN__
    20 #include <emscripten/emscripten.h>
    21 #endif
    22 
    23 #include "SDL_test_common.h"
    24 
    25 #define SWAP(typ,a,b) do{typ t=a;a=b;b=t;}while(0)
    26 #define NUM_OBJECTS 100
    27 
    28 static SDLTest_CommonState *state;
    29 static int num_objects;
    30 static SDL_bool cycle_color;
    31 static SDL_bool cycle_alpha;
    32 static int cycle_direction = 1;
    33 static int current_alpha = 255;
    34 static int current_color = 255;
    35 static SDL_BlendMode blendMode = SDL_BLENDMODE_NONE;
    36 
    37 int mouse_begin_x = -1, mouse_begin_y = -1;
    38 int done;
    39 
    40 void
    41 DrawPoints(SDL_Renderer * renderer)
    42 {
    43     int i;
    44     int x, y;
    45     SDL_Rect viewport;
    46 
    47     /* Query the sizes */
    48     SDL_RenderGetViewport(renderer, &viewport);
    49 
    50     for (i = 0; i < num_objects * 4; ++i) {
    51         /* Cycle the color and alpha, if desired */
    52         if (cycle_color) {
    53             current_color += cycle_direction;
    54             if (current_color < 0) {
    55                 current_color = 0;
    56                 cycle_direction = -cycle_direction;
    57             }
    58             if (current_color > 255) {
    59                 current_color = 255;
    60                 cycle_direction = -cycle_direction;
    61             }
    62         }
    63         if (cycle_alpha) {
    64             current_alpha += cycle_direction;
    65             if (current_alpha < 0) {
    66                 current_alpha = 0;
    67                 cycle_direction = -cycle_direction;
    68             }
    69             if (current_alpha > 255) {
    70                 current_alpha = 255;
    71                 cycle_direction = -cycle_direction;
    72             }
    73         }
    74         SDL_SetRenderDrawColor(renderer, 255, (Uint8) current_color,
    75                                (Uint8) current_color, (Uint8) current_alpha);
    76 
    77         x = rand() % viewport.w;
    78         y = rand() % viewport.h;
    79         SDL_RenderDrawPoint(renderer, x, y);
    80     }
    81 }
    82 
    83 #define MAX_LINES 16
    84 int num_lines = 0;
    85 SDL_Rect lines[MAX_LINES];
    86 static int
    87 add_line(int x1, int y1, int x2, int y2)
    88 {
    89     if (num_lines >= MAX_LINES)
    90         return 0;
    91     if ((x1 == x2) && (y1 == y2))
    92         return 0;
    93 
    94     SDL_Log("adding line (%d, %d), (%d, %d)\n", x1, y1, x2, y2);
    95     lines[num_lines].x = x1;
    96     lines[num_lines].y = y1;
    97     lines[num_lines].w = x2;
    98     lines[num_lines].h = y2;
    99 
   100     return ++num_lines;
   101 }
   102 
   103 
   104 void
   105 DrawLines(SDL_Renderer * renderer)
   106 {
   107     int i;
   108     SDL_Rect viewport;
   109 
   110     /* Query the sizes */
   111     SDL_RenderGetViewport(renderer, &viewport);
   112 
   113     SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
   114 
   115     for (i = 0; i < num_lines; ++i) {
   116         if (i == -1) {
   117             SDL_RenderDrawLine(renderer, 0, 0, viewport.w - 1, viewport.h - 1);
   118             SDL_RenderDrawLine(renderer, 0, viewport.h - 1, viewport.w - 1, 0);
   119             SDL_RenderDrawLine(renderer, 0, viewport.h / 2, viewport.w - 1, viewport.h / 2);
   120             SDL_RenderDrawLine(renderer, viewport.w / 2, 0, viewport.w / 2, viewport.h - 1);
   121         } else {
   122             SDL_RenderDrawLine(renderer, lines[i].x, lines[i].y, lines[i].w, lines[i].h);
   123         }
   124     }
   125 }
   126 
   127 #define MAX_RECTS 16
   128 int num_rects = 0;
   129 SDL_Rect rects[MAX_RECTS];
   130 static int
   131 add_rect(int x1, int y1, int x2, int y2)
   132 {
   133     if (num_rects >= MAX_RECTS)
   134         return 0;
   135     if ((x1 == x2) || (y1 == y2))
   136         return 0;
   137 
   138     if (x1 > x2)
   139         SWAP(int, x1, x2);
   140     if (y1 > y2)
   141         SWAP(int, y1, y2);
   142 
   143     SDL_Log("adding rect (%d, %d), (%d, %d) [%dx%d]\n", x1, y1, x2, y2,
   144            x2 - x1, y2 - y1);
   145 
   146     rects[num_rects].x = x1;
   147     rects[num_rects].y = y1;
   148     rects[num_rects].w = x2 - x1;
   149     rects[num_rects].h = y2 - y1;
   150 
   151     return ++num_rects;
   152 }
   153 
   154 static void
   155 DrawRects(SDL_Renderer * renderer)
   156 {
   157     SDL_SetRenderDrawColor(renderer, 255, 127, 0, 255);
   158     SDL_RenderFillRects(renderer, rects, num_rects);
   159 }
   160 
   161 static void
   162 DrawRectLineIntersections(SDL_Renderer * renderer)
   163 {
   164     int i, j;
   165 
   166     SDL_SetRenderDrawColor(renderer, 0, 255, 55, 255);
   167 
   168     for (i = 0; i < num_rects; i++)
   169         for (j = 0; j < num_lines; j++) {
   170             int x1, y1, x2, y2;
   171             SDL_Rect r;
   172 
   173             r = rects[i];
   174             x1 = lines[j].x;
   175             y1 = lines[j].y;
   176             x2 = lines[j].w;
   177             y2 = lines[j].h;
   178 
   179             if (SDL_IntersectRectAndLine(&r, &x1, &y1, &x2, &y2)) {
   180                 SDL_RenderDrawLine(renderer, x1, y1, x2, y2);
   181             }
   182         }
   183 }
   184 
   185 static void
   186 DrawRectRectIntersections(SDL_Renderer * renderer)
   187 {
   188     int i, j;
   189 
   190     SDL_SetRenderDrawColor(renderer, 255, 200, 0, 255);
   191 
   192     for (i = 0; i < num_rects; i++)
   193         for (j = i + 1; j < num_rects; j++) {
   194             SDL_Rect r;
   195             if (SDL_IntersectRect(&rects[i], &rects[j], &r)) {
   196                 SDL_RenderFillRect(renderer, &r);
   197             }
   198         }
   199 }
   200 
   201 void
   202 loop()
   203 {
   204     int i;
   205     SDL_Event event;
   206 
   207     /* Check for events */
   208     while (SDL_PollEvent(&event)) {
   209         SDLTest_CommonEvent(state, &event, &done);
   210         switch (event.type) {
   211         case SDL_MOUSEBUTTONDOWN:
   212             mouse_begin_x = event.button.x;
   213             mouse_begin_y = event.button.y;
   214             break;
   215         case SDL_MOUSEBUTTONUP:
   216             if (event.button.button == 3)
   217                 add_line(mouse_begin_x, mouse_begin_y, event.button.x,
   218                          event.button.y);
   219             if (event.button.button == 1)
   220                 add_rect(mouse_begin_x, mouse_begin_y, event.button.x,
   221                          event.button.y);
   222             break;
   223         case SDL_KEYDOWN:
   224             switch (event.key.keysym.sym) {
   225             case 'l':
   226                 if (event.key.keysym.mod & KMOD_SHIFT)
   227                     num_lines = 0;
   228                 else
   229                     add_line(rand() % 640, rand() % 480, rand() % 640,
   230                              rand() % 480);
   231                 break;
   232             case 'r':
   233                 if (event.key.keysym.mod & KMOD_SHIFT)
   234                     num_rects = 0;
   235                 else
   236                     add_rect(rand() % 640, rand() % 480, rand() % 640,
   237                              rand() % 480);
   238                 break;
   239             }
   240             break;
   241         default:
   242             break;
   243         }
   244     }
   245     for (i = 0; i < state->num_windows; ++i) {
   246         SDL_Renderer *renderer = state->renderers[i];
   247         if (state->windows[i] == NULL)
   248             continue;
   249         SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
   250         SDL_RenderClear(renderer);
   251 
   252         DrawRects(renderer);
   253         DrawPoints(renderer);
   254         DrawRectRectIntersections(renderer);
   255         DrawLines(renderer);
   256         DrawRectLineIntersections(renderer);
   257 
   258         SDL_RenderPresent(renderer);
   259     }
   260 #ifdef __EMSCRIPTEN__
   261     if (done) {
   262         emscripten_cancel_main_loop();
   263     }
   264 #endif
   265 }
   266 
   267 int
   268 main(int argc, char *argv[])
   269 {
   270     int i;
   271     Uint32 then, now, frames;
   272 
   273     /* Enable standard application logging */
   274     SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
   275 
   276     /* Initialize parameters */
   277     num_objects = NUM_OBJECTS;
   278 
   279     /* Initialize test framework */
   280     state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
   281     if (!state) {
   282         return 1;
   283     }
   284     for (i = 1; i < argc;) {
   285         int consumed;
   286 
   287         consumed = SDLTest_CommonArg(state, i);
   288         if (consumed == 0) {
   289             consumed = -1;
   290             if (SDL_strcasecmp(argv[i], "--blend") == 0) {
   291                 if (argv[i + 1]) {
   292                     if (SDL_strcasecmp(argv[i + 1], "none") == 0) {
   293                         blendMode = SDL_BLENDMODE_NONE;
   294                         consumed = 2;
   295                     } else if (SDL_strcasecmp(argv[i + 1], "blend") == 0) {
   296                         blendMode = SDL_BLENDMODE_BLEND;
   297                         consumed = 2;
   298                     } else if (SDL_strcasecmp(argv[i + 1], "add") == 0) {
   299                         blendMode = SDL_BLENDMODE_ADD;
   300                         consumed = 2;
   301                     } else if (SDL_strcasecmp(argv[i + 1], "mod") == 0) {
   302                         blendMode = SDL_BLENDMODE_MOD;
   303                         consumed = 2;
   304                     }
   305                 }
   306             } else if (SDL_strcasecmp(argv[i], "--cyclecolor") == 0) {
   307                 cycle_color = SDL_TRUE;
   308                 consumed = 1;
   309             } else if (SDL_strcasecmp(argv[i], "--cyclealpha") == 0) {
   310                 cycle_alpha = SDL_TRUE;
   311                 consumed = 1;
   312             } else if (SDL_isdigit(*argv[i])) {
   313                 num_objects = SDL_atoi(argv[i]);
   314                 consumed = 1;
   315             }
   316         }
   317         if (consumed < 0) {
   318             SDL_Log("Usage: %s %s [--blend none|blend|add|mod] [--cyclecolor] [--cyclealpha]\n",
   319                     argv[0], SDLTest_CommonUsage(state));
   320             return 1;
   321         }
   322         i += consumed;
   323     }
   324     if (!SDLTest_CommonInit(state)) {
   325         return 2;
   326     }
   327 
   328     /* Create the windows and initialize the renderers */
   329     for (i = 0; i < state->num_windows; ++i) {
   330         SDL_Renderer *renderer = state->renderers[i];
   331         SDL_SetRenderDrawBlendMode(renderer, blendMode);
   332         SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
   333         SDL_RenderClear(renderer);
   334     }
   335 
   336     srand(time(NULL));
   337 
   338     /* Main render loop */
   339     frames = 0;
   340     then = SDL_GetTicks();
   341     done = 0;
   342 
   343 #ifdef __EMSCRIPTEN__
   344     emscripten_set_main_loop(loop, 0, 1);
   345 #else
   346     while (!done) {
   347         ++frames;
   348         loop();
   349     }
   350 #endif
   351 
   352     SDLTest_CommonQuit(state);
   353 
   354     /* Print out some timing information */
   355     now = SDL_GetTicks();
   356     if (now > then) {
   357         double fps = ((double) frames * 1000) / (now - then);
   358         SDL_Log("%2.2f frames per second\n", fps);
   359     }
   360     return 0;
   361 }
   362 
   363 /* vi: set ts=4 sw=4 expandtab: */