SDL

Форк
0
/
testintersections.c 
393 строки · 11.4 Кб
1
/*
2
  Copyright (C) 1997-2024 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 <SDL3/SDL_main.h>
16
#include <SDL3/SDL_test_common.h>
17

18
#ifdef SDL_PLATFORM_EMSCRIPTEN
19
#include <emscripten/emscripten.h>
20
#endif
21

22
#define SWAP(typ, a, b) \
23
    do {                \
24
        typ t = a;      \
25
        a = b;          \
26
        b = t;          \
27
    } while (0)
28
#define NUM_OBJECTS 100
29

30
static SDLTest_CommonState *state;
31
static int num_objects;
32
static SDL_bool cycle_color;
33
static SDL_bool cycle_alpha;
34
static int cycle_direction = 1;
35
static int current_alpha = 255;
36
static int current_color = 255;
37
static SDL_BlendMode blendMode = SDL_BLENDMODE_NONE;
38

39
static float mouse_begin_x = -1.0f, mouse_begin_y = -1.0f;
40

41
static void DrawPoints(SDL_Renderer *renderer)
42
{
43
    int i;
44
    float x, y;
45
    SDL_Rect viewport;
46

47
    /* Query the sizes */
48
    SDL_GetRenderViewport(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 = (float)SDL_rand(viewport.w);
78
        y = (float)SDL_rand(viewport.h);
79
        SDL_RenderPoint(renderer, x, y);
80
    }
81
}
82

83
#define MAX_LINES 16
84
static int num_lines = 0;
85
static SDL_FRect lines[MAX_LINES];
86
static int add_line(float x1, float y1, float x2, float y2)
87
{
88
    if (num_lines >= MAX_LINES) {
89
        return 0;
90
    }
91
    if ((x1 == x2) && (y1 == y2)) {
92
        return 0;
93
    }
94

95
    SDL_Log("adding line (%g, %g), (%g, %g)\n", x1, y1, x2, y2);
96
    lines[num_lines].x = x1;
97
    lines[num_lines].y = y1;
98
    lines[num_lines].w = x2;
99
    lines[num_lines].h = y2;
100

101
    return ++num_lines;
102
}
103

104
static void DrawLines(SDL_Renderer *renderer)
105
{
106
    int i;
107
    SDL_Rect viewport;
108

109
    /* Query the sizes */
110
    SDL_GetRenderViewport(renderer, &viewport);
111

112
    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
113

114
    for (i = 0; i < num_lines; ++i) {
115
        if (i == -1) {
116
            SDL_RenderLine(renderer, 0.0f, 0.0f, (float)(viewport.w - 1), (float)(viewport.h - 1));
117
            SDL_RenderLine(renderer, 0.0f, (float)(viewport.h - 1), (float)(viewport.w - 1), 0.0f);
118
            SDL_RenderLine(renderer, 0.0f, (float)(viewport.h / 2), (float)(viewport.w - 1), (float)(viewport.h / 2));
119
            SDL_RenderLine(renderer, (float)(viewport.w / 2), 0.0f, (float)(viewport.w / 2), (float)(viewport.h - 1));
120
        } else {
121
            SDL_RenderLine(renderer, lines[i].x, lines[i].y, lines[i].w, lines[i].h);
122
        }
123
    }
124
}
125

126
#define MAX_RECTS 16
127
static int num_rects = 0;
128
static SDL_FRect rects[MAX_RECTS];
129
static int add_rect(float x1, float y1, float x2, float y2)
130
{
131
    if (num_rects >= MAX_RECTS) {
132
        return 0;
133
    }
134
    if ((x1 == x2) || (y1 == y2)) {
135
        return 0;
136
    }
137

138
    if (x1 > x2) {
139
        SWAP(float, x1, x2);
140
    }
141
    if (y1 > y2) {
142
        SWAP(float, y1, y2);
143
    }
144

145
    SDL_Log("adding rect (%g, %g), (%g, %g) [%gx%g]\n", x1, y1, x2, y2,
146
            x2 - x1, y2 - y1);
147

148
    rects[num_rects].x = x1;
149
    rects[num_rects].y = y1;
150
    rects[num_rects].w = x2 - x1;
151
    rects[num_rects].h = y2 - y1;
152

153
    return ++num_rects;
154
}
155

