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