test/testrendertarget.c
author David Ludwig <dludwig@pobox.com>
Wed, 25 Dec 2013 21:39:48 -0500
changeset 8563 c0e68f3b6bbb
parent 7787 e6f3e8fc96ea
child 8149 681eb46b8ac4
permissions -rw-r--r--
WinRT: compiled the d3d11 renderer's shaders into SDL itself

Previously, the shaders would get compiled separately, the output of which would need to be packaged into the app. This change should make SDL's dll be the only binary needed to include SDL in a WinRT app.
slouken@6232
     1
/*
slouken@7517
     2
  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
slouken@6232
     3
slouken@6232
     4
  This software is provided 'as-is', without any express or implied
slouken@6232
     5
  warranty.  In no event will the authors be held liable for any damages
slouken@6232
     6
  arising from the use of this software.
slouken@6232
     7
slouken@6232
     8
  Permission is granted to anyone to use this software for any purpose,
slouken@6232
     9
  including commercial applications, and to alter it and redistribute it
slouken@6232
    10
  freely.
slouken@6232
    11
*/
slouken@6232
    12
/* Simple program:  Move N sprites around on the screen as fast as possible */
slouken@6232
    13
slouken@6232
    14
#include <stdlib.h>
slouken@6232
    15
#include <stdio.h>
slouken@6232
    16
#include <time.h>
slouken@6232
    17
slouken@6785
    18
#include "SDL_test_common.h"
slouken@6232
    19
slouken@6232
    20
slouken@6785
    21
static SDLTest_CommonState *state;
slouken@6232
    22
slouken@6232
    23
typedef struct {
slouken@6232
    24
    SDL_Window *window;
slouken@6232
    25
    SDL_Renderer *renderer;
slouken@6232
    26
    SDL_Texture *background;
slouken@6232
    27
    SDL_Texture *sprite;
slouken@6232
    28
    SDL_Rect sprite_rect;
slouken@6232
    29
    int scale_direction;
slouken@6232
    30
} DrawState;
slouken@6232
    31
slouken@6232
    32
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
slouken@6232
    33
static void
slouken@6232
    34
quit(int rc)
slouken@6232
    35
{
slouken@6785
    36
    SDLTest_CommonQuit(state);
slouken@6232
    37
    exit(rc);
slouken@6232
    38
}
slouken@6232
    39
slouken@6232
    40
SDL_Texture *
slouken@6232
    41
LoadTexture(SDL_Renderer *renderer, char *file, SDL_bool transparent)
slouken@6232
    42
{
slouken@6232
    43
    SDL_Surface *temp;
slouken@6232
    44
    SDL_Texture *texture;
slouken@6232
    45
slouken@6232
    46
    /* Load the sprite image */
slouken@6232
    47
    temp = SDL_LoadBMP(file);
slouken@6232
    48
    if (temp == NULL) {
aschiffler@7639
    49
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError());
slouken@6232
    50
        return NULL;
slouken@6232
    51
    }
slouken@6232
    52
slouken@6232
    53
    /* Set transparent pixel as the pixel at (0,0) */
slouken@6232
    54
    if (transparent) {
slouken@6232
    55
        if (temp->format->palette) {
slouken@6232
    56
            SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels);
slouken@6232
    57
        } else {
slouken@6232
    58
            switch (temp->format->BitsPerPixel) {
slouken@6232
    59
            case 15:
slouken@6232
    60
                SDL_SetColorKey(temp, SDL_TRUE,
slouken@6232
    61
                                (*(Uint16 *) temp->pixels) & 0x00007FFF);
slouken@6232
    62
                break;
slouken@6232
    63
            case 16:
slouken@6232
    64
                SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels);
slouken@6232
    65
                break;
slouken@6232
    66
            case 24:
slouken@6232
    67
                SDL_SetColorKey(temp, SDL_TRUE,
slouken@6232
    68
                                (*(Uint32 *) temp->pixels) & 0x00FFFFFF);
slouken@6232
    69
                break;
slouken@6232
    70
            case 32:
slouken@6232
    71
                SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels);
slouken@6232
    72
                break;
slouken@6232
    73
            }
slouken@6232
    74
        }
slouken@6232
    75
    }
slouken@6232
    76
slouken@6232
    77
    /* Create textures from the image */
slouken@6232
    78
    texture = SDL_CreateTextureFromSurface(renderer, temp);
slouken@6232
    79
    if (!texture) {
aschiffler@7639
    80
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError());
slouken@6232
    81
        SDL_FreeSurface(temp);
slouken@6232
    82
        return NULL;
slouken@6232
    83
    }
