testrendercopyex.c (6132B)
1 /* 2 Copyright (C) 1997-2020 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 178 if (!SDLTest_CommonDefaultArgs(state, argc, argv) || !SDLTest_CommonInit(state)) { 179 SDLTest_CommonQuit(state); 180 return 1; 181 } 182 183 drawstates = SDL_stack_alloc(DrawState, state->num_windows); 184 for (i = 0; i < state->num_windows; ++i) { 185 DrawState *drawstate = &drawstates[i]; 186 187 drawstate->window = state->windows[i]; 188 drawstate->renderer = state->renderers[i]; 189 drawstate->sprite = LoadTexture(drawstate->renderer, "icon.bmp", SDL_TRUE); 190 drawstate->background = LoadTexture(drawstate->renderer, "sample.bmp", SDL_FALSE); 191 if (!drawstate->sprite || !drawstate->background) { 192 quit(2); 193 } 194 SDL_QueryTexture(drawstate->sprite, NULL, NULL, 195 &drawstate->sprite_rect.w, &drawstate->sprite_rect.h); 196 drawstate->scale_direction = 1; 197 } 198 199 /* Main render loop */ 200 frames = 0; 201 then = SDL_GetTicks(); 202 done = 0; 203 204 #ifdef __EMSCRIPTEN__ 205 emscripten_set_main_loop(loop, 0, 1); 206 #else 207 while (!done) { 208 ++frames; 209 loop(); 210 } 211 #endif 212 /* Print out some timing information */ 213 now = SDL_GetTicks(); 214 if (now > then) { 215 double fps = ((double) frames * 1000) / (now - then); 216 SDL_Log("%2.2f frames per second\n", fps); 217 } 218 219 SDL_stack_free(drawstates); 220 221 quit(0); 222 return 0; 223 } 224 225 /* vi: set ts=4 sw=4 expandtab: */