test/testrendercopyex.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
gabomdq@6320
     1
/*
slouken@10737
     2
  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
gabomdq@6320
     3
gabomdq@6320
     4
  This software is provided 'as-is', without any express or implied
gabomdq@6320
     5
  warranty.  In no event will the authors be held liable for any damages
gabomdq@6320
     6
  arising from the use of this software.
gabomdq@6320
     7
gabomdq@6320
     8
  Permission is granted to anyone to use this software for any purpose,
gabomdq@6320
     9
  including commercial applications, and to alter it and redistribute it
gabomdq@6320
    10
  freely.
gabomdq@6320
    11
*/
gabomdq@6320
    12
/* Simple program:  Move N sprites around on the screen as fast as possible */
gabomdq@6320
    13
gabomdq@6320
    14
#include <stdlib.h>
gabomdq@6320
    15
#include <stdio.h>
gabomdq@6320
    16
#include <time.h>
gabomdq@6320
    17
icculus@9278
    18
#ifdef __EMSCRIPTEN__
icculus@9278
    19
#include <emscripten/emscripten.h>
icculus@9278
    20
#endif
icculus@9278
    21
slouken@6785
    22
#include "SDL_test_common.h"
gabomdq@6320
    23
gabomdq@6320
    24
slouken@6785
    25
static SDLTest_CommonState *state;
gabomdq@6320
    26
gabomdq@6320
    27
typedef struct {
gabomdq@6320
    28
    SDL_Window *window;
gabomdq@6320
    29
    SDL_Renderer *renderer;
gabomdq@6320
    30
    SDL_Texture *background;
gabomdq@6320
    31
    SDL_Texture *sprite;
gabomdq@6320
    32
    SDL_Rect sprite_rect;
gabomdq@6320
    33
    int scale_direction;
gabomdq@6320
    34
} DrawState;
gabomdq@6320
    35
icculus@9278
    36
DrawState *drawstates;
icculus@9278
    37
int done;
icculus@9278
    38
gabomdq@6320
    39
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
gabomdq@6320
    40
static void
gabomdq@6320
    41
quit(int rc)
gabomdq@6320
    42
{
slouken@6785
    43
    SDLTest_CommonQuit(state);
gabomdq@6320
    44
    exit(rc);
gabomdq@6320
    45
}
gabomdq@6320
    46
gabomdq@6320
    47
SDL_Texture *
philipp@10359
    48
LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent)
gabomdq@6320
    49
{
gabomdq@6320
    50
    SDL_Surface *temp;
gabomdq@6320
    51
    SDL_Texture *texture;
gabomdq@6320
    52
gabomdq@6320
    53
    /* Load the sprite image */
gabomdq@6320
    54
    temp = SDL_LoadBMP(file);
gabomdq@6320
    55
    if (temp == NULL) {
aschiffler@7639
    56
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError());
gabomdq@6320
    57
        return NULL;
gabomdq@6320
    58
    }
gabomdq@6320
    59
gabomdq@6320
    60
    /* Set transparent pixel as the pixel at (0,0) */
gabomdq@6320
    61
    if (transparent) {
gabomdq@6320
    62
        if (temp->format->palette) {
gabomdq@6320
    63
            SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels);
gabomdq@6320
    64
        } else {
gabomdq@6320
    65
            switch (temp->format->BitsPerPixel) {
gabomdq@6320
    66
            case 15:
gabomdq@6320
    67
                SDL_SetColorKey(temp, SDL_TRUE,
gabomdq@6320
    68
                                (*(Uint16 *) temp->pixels) & 0x00007FFF);
gabomdq@6320
    69
                break;
gabomdq@6320
    70
            case 16:
gabomdq@6320
    71
                SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels);
gabomdq@6320
    72
                break;
gabomdq@6320
    73
            case 24:
gabomdq@6320
    74
                SDL_SetColorKey(temp, SDL_TRUE,
gabomdq@6320
    75
                                (*(Uint32 *) temp->pixels) & 0x00FFFFFF);
gabomdq@6320
    76
                break;
gabomdq@6320
    77
            case 32:
gabomdq@6320
    78
                SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels);
gabomdq@6320
    79
                break;
gabomdq@6320
    80
            }
gabomdq@6320
    81
        }
gabomdq@6320
    82
    }
gabomdq@6320
    83
gabomdq@6320
    84
    /* Create textures from the image */