slouken@6232
    84
    SDL_FreeSurface(temp);
slouken@6232
    85
slouken@6232
    86
    /* We're ready to roll. :) */
slouken@6232
    87
    return texture;
slouken@6232
    88
}
slouken@6232
    89
slouken@7781
    90
SDL_bool
slouken@7502
    91
DrawComposite(DrawState *s)
slouken@7502
    92
{
slouken@7502
    93
    SDL_Rect viewport, R;
philipp@7513
    94
    SDL_Texture *target;
slouken@7502
    95
slouken@7502
    96
    static SDL_bool blend_tested = SDL_FALSE;
slouken@7502
    97
    if (!blend_tested) {
slouken@7502
    98
        SDL_Texture *A, *B;
slouken@7502
    99
        Uint32 P;
slouken@7502
   100
slouken@7502
   101
        A = SDL_CreateTexture(s->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, 1, 1);
slouken@7502
   102
        SDL_SetTextureBlendMode(A, SDL_BLENDMODE_BLEND);
slouken@7502
   103
slouken@7502
   104
        B = SDL_CreateTexture(s->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, 1, 1);
slouken@7502
   105
        SDL_SetTextureBlendMode(B, SDL_BLENDMODE_BLEND);
slouken@7502
   106
slouken@7502
   107
        SDL_SetRenderTarget(s->renderer, A);
slouken@7502
   108
        SDL_SetRenderDrawColor(s->renderer, 0x00, 0x00, 0x00, 0x80);
slouken@7502
   109
        SDL_RenderFillRect(s->renderer, NULL);
slouken@7502
   110
slouken@7502
   111
        SDL_SetRenderTarget(s->renderer, B);
slouken@7502
   112
        SDL_SetRenderDrawColor(s->renderer, 0x00, 0x00, 0x00, 0x00);
slouken@7502
   113
        SDL_RenderFillRect(s->renderer, NULL);
slouken@7502
   114
        SDL_RenderCopy(s->renderer, A, NULL, NULL);
slouken@7502
   115
        SDL_RenderReadPixels(s->renderer, NULL, SDL_PIXELFORMAT_ARGB8888, &P, sizeof(P));
slouken@7502
   116
aschiffler@7639
   117
        SDL_Log("Blended pixel: 0x%8.8X\n", P);
slouken@7502
   118
slouken@7502
   119
        SDL_DestroyTexture(A);
slouken@7502
   120
        SDL_DestroyTexture(B);
slouken@7502
   121
        blend_tested = SDL_TRUE;
slouken@7502
   122
    }
slouken@7502
   123
slouken@7502
   124
    SDL_RenderGetViewport(s->renderer, &viewport);
slouken@7502
   125
slouken@7502
   126
    target = SDL_CreateTexture(s->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, viewport.w, viewport.h);
slouken@7502
   127
    SDL_SetTextureBlendMode(target, SDL_BLENDMODE_BLEND);
slouken@7502
   128
    SDL_SetRenderTarget(s->renderer, target);
slouken@7502
   129
slouken@7502
   130
    /* Draw the background.
slouken@7502
   131
       This is solid black so when the sprite is copied to it, any per-pixel alpha will be blended through.
slouken@7502
   132
     */
slouken@7502
   133
    SDL_SetRenderDrawColor(s->renderer, 0x00, 0x00, 0x00, 0x00);
slouken@7502
   134
    SDL_RenderFillRect(s->renderer, NULL);
slouken@7502
   135
slouken@7502
   136
    /* Scale and draw the sprite */
slouken@7502
   137
    s->sprite_rect.w += s->scale_direction;
slouken@7502
   138
    s->sprite_rect.h += s->scale_direction;
slouken@7502
   139
    if (s->scale_direction > 0) {
slouken@7502
   140
        if (s->sprite_rect.w >= viewport.w || s->sprite_rect.h >= viewport.h) {
slouken@7502
   141
            s->scale_direction = -1;
slouken@7502
   142
        }
slouken@7502
   143
    } else {
slouken@7502
   144
        if (s->sprite_rect.w <= 1 || s->sprite_rect.h <= 1) {
slouken@7502
   145
            s->scale_direction = 1;
slouken@7502
   146
        }
slouken@7502
   147
    }
slouken@7502
   148
    s->sprite_rect.x = (viewport.w - s->sprite_rect.w) / 2;
slouken@7502
   149
    s->sprite_rect.y = (viewport.h - s->sprite_rect.h) / 2;
slouken@7502
   150
slouken@7502
   151
    SDL_RenderCopy(s->renderer, s->sprite, NULL, &s->sprite_rect);
slouken@7502
   152
slouken@7502
   153
    SDL_SetRenderTarget(s->renderer, NULL);
slouken@7502
   154
    SDL_RenderCopy(s->renderer, s->background, NULL, NULL);
slouken@7502
   155
slouken@7502
   156
    SDL_SetRenderDrawBlendMode(s->renderer, SDL_BLENDMODE_BLEND);
slouken@7502
   157
    SDL_SetRenderDrawColor(s->renderer, 0xff, 0x00, 0x00, 0x80);
slouken@7502
   158
    R.x = 0;
slouken@7502
   159
    R.y = 0;
slouken@7502
   160
    R.w = 100;
slouken@7502
   161
    R.h = 100;
slouken@7502
   162
    SDL_RenderFillRect(s->renderer, &R);
slouken@7502
   163
    SDL_SetRenderDrawBlendMode(s->renderer, SDL_BLENDMODE_NONE);
slouken@7502
   164
slouken@7502
   165
    SDL_RenderCopy(s->renderer, target, NULL, NULL);
slouken@7502
   166
    SDL_DestroyTexture(target);
slouken@7502
   167
slouken@7502
   168
    /* Update the screen! */
slouken@7502
   169
    SDL_RenderPresent(s->renderer);
slouken@7781
   170
    return SDL_TRUE;
slouken@7502
   171
}
slouken@7502
   172
