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