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