slouken@7781
   173
SDL_bool
slouken@6232
   174
Draw(DrawState *s)
slouken@6232
   175
{
slouken@6232
   176
    SDL_Rect viewport;
slouken@6232
   177
    SDL_Texture *target;
slouken@6232
   178
slouken@6232
   179
    SDL_RenderGetViewport(s->renderer, &viewport);
slouken@6232
   180
slouken@6232
   181
    target = SDL_CreateTexture(s->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, viewport.w, viewport.h);
slouken@7781
   182
    if (!target) {
slouken@7781
   183
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create render target texture: %s\n", SDL_GetError());
slouken@7781
   184
        return SDL_FALSE;
slouken@7781
   185
    }
slouken@6247
   186
    SDL_SetRenderTarget(s->renderer, target);
slouken@6232
   187
slouken@6232
   188
    /* Draw the background */
slouken@6232
   189
    SDL_RenderCopy(s->renderer, s->background, NULL, NULL);
slouken@6232
   190
slouken@6232
   191
    /* Scale and draw the sprite */
slouken@6232
   192
    s->sprite_rect.w += s->scale_direction;
slouken@6232
   193
    s->sprite_rect.h += s->scale_direction;
slouken@6232
   194
    if (s->scale_direction > 0) {
slouken@6232
   195
        if (s->sprite_rect.w >= viewport.w || s->sprite_rect.h >= viewport.h) {
slouken@6232
   196
            s->scale_direction = -1;
slouken@6232
   197
        }
slouken@6232
   198
    } else {
slouken@6232
   199
        if (s->sprite_rect.w <= 1 || s->sprite_rect.h <= 1) {
slouken@6232
   200
            s->scale_direction = 1;
slouken@6232
   201
        }
slouken@6232
   202
    }
slouken@6232
   203
    s->sprite_rect.x = (viewport.w - s->sprite_rect.w) / 2;
slouken@6232
   204
    s->sprite_rect.y = (viewport.h - s->sprite_rect.h) / 2;
slouken@6232
   205
slouken@6232
   206
    SDL_RenderCopy(s->renderer, s->sprite, NULL, &s->sprite_rect);
slouken@6232
   207
slouken@6247
   208
    SDL_SetRenderTarget(s->renderer, NULL);
slouken@6232
   209
    SDL_RenderCopy(s->renderer, target, NULL, NULL);
slouken@6232
   210
    SDL_DestroyTexture(target);
slouken@6232
   211
slouken@6232
   212
    /* Update the screen! */
slouken@6232
   213
    SDL_RenderPresent(s->renderer);
slouken@7781
   214
    return SDL_TRUE;
slouken@6232
   215
}
slouken@6232
   216
slouken@6232
   217
int
slouken@6232
   218
