test/testintersections.c
author Sam Lantinga <slouken@libsdl.org>
Tue, 15 Feb 2011 13:59:59 -0800
changeset 5297 1800dc39b74c
parent 5184 d976b67150c5
child 5535 96594ac5fd1a
permissions -rw-r--r--
Changed the concept of a render clip rect to a render viewport.
The render viewport is automatically re-centered when the window changes size, so applications that don't care will not have to handle recalculating their rendering coordinates.

Fixed API for drawing and filling multiple rectangles - the parameter should be an array of rects, not an array of pointers to rects.

Fixed API for updating window rects for consistency with other APIs - the order is pointer to array followed by count in array.
     1 
     2 /* Simple program:  draw as many random objects on the screen as possible */
     3 
     4 #include <stdlib.h>
     5 #include <stdio.h>
     6 #include <time.h>
     7 
     8 #include "common.h"
     9 
    10 #define SWAP(typ,a,b) do{typ t=a;a=b;b=t;}while(0)
    11 #define NUM_OBJECTS	100
    12 
    13 static CommonState *state;
    14 static int num_objects;
    15 static SDL_bool cycle_color;
    16 static SDL_bool cycle_alpha;
    17 static int cycle_direction = 1;
    18 static int current_alpha = 255;
    19 static int current_color = 255;
    20 static SDL_BlendMode blendMode = SDL_BLENDMODE_NONE;
    21 
    22 void
    23 DrawPoints(SDL_Renderer * renderer)
    24 {
    25     int i;
    26     int x, y;
    27     SDL_Rect viewport;
    28 
    29     /* Query the sizes */
    30     SDL_RenderGetViewport(renderer, &viewport);
    31 
    32     for (i = 0; i < num_objects * 4; ++i) {
    33         /* Cycle the color and alpha, if desired */
    34         if (cycle_color) {
    35             current_color += cycle_direction;
    36             if (current_color < 0) {
    37                 current_color = 0;
    38                 cycle_direction = -cycle_direction;
    39             }
    40             if (current_color > 255) {
    41                 current_color = 255;
    42                 cycle_direction = -cycle_direction;
    43             }
    44         }
    45         if (cycle_alpha) {
    46             current_alpha += cycle_direction;
    47             if (current_alpha < 0) {
    48                 current_alpha = 0;
    49                 cycle_direction = -cycle_direction;
    50             }
    51             if (current_alpha > 255) {
    52                 current_alpha = 255;
    53                 cycle_direction = -cycle_direction;
    54             }
    55         }
    56         SDL_SetRenderDrawColor(renderer, 255, (Uint8) current_color,
    57                                (Uint8) current_color, (Uint8) current_alpha);
    58 
    59         x = rand() % viewport.w;
    60         y = rand() % viewport.h;
    61         SDL_RenderDrawPoint(renderer, x, y);
    62     }
    63 }
    64 
    65 #define MAX_LINES 16
    66 int num_lines = 0;
    67 SDL_Rect lines[MAX_LINES];
    68 static int
    69 add_line(int x1, int y1, int x2, int y2)
    70 {
    71     if (num_lines >= MAX_LINES)
    72         return 0;
    73     if ((x1 == x2) && (y1 == y2))
    74         return 0;
    75 
    76     printf("adding line (%d, %d), (%d, %d)\n", x1, y1, x2, y2);
    77     lines[num_lines].x = x1;
    78     lines[num_lines].y = y1;
    79     lines[num_lines].w = x2;
    80     lines[num_lines].h = y2;
    81 
    82     return ++num_lines;
    83 }
    84 
    85 
    86 void
    87 DrawLines(SDL_Renderer * renderer)
    88 {
    89     int i;
    90     int x1, y1, x2, y2;
    91     SDL_Rect viewport;
    92 
    93     /* Query the sizes */
    94     SDL_RenderGetViewport(renderer, &viewport);
    95 
    96     SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
    97 
    98     for (i = 0; i < num_lines; ++i) {
    99         if (i == -1) {
   100             SDL_RenderDrawLine(renderer, 0, 0, viewport.w - 1, viewport.h - 1);
   101             SDL_RenderDrawLine(renderer, 0, viewport.h - 1, viewport.w - 1, 0);
   102             SDL_RenderDrawLine(renderer, 0, viewport.h / 2, viewport.w - 1, viewport.h / 2);
   103             SDL_RenderDrawLine(renderer, viewport.w / 2, 0, viewport.w / 2, viewport.h - 1);
   104         } else {
   105             SDL_RenderDrawLine(renderer, lines[i].x, lines[i].y, lines[i].w, lines[i].h);
   106         }
   107     }
   108 }
   109 
   110 #define MAX_RECTS 16
   111 int num_rects = 0;
   112 SDL_Rect rects[MAX_RECTS];
   113 static int
   114 add_rect(int x1, int y1, int x2, int y2)
   115 {
   116     if (num_rects >= MAX_RECTS)
   117         return 0;
   118     if ((x1 == x2) || (y1 == y2))
   119         return 0;
   120 
   121     if (x1 > x2)
   122         SWAP(int, x1, x2);
   123     if (y1 > y2)
   124         SWAP(int, y1, y2);
   125 
   126     printf("adding rect (%d, %d), (%d, %d) [%dx%d]\n", x1, y1, x2, y2,
   127            x2 - x1, y2 - y1);
   128 
   129     rects[num_rects].x = x1;
   130     rects[num_rects].y = y1;
   131     rects[num_rects].w = x2 - x1;
   132     rects[num_rects].h = y2 - y1;
   133 
   134     return ++num_rects;
   135 }
   136 
   137 static void
   138 DrawRects(SDL_Renderer * renderer)
   139 {
   140     SDL_SetRenderDrawColor(renderer, 255, 127, 0, 255);
   141     SDL_RenderFillRects(renderer, rects, num_rects);
   142 }
   143 
   144 static void
   145 DrawRectLineIntersections(SDL_Renderer * renderer)
   146 {
   147     int i, j;
   148 
   149     SDL_SetRenderDrawColor(renderer, 0, 255, 55, 255);
   150 
   151     for (i = 0; i < num_rects; i++)
   152         for (j = 0; j < num_lines; j++) {
   153             int x1, y1, x2, y2;
   154             SDL_Rect r;
   155 
   156             r = rects[i];
   157             x1 = lines[j].x;
   158             y1 = lines[j].y;
   159             x2 = lines[j].w;
   160             y2 = lines[j].h;
   161 
   162             if (SDL_IntersectRectAndLine(&r, &x1, &y1, &x2, &y2)) {
   163                 SDL_RenderDrawLine(renderer, x1, y1, x2, y2);
   164             }
   165         }
   166 }
   167 
   168 static void
   169 DrawRectRectIntersections(SDL_Renderer * renderer)
   170 {
   171     int i, j;
   172 
   173     SDL_SetRenderDrawColor(renderer, 255, 200, 0, 255);
   174 
   175     for (i = 0; i < num_rects; i++)
   176         for (j = i + 1; j < num_rects; j++) {
   177             SDL_Rect r;
   178             if (SDL_IntersectRect(&rects[i], &rects[j], &r)) {
   179                 SDL_RenderFillRect(renderer, &r);
   180             }
   181         }
   182 }
   183 
   184 int
   185 main(int argc, char *argv[])
   186 {
   187     int mouse_begin_x = -1, mouse_begin_y = -1;
   188     int i, done;
   189     SDL_Event event;
   190     Uint32 then, now, frames;
   191 
   192     /* Initialize parameters */
   193     num_objects = NUM_OBJECTS;
   194 
   195     /* Initialize test framework */
   196     state = CommonCreateState(argv, SDL_INIT_VIDEO);
   197     if (!state) {
   198         return 1;
   199     }
   200     for (i = 1; i < argc;) {
   201         int consumed;
   202 
   203         consumed = CommonArg(state, i);
   204         if (consumed == 0) {
   205             consumed = -1;
   206             if (SDL_strcasecmp(argv[i], "--blend") == 0) {
   207                 if (argv[i + 1]) {
   208                     if (SDL_strcasecmp(argv[i + 1], "none") == 0) {
   209                         blendMode = SDL_BLENDMODE_NONE;
   210                         consumed = 2;
   211                     } else if (SDL_strcasecmp(argv[i + 1], "blend") == 0) {
   212                         blendMode = SDL_BLENDMODE_BLEND;
   213                         consumed = 2;
   214                     } else if (SDL_strcasecmp(argv[i + 1], "add") == 0) {
   215                         blendMode = SDL_BLENDMODE_ADD;
   216                         consumed = 2;
   217                     } else if (SDL_strcasecmp(argv[i + 1], "mod") == 0) {
   218                         blendMode = SDL_BLENDMODE_MOD;
   219                         consumed = 2;
   220                     }
   221                 }
   222             } else if (SDL_strcasecmp(argv[i], "--cyclecolor") == 0) {
   223                 cycle_color = SDL_TRUE;
   224                 consumed = 1;
   225             } else if (SDL_strcasecmp(argv[i], "--cyclealpha") == 0) {
   226                 cycle_alpha = SDL_TRUE;
   227                 consumed = 1;
   228             } else if (SDL_isdigit(*argv[i])) {
   229                 num_objects = SDL_atoi(argv[i]);
   230                 consumed = 1;
   231             }
   232         }
   233         if (consumed < 0) {
   234             fprintf(stderr,
   235                     "Usage: %s %s [--blend none|blend|add|mod] [--cyclecolor] [--cyclealpha]\n",
   236                     argv[0], CommonUsage(state));
   237             return 1;
   238         }
   239         i += consumed;
   240     }
   241     if (!CommonInit(state)) {
   242         return 2;
   243     }
   244 
   245     /* Create the windows and initialize the renderers */
   246     for (i = 0; i < state->num_windows; ++i) {
   247         SDL_Renderer *renderer = state->renderers[i];
   248         SDL_SetRenderDrawBlendMode(renderer, blendMode);
   249         SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
   250         SDL_RenderClear(renderer);
   251     }
   252 
   253     srand(time(NULL));
   254 
   255     /* Main render loop */
   256     frames = 0;
   257     then = SDL_GetTicks();
   258     done = 0;
   259     while (!done) {
   260         /* Check for events */
   261         ++frames;
   262         while (SDL_PollEvent(&event)) {
   263             CommonEvent(state, &event, &done);
   264             switch (event.type) {
   265             case SDL_MOUSEBUTTONDOWN:
   266                 mouse_begin_x = event.button.x;
   267                 mouse_begin_y = event.button.y;
   268                 break;
   269             case SDL_MOUSEBUTTONUP:
   270                 if (event.button.button == 3)
   271                     add_line(mouse_begin_x, mouse_begin_y, event.button.x,
   272                              event.button.y);
   273                 if (event.button.button == 1)
   274                     add_rect(mouse_begin_x, mouse_begin_y, event.button.x,
   275                              event.button.y);
   276                 break;
   277             case SDL_KEYDOWN:
   278                 switch (event.key.keysym.sym) {
   279                 case 'l':
   280                     if (event.key.keysym.mod & KMOD_SHIFT)
   281                         num_lines = 0;
   282                     else
   283                         add_line(rand() % 640, rand() % 480, rand() % 640,
   284                                  rand() % 480);
   285                     break;
   286                 case 'r':
   287                     if (event.key.keysym.mod & KMOD_SHIFT)
   288                         num_rects = 0;
   289                     else
   290                         add_rect(rand() % 640, rand() % 480, rand() % 640,
   291                                  rand() % 480);
   292                     break;
   293                 }
   294                 break;
   295             default:
   296                 break;
   297             }
   298         }
   299         for (i = 0; i < state->num_windows; ++i) {
   300             SDL_Renderer *renderer = state->renderers[i];
   301             SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
   302             SDL_RenderClear(renderer);
   303 
   304             DrawRects(renderer);
   305             DrawPoints(renderer);
   306             DrawRectRectIntersections(renderer);
   307             DrawLines(renderer);
   308             DrawRectLineIntersections(renderer);
   309 
   310             SDL_RenderPresent(renderer);
   311         }
   312     }
   313 
   314     CommonQuit(state);
   315 
   316     /* Print out some timing information */
   317     now = SDL_GetTicks();
   318     if (now > then) {
   319         double fps = ((double) frames * 1000) / (now - then);
   320         printf("%2.2f frames per second\n", fps);
   321     }
   322     return 0;
   323 }
   324 
   325 /* vi: set ts=4 sw=4 expandtab: */