1 | /* |
2 | Copyright (C) 1997-2021 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 | |
13 | /* Simple program: picks the offscreen backend and renders each frame to a bmp */ |
14 | |
15 | #include <stdlib.h> |
16 | #include <stdio.h> |
17 | #include <time.h> |
18 | |
19 | #ifdef __EMSCRIPTEN__ |
20 | #include <emscripten/emscripten.h> |
21 | #endif |
22 | |
23 | #include "SDL.h" |
24 | #include "SDL_stdinc.h" |
25 | #include "SDL_opengl.h" |
26 | |
27 | static SDL_Renderer *renderer = NULL; |
28 | static SDL_Window *window = NULL; |
29 | static int done = SDL_FALSE; |
30 | static int frame_number = 0; |
31 | static int width = 640; |
32 | static int height = 480; |
33 | static int max_frames = 200; |
34 | |
35 | void |
36 | draw() |
37 | { |
38 | SDL_Rect Rect; |
39 | |
40 | SDL_SetRenderDrawColor(renderer, 0x10, 0x9A, 0xCE, 0xFF); |
41 | SDL_RenderClear(renderer); |
42 | |
43 | /* Grow based on the frame just to show a difference per frame of the region */ |
44 | Rect.x = 0; |
45 | Rect.y = 0; |
46 | Rect.w = (frame_number * 2) % width; |
47 | Rect.h = (frame_number * 2) % height; |
48 | SDL_SetRenderDrawColor(renderer, 0xFF, 0x10, 0x21, 0xFF); |
49 | SDL_RenderFillRect(renderer, &Rect); |
50 | |
51 | SDL_RenderPresent(renderer); |
52 | } |
53 | |
54 | void |
55 | save_surface_to_bmp() |
56 | { |
57 | SDL_Surface* surface; |
58 | Uint32 r_mask, g_mask, b_mask, a_mask; |
59 | Uint32 pixel_format; |
60 | char file[128]; |
61 | int bbp; |
62 | |
63 | pixel_format = SDL_GetWindowPixelFormat(window); |
64 | SDL_PixelFormatEnumToMasks(pixel_format, &bbp, &r_mask, &g_mask, &b_mask, &a_mask); |
65 | |
66 | surface = SDL_CreateRGBSurface(0, width, height, bbp, r_mask, g_mask, b_mask, a_mask); |
67 | SDL_RenderReadPixels(renderer, NULL, pixel_format, (void*)surface->pixels, surface->pitch); |
68 | |
69 | SDL_snprintf(file, sizeof(file), "SDL_window%d-%8.8d.bmp" , |
70 | SDL_GetWindowID(window), ++frame_number); |
71 | |
72 | SDL_SaveBMP(surface, file); |
73 | SDL_FreeSurface(surface); |
74 | } |
75 | |
76 | void |
77 | loop() |
78 | { |
79 | SDL_Event event; |
80 | |
81 | /* Check for events */ |
82 | while (SDL_PollEvent(&event)) { |
83 | switch (event.type) { |
84 | case SDL_QUIT: |
85 | done = SDL_TRUE; |
86 | break; |
87 | } |
88 | } |
89 | |
90 | draw(); |
91 | save_surface_to_bmp(); |
92 | |
93 | #ifdef __EMSCRIPTEN__ |
94 | if (done) { |
95 | emscripten_cancel_main_loop(); |
96 | } |
97 | #endif |
98 | } |
99 | |
100 | int |
101 | main(int argc, char *argv[]) |
102 | { |
103 | Uint32 then, now, frames; |
104 | |
105 | /* Enable standard application logging */ |
106 | SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); |
107 | |
108 | /* Force the offscreen renderer, if it cannot be created then fail out */ |
109 | if (SDL_VideoInit("offscreen" ) < 0) { |
110 | SDL_Log("Couldn't initialize the offscreen video driver: %s\n" , |
111 | SDL_GetError()); |
112 | return SDL_FALSE; |
113 | } |
114 | |
115 | /* If OPENGL fails to init it will fallback to using a framebuffer for rendering */ |
116 | window = SDL_CreateWindow("Offscreen Test" , |
117 | SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, |
118 | width, height, 0); |
119 | |
120 | if (!window) { |
121 | SDL_Log("Couldn't create window: %s\n" , |
122 | SDL_GetError()); |
123 | return SDL_FALSE; |
124 | } |
125 | |
126 | renderer = SDL_CreateRenderer(window, -1, 0); |
127 | |
128 | if (!renderer) { |
129 | SDL_Log("Couldn't create renderer: %s\n" , |
130 | SDL_GetError()); |
131 | return SDL_FALSE; |
132 | } |
133 | |
134 | SDL_RenderClear(renderer); |
135 | |
136 | srand((unsigned int)time(NULL)); |
137 | |
138 | /* Main render loop */ |
139 | frames = 0; |
140 | then = SDL_GetTicks(); |
141 | done = 0; |
142 | |
143 | SDL_Log("Rendering %i frames offscreen\n" , max_frames); |
144 | |
145 | #ifdef __EMSCRIPTEN__ |
146 | emscripten_set_main_loop(loop, 0, 1); |
147 | #else |
148 | while (!done && frames < max_frames) { |
149 | ++frames; |
150 | loop(); |
151 | |
152 | /* Print out some timing information, along with remaining frames */ |
153 | if (frames % (max_frames / 10) == 0) { |
154 | now = SDL_GetTicks(); |
155 | if (now > then) { |
156 | double fps = ((double) frames * 1000) / (now - then); |
157 | SDL_Log("Frames remaining: %i rendering at %2.2f frames per second\n" , max_frames - frames, fps); |
158 | } |
159 | } |
160 | } |
161 | #endif |
162 | |
163 | SDL_DestroyRenderer(renderer); |
164 | SDL_DestroyWindow(window); |
165 | SDL_Quit(); |
166 | |
167 | return 0; |
168 | } |
169 | |
170 | /* vi: set ts=4 sw=4 expandtab: */ |
171 | |