main(int argc, char *argv[])
slouken@6232
   219
{
slouken@6232
   220
    DrawState *drawstates;
slouken@6232
   221
    int i, done;
slouken@6232
   222
    SDL_Event event;
slouken@6232
   223
    int frames;
slouken@6232
   224
    Uint32 then, now;
slouken@7502
   225
    SDL_bool test_composite = SDL_FALSE;
slouken@6232
   226
aschiffler@7639
   227
    /* Enable standard application logging */
aschiffler@7639
   228
    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
aschiffler@7639
   229
slouken@6232
   230
    /* Initialize test framework */
slouken@6785
   231
    state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
slouken@6232
   232
    if (!state) {
slouken@6232
   233
        return 1;
slouken@6232
   234
    }
slouken@6232
   235
    for (i = 1; i < argc;) {
slouken@6232
   236
        int consumed;
slouken@6232
   237
slouken@6785
   238
        consumed = SDLTest_CommonArg(state, i);
slouken@6232
   239
        if (consumed == 0) {
slouken@7502
   240
            consumed = -1;
slouken@7502
   241
            if (SDL_strcasecmp(argv[i], "--composite") == 0) {
slouken@7502
   242
                test_composite = SDL_TRUE;
slouken@7502
   243
                consumed = 1;
slouken@7502
   244
            }
slouken@7502
   245
        }
slouken@7502
   246
        if (consumed < 0) {
aschiffler@7639
   247
            SDL_Log("Usage: %s %s [--composite]\n",
slouken@7502
   248
                    argv[0], SDLTest_CommonUsage(state));
slouken@7502
   249
            quit(1);
slouken@6232
   250
        }
slouken@6232
   251
        i += consumed;
slouken@6232
   252
    }
slouken@6785
   253
    if (!SDLTest_CommonInit(state)) {
slouken@6232
   254
        quit(2);
slouken@6232
   255
    }
slouken@6232
   256
slouken@6232
   257
    drawstates = SDL_stack_alloc(DrawState, state->num_windows);
slouken@6232
   258
    for (i = 0; i < state->num_windows; ++i) {
slouken@6232
   259
        DrawState *drawstate = &drawstates[i];
slouken@6232
   260
slouken@6232
   261
        drawstate->window = state->windows[i];
slouken@6232
   262
        drawstate->renderer = state->renderers[i];
slouken@7502
   263
        if (test_composite) {
slouken@7502
   264
            drawstate->sprite = LoadTexture(drawstate->renderer, "icon-alpha.bmp", SDL_TRUE);
slouken@7502
   265
        } else {
slouken@7502
   266
            drawstate->sprite = LoadTexture(drawstate->renderer, "icon.bmp", SDL_TRUE);
slouken@7502
   267
        }
slouken@6232
   268
        drawstate->background = LoadTexture(drawstate->renderer, "sample.bmp", SDL_FALSE);
slouken@6232
   269
        if (!drawstate->sprite || !drawstate->background) {
slouken@6232
   270
            quit(2);
slouken@6232
   271
        }
slouken@6232
   272
        SDL_QueryTexture(drawstate->sprite, NULL, NULL,
slouken@6232
   273
                         &drawstate->sprite_rect.w, &drawstate->sprite_rect.h);
slouken@6232
   274
        drawstate->scale_direction = 1;
slouken@6232
   275
    }
slouken@6232
   276
slouken@6232
   277
    /* Main render loop */
slouken@6232
   278
    frames = 0;
slouken@6232
   279
    then = SDL_GetTicks();
slouken@6232
   280
    done = 0;
slouken@6232
   281
    while (!done) {
slouken@6232
   282
        /* Check for events */
slouken@6232
   283
        ++frames;
slouken@6232
   284
        while (SDL_PollEvent(&event)) {
slouken@6785
   285
            SDLTest_CommonEvent(state, &event, &done);
slouken@6232
   286
        }
slouken@6232
   287
        for (i = 0; i < state->num_windows; ++i) {
slouken@7787
   288
            if (state->windows[i] == NULL)
slouken@7787
   289
                continue;
slouken@7502
   290
            if (test_composite) {
slouken@7781
   291
                if (!DrawComposite(&drawstates[i])) done = 1;
slouken@7502
   292
            } else {
slouken@7781
   293
                if (!Draw(&drawstates[i])) done = 1;
slouken@7502
   294
            }
slouken@6232
   295
        }
slouken@6232
   296
    }
slouken@6232
   297
slouken@6232
   298
    /* Print out some timing information */
slouken@6232
   299
    now = SDL_GetTicks();
slouken@6232
   300
    if (now > then) {
slouken@6232
   301
        double fps = ((double) frames * 1000) / (now - then);
aschiffler@7639
   302
        SDL_Log("%2.2f frames per second\n", fps);
slouken@6232
   303
    }
slouken@6232
   304
slouken@6232
   305
    SDL_stack_free(drawstates);
slouken@6232
   306
slouken@6232
   307
    quit(0);
slouken@6232
   308
    return 0;
slouken@6232
   309
}
slouken@6232
   310
slouken@6232
   311
/* vi: set ts=4 sw=4 expandtab: */