test/testintersections.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 04 Jan 2009 19:33:21 +0000
changeset 2994 7563b99e9a49
child 2997 e4f025078c1c
permissions -rw-r--r--
Date: Sat, 3 Jan 2009 22:11:18 -0500
From: "Donny Viszneki"
Subject: Re: [SDL] Want to help with SDL 1.3?

>> > For example, here's a good quick project for someone from the TODO list:
>> > * Add diagonal line clipping to SDL_IntersectRectAndLine()

Just wanted to point out that the patch is available at
http://codebad.com/rect-line-ix.patch

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