gabomdq@6320
    85
    texture = SDL_CreateTextureFromSurface(renderer, temp);
gabomdq@6320
    86
    if (!texture) {
aschiffler@7639
    87
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError());
gabomdq@6320
    88
        SDL_FreeSurface(temp);
gabomdq@6320
    89
        return NULL;
gabomdq@6320
    90
    }
gabomdq@6320
    91
    SDL_FreeSurface(temp);
gabomdq@6320
    92
gabomdq@6320
    93
    /* We're ready to roll. :) */
gabomdq@6320
    94
    return texture;
gabomdq@6320
    95
}
gabomdq@6320
    96
gabomdq@6320
    97
void
gabomdq@6320
    98
Draw(DrawState *s)
gabomdq@6320
    99
{
gabomdq@6320
   100
    SDL_Rect viewport;
gabomdq@6320
   101
    SDL_Texture *target;
gabomdq@6320
   102
    SDL_Point *center=NULL;
gabomdq@6320
   103
    SDL_Point origin = {0,0};
gabomdq@6320
   104
gabomdq@6320
   105
    SDL_RenderGetViewport(s->renderer, &viewport);
gabomdq@6320
   106
gabomdq@6320
   107
    target = SDL_CreateTexture(s->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, viewport.w, viewport.h);
gabomdq@6320
   108
    SDL_SetRenderTarget(s->renderer, target);
gabomdq@6320
   109
gabomdq@6320
   110
    /* Draw the background */
gabomdq@6320
   111
    SDL_RenderCopy(s->renderer, s->background, NULL, NULL);
gabomdq@6320
   112
gabomdq@6320
   113
    /* Scale and draw the sprite */
gabomdq@6320
   114
    s->sprite_rect.w += s->scale_direction;
gabomdq@6320
   115
    s->sprite_rect.h += s->scale_direction;
gabomdq@6320
   116
    if (s->scale_direction > 0) {
gabomdq@6320
   117
        center = &origin;
gabomdq@6320
   118
        if (s->sprite_rect.w >= viewport.w || s->sprite_rect.h >= viewport.h) {
gabomdq@6320
   119
            s->scale_direction = -1;
gabomdq@6320
   120
        }
gabomdq@6320
   121
    } else {
gabomdq@6320
   122
        if (s->sprite_rect.w <= 1 || s->sprite_rect.h <= 1) {
gabomdq@6320
   123
            s->scale_direction = 1;
gabomdq@6320
   124
        }
gabomdq@6320
   125
    }
gabomdq@6320
   126
    s->sprite_rect.x = (viewport.w - s->sprite_rect.w) / 2;
gabomdq@6320
   127
    s->sprite_rect.y = (viewport.h - s->sprite_rect.h) / 2;
gabomdq@6320
   128
philipp@10359
   129
    SDL_RenderCopyEx(s->renderer, s->sprite, NULL, &s->sprite_rect, (double)s->sprite_rect.w, center, (SDL_RendererFlip)s->scale_direction);
gabomdq@6320
   130
gabomdq@6320
   131
    SDL_SetRenderTarget(s->renderer, NULL);
gabomdq@6320
   132
    SDL_RenderCopy(s->renderer, target, NULL, NULL);
gabomdq@6320
   133
    SDL_DestroyTexture(target);
gabomdq@6320
   134
gabomdq@6320
   135
    /* Update the screen! */
gabomdq@6320
   136
    SDL_RenderPresent(s->renderer);
gabomdq@7678
   137
    /* SDL_Delay(10); */
gabomdq@6320
   138
}
gabomdq@6320
   139
icculus@9278
   140
void loop()
icculus@9278
   141
{
icculus@9278
   142
    int i;
icculus@9278
   143
    SDL_Event event;
icculus@9278
   144
icculus@9278
   145
    /* Check for events */
icculus@9278
   146
icculus@9278
   147
    while (SDL_PollEvent(&event)) {
icculus@9278
   148
        SDLTest_CommonEvent(state, &event, &done);
icculus@9278
   149
    }
icculus@9278
   150
    for (i = 0; i < state->num_windows; ++i) {
icculus@9278
   151
        if (state->windows[i] == NULL)
icculus@9278
   152
            continue;
icculus@9278
   153
        Draw(&drawstates[i]);
icculus@9278
   154
    }
philipp@9607
   155
#ifdef __EMSCRIPTEN__
philipp@9607
   156
    if (done) {
philipp@9607
   157
        emscripten_cancel_main_loop();
philipp@9607
   158
    }
philipp@9607
   159
#endif
icculus@9278
   160
}
icculus@9278
   161