156
static void
157
DrawRects(SDL_Renderer *renderer)
158
{
159
    SDL_SetRenderDrawColor(renderer, 255, 127, 0, 255);
160
    SDL_RenderFillRects(renderer, rects, num_rects);
161
}
162

163
static void
164
DrawRectLineIntersections(SDL_Renderer *renderer)
165
{
166
    int i, j;
167

168
    SDL_SetRenderDrawColor(renderer, 0, 255, 55, 255);
169

170
    for (i = 0; i < num_rects; i++) {
171
        for (j = 0; j < num_lines; j++) {
172
            float x1, y1, x2, y2;
173
            SDL_FRect r;
174

175
            r = rects[i];
176
            x1 = lines[j].x;
177
            y1 = lines[j].y;
178
            x2 = lines[j].w;
179
            y2 = lines[j].h;
180

181
            if (SDL_GetRectAndLineIntersectionFloat(&r, &x1, &y1, &x2, &y2)) {
182
                SDL_RenderLine(renderer, x1, y1, x2, y2);
183
            }
184
        }
185
    }
186
}
187

188
static void
189
DrawRectRectIntersections(SDL_Renderer *renderer)
190
{
191
    int i, j;
192

193
    SDL_SetRenderDrawColor(renderer, 255, 200, 0, 255);
194

195
    for (i = 0; i < num_rects; i++) {
196
        for (j = i + 1; j < num_rects; j++) {
197
            SDL_FRect r;
198
            if (SDL_GetRectIntersectionFloat(&rects[i], &rects[j], &r)) {
199
                SDL_RenderFillRect(renderer, &r);
200
            }
201
        }
202
    }
203
}
204

205
static void loop(void *arg)
206
{
207
    int i;
208
    SDL_Event event;
209
    int *done = (int *)arg;
210

211
    /* Check for events */
212
    while (SDL_PollEvent(&event)) {
213
        SDLTest_CommonEvent(state, &event, done);
214
        switch (event.type) {
215
        case SDL_EVENT_MOUSE_BUTTON_DOWN:
216
            mouse_begin_x = event.button.x;
217
            mouse_begin_y = event.button.y;
218
            break;
219
        case SDL_EVENT_MOUSE_BUTTON_UP:
220
            if (event.button.button == 3) {
221
                add_line(mouse_begin_x, mouse_begin_y, event.button.x, event.button.y);
222
            }
223
            if (event.button.button == 1) {
224
                add_rect(mouse_begin_x, mouse_begin_y, event.button.x, event.button.y);
225
            }
226
            break;
227
        case SDL_EVENT_KEY_DOWN:
228
            switch (event.key.key) {
229
            case SDLK_L:
230
                if (event.key.mod & SDL_KMOD_SHIFT) {
231
                    num_lines = 0;
232
                } else {
233
                    add_line(
234
                        (float)SDL_rand(640),
235
                        (float)SDL_rand(480),
236
                        (float)SDL_rand(640),
237
                        (float)SDL_rand(480));
238
                }
239
                break;
240
            case SDLK_R:
241
                if (event.key.mod & SDL_KMOD_SHIFT) {
242
                    num_rects = 0;
243
                } else {
244
                    add_rect(
245
                        (float)SDL_rand(640),
246
                        (float)SDL_rand(480),
247
                        (float)SDL_rand(640),
248
                        (float)SDL_rand(480));
249
                }
250
                break;
251
            default:
252
                break;
253
            }
254
            break;
255
        default:
256
            break;
257
        }
258
    }
259
    for (i = 0; i < state->num_windows; ++i) {
260
        SDL_Renderer *renderer = state->renderers[i];
261
        if (state->windows[i] == NULL) {
262
            continue;
263
        }
264
        SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
265
        SDL_RenderClear(renderer);
266

267
        DrawRects(renderer);
268
        DrawPoints(renderer);
269
        DrawRectRectIntersections(renderer);
270
        DrawLines(renderer);
271
        DrawRectLineIntersections(renderer);
272

273
        SDL_RenderPresent(renderer);
274
    }
275
#ifdef SDL_PLATFORM_EMSCRIPTEN
276
    if (*done) {
277
        emscripten_cancel_main_loop();
278
    }
279
#endif
280
}
281

