Blender V4.5
window.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include <cstdio>
6#include <cstdlib>
7
8#include "app/opengl/window.h"
9
10#include "util/string.h"
11#include "util/thread.h"
12#include "util/version.h"
13
14#include <SDL.h>
15#include <epoxy/gl.h>
16
18
19/* structs */
20
21struct Window {
28
29 bool first_display = true;
30 bool redraw = false;
31
32 int mouseX = 0, mouseY = 0;
33 int mouseBut0 = 0, mouseBut2 = 0;
34
35 int width = 0, height = 0;
36
37 SDL_Window *window = nullptr;
38 SDL_GLContext gl_context = nullptr;
40} V;
41
42/* public */
43
44static void window_display_text(int /*x*/, int /*y*/, const char *text)
45{
46/* Not currently supported, need to add text rendering support. */
47#if 0
48 const char *c;
49
50 glRasterPos3f(x, y, 0);
51 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
52
53 printf("display %s\n", text);
54
55 for (c = text; *c != '\0'; c++) {
56 const uint8_t *bitmap = helvetica10_character_map[*c];
57 glBitmap(bitmap[0],
58 helvetica10_height,
59 helvetica10_x_offset,
60 helvetica10_y_offset,
61 bitmap[0],
62 0.0f,
63 bitmap + 1);
64 }
65#else
66 static string last_text;
67
68 if (text != last_text) {
69 printf("%s\n", text);
70 last_text = text;
71 }
72#endif
73}
74
75void window_display_info(const char *info)
76{
77 const int height = 20;
78
79#if 0
80 glEnable(GL_BLEND);
81 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
82 glColor4f(0.1f, 0.1f, 0.1f, 0.8f);
83 glRectf(0.0f, V.height - height, V.width, V.height);
84 glDisable(GL_BLEND);
85
86 glColor3f(0.5f, 0.5f, 0.5f);
87#endif
88
89 window_display_text(10, 7 + V.height - height, info);
90
91#if 0
92 glColor3f(1.0f, 1.0f, 1.0f);
93#endif
94}
95
97{
98 const int w = (int)((float)V.width / 1.15f);
99 const int h = (int)((float)V.height / 1.15f);
100
101 const int x1 = (V.width - w) / 2;
102#if 0
103 const int x2 = x1 + w;
104#endif
105
106 const int y1 = (V.height - h) / 2;
107 const int y2 = y1 + h;
108
109#if 0
110 glEnable(GL_BLEND);
111 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
112 glColor4f(0.5f, 0.5f, 0.5f, 0.8f);
113 glRectf(x1, y1, x2, y2);
114 glDisable(GL_BLEND);
115
116 glColor3f(0.8f, 0.8f, 0.8f);
117#endif
118
119 const string info = string("Cycles Renderer ") + CYCLES_VERSION_STRING;
120
121 window_display_text(x1 + 20, y2 - 20, info.c_str());
122 window_display_text(x1 + 20, y2 - 40, "(C) 2011-2016 Blender Foundation");
123 window_display_text(x1 + 20, y2 - 80, "Controls:");
124 window_display_text(x1 + 20, y2 - 100, "h: Info/Help");
125 window_display_text(x1 + 20, y2 - 120, "r: Reset");
126 window_display_text(x1 + 20, y2 - 140, "p: Pause");
127 window_display_text(x1 + 20, y2 - 160, "esc: Cancel");
128 window_display_text(x1 + 20, y2 - 180, "q: Quit program");
129
130 window_display_text(x1 + 20, y2 - 210, "i: Interactive mode");
131 window_display_text(x1 + 20, y2 - 230, "Left mouse: Move camera");
132 window_display_text(x1 + 20, y2 - 250, "Right mouse: Rotate camera");
133 window_display_text(x1 + 20, y2 - 270, "W/A/S/D: Move camera");
134 window_display_text(x1 + 20, y2 - 290, "0/1/2/3: Set max bounces");
135
136#if 0
137 glColor3f(1.0f, 1.0f, 1.0f);
138#endif
139}
140
141static void window_display()
142{
143 if (V.first_display) {
144 if (V.initf) {
145 V.initf();
146 }
147 if (V.exitf) {
148 atexit(V.exitf);
149 }
150
151 V.first_display = false;
152 }
153
155
156 glViewport(0, 0, V.width, V.height);
157
158 glMatrixMode(GL_PROJECTION);
159 glLoadIdentity();
160
161 glMatrixMode(GL_MODELVIEW);
162 glLoadIdentity();
163
164 glClearColor(0.05f, 0.05f, 0.05f, 0.0f);
165 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
166
167 glMatrixMode(GL_PROJECTION);
168 glLoadIdentity();
169 glOrtho(0, V.width, 0, V.height, -1, 1);
170
171 glMatrixMode(GL_MODELVIEW);
172 glLoadIdentity();
173
174 glRasterPos3f(0, 0, 0);
175
176 if (V.display) {
177 V.display();
178 }
179
180 SDL_GL_SwapWindow(V.window);
182}
183
184static void window_reshape(const int width, const int height)
185{
186 if (V.width != width || V.height != height) {
187 if (V.resize) {
188 V.resize(width, height);
189 }
190 }
191
192 V.width = width;
193 V.height = height;
194}
195
196static bool window_keyboard(unsigned char key)
197{
198 if (V.keyboard) {
199 V.keyboard(key);
200 }
201
202 if (key == 'q') {
203 if (V.exitf) {
204 V.exitf();
205 }
206 return true;
207 }
208
209 return false;
210}
211
212static void window_mouse(const int button, const int state, const int x, int y)
213{
214 if (button == SDL_BUTTON_LEFT) {
215 if (state == SDL_MOUSEBUTTONDOWN) {
216 V.mouseX = x;
217 V.mouseY = y;
218 V.mouseBut0 = 1;
219 }
220 else if (state == SDL_MOUSEBUTTONUP) {
221 V.mouseBut0 = 0;
222 }
223 }
224 else if (button == SDL_BUTTON_RIGHT) {
225 if (state == SDL_MOUSEBUTTONDOWN) {
226 V.mouseX = x;
227 V.mouseY = y;
228 V.mouseBut2 = 1;
229 }
230 else if (state == SDL_MOUSEBUTTONUP) {
231 V.mouseBut2 = 0;
232 }
233 }
234}
235
236static void window_motion(const int x, const int y)
237{
238 const int but = V.mouseBut0 ? 0 : 2;
239 const int distX = x - V.mouseX;
240 const int distY = y - V.mouseY;
241
242 if (V.motion) {
243 V.motion(distX, distY, but);
244 }
245
246 V.mouseX = x;
247 V.mouseY = y;
248}
249
251{
252 V.gl_context_mutex.lock();
253 SDL_GL_MakeCurrent(V.window, V.gl_context);
254 return true;
255}
256
258{
259 SDL_GL_MakeCurrent(V.window, nullptr);
260 V.gl_context_mutex.unlock();
261}
262
263void window_main_loop(const char *title,
264 const int width,
265 const int height,
267 WindowExitFunc exitf,
268 WindowResizeFunc resize,
269 WindowDisplayFunc display,
270 WindowKeyboardFunc keyboard,
271 WindowMotionFunc motion)
272{
273 V.width = width;
274 V.height = height;
275 V.first_display = true;
276 V.redraw = false;
277 V.initf = initf;
278 V.exitf = exitf;
279 V.resize = resize;
280 V.display = display;
281 V.keyboard = keyboard;
282 V.motion = motion;
283
284 SDL_Init(SDL_INIT_VIDEO);
285 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
286 SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
287 V.window = SDL_CreateWindow(title,
288 SDL_WINDOWPOS_UNDEFINED,
289 SDL_WINDOWPOS_UNDEFINED,
290 width,
291 height,
292 SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
293 if (V.window == nullptr) {
294 fprintf(stderr, "Failed to create window: %s\n", SDL_GetError());
295 return;
296 }
297
298 SDL_RaiseWindow(V.window);
299
300 V.gl_context = SDL_GL_CreateContext(V.window);
301 SDL_GL_MakeCurrent(V.window, nullptr);
302
303 window_reshape(width, height);
305
306 while (true) {
307 bool quit = false;
308 SDL_Event event;
309 while (!quit && SDL_PollEvent(&event)) {
310 if (event.type == SDL_TEXTINPUT) {
311 quit = window_keyboard(event.text.text[0]);
312 }
313 else if (event.type == SDL_MOUSEMOTION) {
314 window_motion(event.motion.x, event.motion.y);
315 }
316 else if (event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP) {
317 window_mouse(event.button.button, event.button.state, event.button.x, event.button.y);
318 }
319 else if (event.type == SDL_WINDOWEVENT) {
320 if (event.window.event == SDL_WINDOWEVENT_RESIZED ||
321 event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
322 {
323 window_reshape(event.window.data1, event.window.data2);
324 }
325 }
326 else if (event.type == SDL_QUIT) {
327 if (V.exitf) {
328 V.exitf();
329 }
330 quit = true;
331 }
332 }
333
334 if (quit) {
335 break;
336 }
337
338 if (V.redraw) {
339 V.redraw = false;
341 }
342
343 SDL_WaitEventTimeout(nullptr, 100);
344 }
345
346 SDL_GL_DeleteContext(V.gl_context);
347 SDL_DestroyWindow(V.window);
348 SDL_Quit();
349}
350
352{
353 V.redraw = true;
354}
355
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
#define CCL_NAMESPACE_END
#define printf(...)
static ulong state[N]
static int initf
WindowKeyboardFunc keyboard
Definition window.cpp:26
WindowResizeFunc resize
Definition window.cpp:24
int mouseBut2
Definition window.cpp:33
WindowMotionFunc motion
Definition window.cpp:27
WindowDisplayFunc display
Definition window.cpp:25
WindowExitFunc exitf
Definition window.cpp:23
SDL_GLContext gl_context
Definition window.cpp:38
thread_mutex gl_context_mutex
Definition window.cpp:39
int mouseY
Definition window.cpp:32
WindowInitFunc initf
Definition window.cpp:22
bool redraw
Definition window.cpp:30
int mouseBut0
Definition window.cpp:33
int mouseX
Definition window.cpp:32
bool first_display
Definition window.cpp:29
SDL_Window * window
Definition window.cpp:37
int height
Definition window.cpp:35
int width
Definition window.cpp:35
std::mutex thread_mutex
Definition thread.h:27
#define CYCLES_VERSION_STRING
Definition version.h:19
static void window_motion(const int x, const int y)
Definition window.cpp:236
void window_opengl_context_disable()
Definition window.cpp:257
bool window_opengl_context_enable()
Definition window.cpp:250
void window_display_info(const char *info)
Definition window.cpp:75
static void window_mouse(const int button, const int state, const int x, int y)
Definition window.cpp:212
void window_main_loop(const char *title, const int width, const int height, WindowInitFunc initf, WindowExitFunc exitf, WindowResizeFunc resize, WindowDisplayFunc display, WindowKeyboardFunc keyboard, WindowMotionFunc motion)
Definition window.cpp:263
static void window_display()
Definition window.cpp:141
static void window_reshape(const int width, const int height)
Definition window.cpp:184
CCL_NAMESPACE_BEGIN struct Window V
static void window_display_text(int, int, const char *text)
Definition window.cpp:44
void window_redraw()
Definition window.cpp:351
static bool window_keyboard(unsigned char key)
Definition window.cpp:196
void window_display_help()
Definition window.cpp:96
void(*)(unsigned char) WindowKeyboardFunc
Definition window.h:16
void(*)() WindowInitFunc
Definition window.h:12
void(*)() WindowExitFunc
Definition window.h:13
void(*)(int, int, int) WindowMotionFunc
Definition window.h:17
void(*)() WindowDisplayFunc
Definition window.h:15
void(*)(int, int) WindowResizeFunc
Definition window.h:14