testviewport.c (7997B)
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: Check viewports */ 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.h" 23 #include "SDL_test_common.h" 24 25 26 static SDLTest_CommonState *state; 27 28 static SDL_Rect viewport; 29 static int done, j; 30 static SDL_bool use_target = SDL_FALSE; 31 #ifdef __EMSCRIPTEN__ 32 static Uint32 wait_start; 33 #endif 34 static SDL_Texture *sprite; 35 static int sprite_w, sprite_h; 36 37 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ 38 static void 39 quit(int rc) 40 { 41 SDLTest_CommonQuit(state); 42 exit(rc); 43 } 44 45 int 46 LoadSprite(char *file, SDL_Renderer *renderer) 47 { 48 SDL_Surface *temp; 49 50 /* Load the sprite image */ 51 temp = SDL_LoadBMP(file); 52 if (temp == NULL) { 53 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", file, SDL_GetError()); 54 return (-1); 55 } 56 sprite_w = temp->w; 57 sprite_h = temp->h; 58 59 /* Set transparent pixel as the pixel at (0,0) */ 60 if (temp->format->palette) { 61 SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels); 62 } else { 63 switch (temp->format->BitsPerPixel) { 64 case 15: 65 SDL_SetColorKey(temp, SDL_TRUE, 66 (*(Uint16 *) temp->pixels) & 0x00007FFF); 67 break; 68 case 16: 69 SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels); 70 break; 71 case 24: 72 SDL_SetColorKey(temp, SDL_TRUE, 73 (*(Uint32 *) temp->pixels) & 0x00FFFFFF); 74 break; 75 case 32: 76 SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels); 77 break; 78 } 79 } 80 81 /* Create textures from the image */ 82 sprite = SDL_CreateTextureFromSurface(renderer, temp); 83 if (!sprite) { 84 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError()); 85 SDL_FreeSurface(temp); 86 return (-1); 87 } 88 SDL_FreeSurface(temp); 89 90 /* We're ready to roll. :) */ 91 return (0); 92 } 93 94 void 95 DrawOnViewport(SDL_Renderer * renderer, SDL_Rect viewport) 96 { 97 SDL_Rect rect; 98 99 /* Set the viewport */ 100 SDL_RenderSetViewport(renderer, &viewport); 101 102 /* Draw a gray background */ 103 SDL_SetRenderDrawColor(renderer, 0x80, 0x80, 0x80, 0xFF); 104 SDL_RenderClear(renderer); 105 106 /* Test inside points */ 107 SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0x00, 0xFF); 108 SDL_RenderDrawPoint(renderer, viewport.h/2 + 20, viewport.w/2); 109 SDL_RenderDrawPoint(renderer, viewport.h/2 - 20, viewport.w/2); 110 SDL_RenderDrawPoint(renderer, viewport.h/2 , viewport.w/2 - 20); 111 SDL_RenderDrawPoint(renderer, viewport.h/2 , viewport.w/2 + 20); 112 113 /* Test horizontal and vertical lines */ 114 SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0x00, 0xFF); 115 SDL_RenderDrawLine(renderer, 1, 0, viewport.w-2, 0); 116 SDL_RenderDrawLine(renderer, 1, viewport.h-1, viewport.w-2, viewport.h-1); 117 SDL_RenderDrawLine(renderer, 0, 1, 0, viewport.h-2); 118 SDL_RenderDrawLine(renderer, viewport.w-1, 1, viewport.w-1, viewport.h-2); 119 120 /* Test diagonal lines */ 121 SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0xFF, 0xFF); 122 SDL_RenderDrawLine(renderer, 0, 0, viewport.w-1, viewport.h-1); 123 SDL_RenderDrawLine(renderer, viewport.w-1, 0, 0, viewport.h-1); 124 125 /* Test outside points */ 126 SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0x00, 0xFF); 127 SDL_RenderDrawPoint(renderer, viewport.h/2 + viewport.h, viewport.w/2); 128 SDL_RenderDrawPoint(renderer, viewport.h/2 - viewport.h, viewport.w/2); 129 SDL_RenderDrawPoint(renderer, viewport.h/2, viewport.w/2 - viewport.w); 130 SDL_RenderDrawPoint(renderer, viewport.h/2, viewport.w/2 + viewport.w); 131 132 /* Add a box at the top */ 133 rect.w = 8; 134 rect.h = 8; 135 rect.x = (viewport.w - rect.w) / 2; 136 rect.y = 0; 137 SDL_RenderFillRect(renderer, &rect); 138 139 /* Add a clip rect and fill it with the sprite */ 140 SDL_QueryTexture(sprite, NULL, NULL, &rect.w, &rect.h); 141 rect.x = (viewport.w - rect.w) / 2; 142 rect.y = (viewport.h - rect.h) / 2; 143 SDL_RenderSetClipRect(renderer, &rect); 144 SDL_RenderCopy(renderer, sprite, NULL, &rect); 145 SDL_RenderSetClipRect(renderer, NULL); 146 } 147 148 void 149 loop() 150 { 151 #ifdef __EMSCRIPTEN__ 152 /* Avoid using delays */ 153 if(SDL_GetTicks() - wait_start < 1000) 154 return; 155 wait_start = SDL_GetTicks(); 156 #endif 157 SDL_Event event; 158 int i; 159 /* Check for events */ 160 while (SDL_PollEvent(&event)) { 161 SDLTest_CommonEvent(state, &event, &done); 162 } 163 164 /* Move a viewport box in steps around the screen */ 165 viewport.x = j * 100; 166 viewport.y = viewport.x; 167 viewport.w = 100 + j * 50; 168 viewport.h = 100 + j * 50; 169 j = (j + 1) % 4; 170 SDL_Log("Current Viewport x=%i y=%i w=%i h=%i", viewport.x, viewport.y, viewport.w, viewport.h); 171 172 for (i = 0; i < state->num_windows; ++i) { 173 if (state->windows[i] == NULL) 174 continue; 175 176 /* Draw using viewport */ 177 DrawOnViewport(state->renderers[i], viewport); 178 179 /* Update the screen! */ 180 if (use_target) { 181 SDL_SetRenderTarget(state->renderers[i], NULL); 182 SDL_RenderCopy(state->renderers[i], state->targets[i], NULL, NULL); 183 SDL_RenderPresent(state->renderers[i]); 184 SDL_SetRenderTarget(state->renderers[i], state->targets[i]); 185 } else { 186 SDL_RenderPresent(state->renderers[i]); 187 } 188 } 189 190 #ifdef __EMSCRIPTEN__ 191 if (done) { 192 emscripten_cancel_main_loop(); 193 } 194 #endif 195 } 196 197 int 198 main(int argc, char *argv[]) 199 { 200 int i; 201 Uint32 then, now, frames; 202 203 /* Initialize test framework */ 204 state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); 205 if (!state) { 206 return 1; 207 } 208 209 210 for (i = 1; i < argc;) { 211 int consumed; 212 213 consumed = SDLTest_CommonArg(state, i); 214 if (consumed == 0) { 215 consumed = -1; 216 if (SDL_strcasecmp(argv[i], "--target") == 0) { 217 use_target = SDL_TRUE; 218 consumed = 1; 219 } 220 } 221 if (consumed < 0) { 222 static const char *options[] = { "[--target]", NULL }; 223 SDLTest_CommonLogUsage(state, argv[0], options); 224 quit(1); 225 } 226 i += consumed; 227 } 228 if (!SDLTest_CommonInit(state)) { 229 quit(2); 230 } 231 232 if (LoadSprite("icon.bmp", state->renderers[0]) < 0) { 233 quit(2); 234 } 235 236 if (use_target) { 237 int w, h; 238 239 for (i = 0; i < state->num_windows; ++i) { 240 SDL_GetWindowSize(state->windows[i], &w, &h); 241 state->targets[i] = SDL_CreateTexture(state->renderers[i], SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, w, h); 242 SDL_SetRenderTarget(state->renderers[i], state->targets[i]); 243 } 244 } 245 246 for (i = 0; i < state->num_windows; ++i) { 247 SDL_Renderer *renderer = state->renderers[i]; 248 SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF); 249 SDL_RenderClear(renderer); 250 } 251 252 /* Main render loop */ 253 frames = 0; 254 then = SDL_GetTicks(); 255 done = 0; 256 j = 0; 257 258 #ifdef __EMSCRIPTEN__ 259 wait_start = SDL_GetTicks(); 260 emscripten_set_main_loop(loop, 0, 1); 261 #else 262 while (!done) { 263 ++frames; 264 loop(); 265 SDL_Delay(1000); 266 } 267 #endif 268 269 /* Print out some timing information */ 270 now = SDL_GetTicks(); 271 if (now > then) { 272 double fps = ((double) frames * 1000) / (now - then); 273 SDL_Log("%2.2f frames per second\n", fps); 274 } 275 quit(0); 276 return 0; 277 } 278 279 /* vi: set ts=4 sw=4 expandtab: */