282
int main(int argc, char *argv[])
283
{
284
    int i;
285
    Uint64 then, now;
286
    Uint32 frames;
287
    int done;
288

289
    /* Initialize parameters */
290
    num_objects = -1; /* -1 means not initialized */
291

292
    /* Initialize test framework */
293
    state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
294
    if (!state) {
295
        return 1;
296
    }
297

298
    /* Enable standard application logging */
299
    SDL_SetLogPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
300

301
    for (i = 1; i < argc;) {
302
        int consumed;
303

304
        consumed = SDLTest_CommonArg(state, i);
305
        if (consumed == 0) {
306
            consumed = -1;
307
            if (SDL_strcasecmp(argv[i], "--blend") == 0) {
308
                if (argv[i + 1]) {
309
                    if (SDL_strcasecmp(argv[i + 1], "none") == 0) {
310
                        blendMode = SDL_BLENDMODE_NONE;
311
                        consumed = 2;
312
                    } else if (SDL_strcasecmp(argv[i + 1], "blend") == 0) {
313
                        blendMode = SDL_BLENDMODE_BLEND;
314
                        consumed = 2;
315
                    } else if (SDL_strcasecmp(argv[i + 1], "blend_premultiplied") == 0) {
316
                        blendMode = SDL_BLENDMODE_BLEND_PREMULTIPLIED;
317
                        consumed = 2;
318
                    } else if (SDL_strcasecmp(argv[i + 1], "add") == 0) {
319
                        blendMode = SDL_BLENDMODE_ADD;
320
                        consumed = 2;
321
                    } else if (SDL_strcasecmp(argv[i + 1], "add_premultiplied") == 0) {
322
                        blendMode = SDL_BLENDMODE_ADD_PREMULTIPLIED;
323
                        consumed = 2;
324
                    } else if (SDL_strcasecmp(argv[i + 1], "mod") == 0) {
325
                        blendMode = SDL_BLENDMODE_MOD;
326
                        consumed = 2;
327
                    } else if (SDL_strcasecmp(argv[i + 1], "mul") == 0) {
328
                        blendMode = SDL_BLENDMODE_MUL;
329
                        consumed = 2;
330
                    }
331
                }
332
            } else if (SDL_strcasecmp(argv[i], "--cyclecolor") == 0) {
333
                cycle_color = SDL_TRUE;
334
                consumed = 1;
335
            } else if (SDL_strcasecmp(argv[i], "--cyclealpha") == 0) {
336
                cycle_alpha = SDL_TRUE;
337
                consumed = 1;
338
            } else if (num_objects < 0 && SDL_isdigit(*argv[i])) {
339
                char *endptr = NULL;
340
                num_objects = (int)SDL_strtol(argv[i], &endptr, 0);
341
                if (endptr != argv[i] && *endptr == '\0' && num_objects >= 0) {
342
                    consumed = 1;
343
                }
344
            }
345
        }
346
        if (consumed < 0) {
347
            static const char *options[] = { "[--blend none|blend|blend_premultiplied|add|add_premultiplied|mod|mul]", "[--cyclecolor]", "[--cyclealpha]", "[count]", NULL };
348
            SDLTest_CommonLogUsage(state, argv[0], options);
349
            return 1;
350
        }
351
        i += consumed;
352
    }
353
    if (!SDLTest_CommonInit(state)) {
354
        return 2;
355
    }
356

357
    if (num_objects < 0) {
358
        num_objects = NUM_OBJECTS;
359
    }
360

361
    /* Create the windows and initialize the renderers */
362
    for (i = 0; i < state->num_windows; ++i) {
363
        SDL_Renderer *renderer = state->renderers[i];
364
        SDL_SetRenderDrawBlendMode(renderer, blendMode);
365
        SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
366
        SDL_RenderClear(renderer);
367
    }
368

369
    /* Main render loop */
370
    frames = 0;
371
    then = SDL_GetTicks();
372
    done = 0;
373

374
#ifdef SDL_PLATFORM_EMSCRIPTEN
375
    emscripten_set_main_loop_arg(loop, &done, 0, 1);
376
#else
377
    while (!done) {
378
        ++frames;
379
        loop(&done);
380
    }
381
#endif
382

383
    /* Print out some timing information */
384
    now = SDL_GetTicks();
385

386
    SDLTest_CommonQuit(state);
387

388
    if (now > then) {
389
        double fps = ((double)frames * 1000) / (now - then);
390
        SDL_Log("%2.2f frames per second\n", fps);
391
    }
392
    return 0;
393
}
394

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.