gabomdq@6320
   162
int
gabomdq@6320
   163
main(int argc, char *argv[])
gabomdq@6320
   164
{
icculus@9278
   165
    int i;
gabomdq@6320
   166
    int frames;
gabomdq@6320
   167
    Uint32 then, now;
gabomdq@6320
   168
philipp@9922
   169
    /* Enable standard application logging */
aschiffler@7639
   170
    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
aschiffler@7639
   171
gabomdq@6320
   172
    /* Initialize test framework */
slouken@6785
   173
    state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
gabomdq@6320
   174
    if (!state) {
gabomdq@6320
   175
        return 1;
gabomdq@6320
   176
    }
gabomdq@6320
   177
    for (i = 1; i < argc;) {
gabomdq@6320
   178
        int consumed;
gabomdq@6320
   179
slouken@6785
   180
        consumed = SDLTest_CommonArg(state, i);
gabomdq@6320
   181
        if (consumed == 0) {
aschiffler@7639
   182
            SDL_Log("Usage: %s %s\n", argv[0], SDLTest_CommonUsage(state));
gabomdq@6320
   183
            return 1;
gabomdq@6320
   184
        }
gabomdq@6320
   185
        i += consumed;
gabomdq@6320
   186
    }
slouken@6785
   187
    if (!SDLTest_CommonInit(state)) {
gabomdq@6320
   188
        quit(2);
gabomdq@6320
   189
    }
gabomdq@6320
   190
gabomdq@6320
   191
    drawstates = SDL_stack_alloc(DrawState, state->num_windows);
gabomdq@6320
   192
    for (i = 0; i < state->num_windows; ++i) {
gabomdq@6320
   193
        DrawState *drawstate = &drawstates[i];
gabomdq@6320
   194
gabomdq@6320
   195
        drawstate->window = state->windows[i];
gabomdq@6320
   196
        drawstate->renderer = state->renderers[i];
gabomdq@6320
   197
        drawstate->sprite = LoadTexture(drawstate->renderer, "icon.bmp", SDL_TRUE);
gabomdq@6320
   198
        drawstate->background = LoadTexture(drawstate->renderer, "sample.bmp", SDL_FALSE);
gabomdq@6320
   199
        if (!drawstate->sprite || !drawstate->background) {
gabomdq@6320
   200
            quit(2);
gabomdq@6320
   201
        }
gabomdq@6320
   202
        SDL_QueryTexture(drawstate->sprite, NULL, NULL,
gabomdq@6320
   203
                         &drawstate->sprite_rect.w, &drawstate->sprite_rect.h);
gabomdq@6320
   204
        drawstate->scale_direction = 1;
gabomdq@6320
   205
    }
gabomdq@6320
   206
gabomdq@6320
   207
    /* Main render loop */
gabomdq@6320
   208
    frames = 0;
gabomdq@6320
   209
    then = SDL_GetTicks();
gabomdq@6320
   210
    done = 0;
icculus@9278
   211
icculus@9278
   212
#ifdef __EMSCRIPTEN__
icculus@9278
   213
    emscripten_set_main_loop(loop, 0, 1);
icculus@9278
   214
#else
gabomdq@6320
   215
    while (!done) {
gabomdq@6320
   216
        ++frames;
icculus@9278
   217
        loop();
gabomdq@6320
   218
        }
icculus@9278
   219
#endif
gabomdq@6320
   220
    /* Print out some timing information */
gabomdq@6320
   221
    now = SDL_GetTicks();
gabomdq@6320
   222
    if (now > then) {
gabomdq@6320
   223
        double fps = ((double) frames * 1000) / (now - then);
aschiffler@7639
   224
        SDL_Log("%2.2f frames per second\n", fps);
gabomdq@6320
   225
    }
gabomdq@6320
   226
gabomdq@6320
   227
    SDL_stack_free(drawstates);
gabomdq@6320
   228
gabomdq@6320
   229
    quit(0);
gabomdq@6320
   230
    return 0;
gabomdq@6320
   231
}
gabomdq@6320
   232
gabomdq@6320
   233
/* vi: set ts=4 sw=4 expandtab: */