5 #include <GLFW/glfw3.h>
6 #define STB_IMAGE_WRITE_IMPLEMENTATION
7 #include <stb/stb_image_write.h>
8 #include "client/camera.h"
9 #include "client/client.h"
10 #include "client/client_map.h"
11 #include "client/client_node.h"
12 #include "client/client_player.h"
13 #include "client/debug_menu.h"
14 #include "client/font.h"
15 #include "client/gui.h"
16 #include "client/input.h"
17 #include "client/sky.h"
18 #include "client/window.h"
20 #include "signal_handlers.h"
22 int window_width, window_height;
24 static void crosshair_init()
26 gui_add(&gui_root, (GUIElementDefinition) {
31 .align = {0.5f, 0.5f},
32 .scale = {1.0f, 1.0f},
33 .scale_type = GST_IMAGE,
34 .affect_parent_scale = false,
36 .image = texture_get(RESSOURCEPATH "textures/crosshair.png"),
37 .text_color = (v4f32) {0.0f, 0.0f, 0.0f, 0.0f},
38 .bg_color = (v4f32) {0.0f, 0.0f, 0.0f, 0.0f},
44 glEnable(GL_DEPTH_TEST);
45 glEnable(GL_ALPHA_TEST);
47 glEnable(GL_MULTISAMPLE);
48 glEnable(GL_CULL_FACE);
50 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
51 glAlphaFunc(GL_GREATER, 0.0f);
54 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
58 glDisable(GL_CULL_FACE);
61 glDisable(GL_DEPTH_TEST);
65 static void game_loop(Client *client)
67 f64 fps_update_timer = 1.0f;
70 struct timespec ts, ts_old;
71 clock_gettime(CLOCK_REALTIME, &ts_old);
73 while (! glfwWindowShouldClose(window.handle) && client->state != CS_DISCONNECTED && ! interrupted) {
74 clock_gettime(CLOCK_REALTIME, &ts);
75 f64 dtime = (f64) (ts.tv_sec - ts_old.tv_sec) + (f64) (ts.tv_nsec - ts_old.tv_nsec) / 1.0e9;
78 if ((fps_update_timer -= dtime) <= 0.0) {
79 debug_menu_update_fps(frames);
80 fps_update_timer += 1.0;
87 client_player_tick(dtime);
89 debug_menu_update_time();
90 debug_menu_update_daylight();
91 debug_menu_update_sun_angle();
95 glfwSwapBuffers(window.handle);
100 bool game(Client *client)
105 if (! window_init(window_width, window_height))
114 scene_on_resize(window_width, window_height);
122 camera_set_position((v3f32) {0.0f, 0.0f, 0.0f});
123 camera_set_angle(0.0f, 0.0f);
128 gui_on_resize(window_width, window_height);
132 debug_menu_update_fps(0);
133 debug_menu_update_version();
134 debug_menu_update_seed();
135 debug_menu_update_flight();
136 debug_menu_update_collision();
137 debug_menu_update_timelapse();
138 debug_menu_update_fullscreen();
139 debug_menu_update_opengl();
140 debug_menu_update_gpu();
146 client_player_add_to_scene();
160 void take_screenshot()
162 // renderbuffer for depth & stencil buffer
164 glGenRenderbuffers(1, &RBO);
165 glBindRenderbuffer(GL_RENDERBUFFER, RBO);
166 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_DEPTH24_STENCIL8, window_width, window_height);
168 // 2 textures, one with AA, one without
171 glGenTextures(2, textures);
173 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textures[0]);
174 glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 8, GL_RGB, window_width, window_height, GL_TRUE);
176 glBindTexture(GL_TEXTURE_2D, textures[1]);
177 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, window_width, window_height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
179 // 2 framebuffers, one with AA, one without
182 glGenFramebuffers(2, FBOs);
184 glBindFramebuffer(GL_FRAMEBUFFER, FBOs[0]);
185 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, textures[0], 0);
186 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, RBO);
188 glBindFramebuffer(GL_FRAMEBUFFER, FBOs[1]);
189 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
192 glBindFramebuffer(GL_FRAMEBUFFER, FBOs[0]);
194 glBindFramebuffer(GL_FRAMEBUFFER, 0);
196 // blit AA-buffer into no-AA buffer
197 glBindFramebuffer(GL_READ_FRAMEBUFFER, FBOs[0]);
198 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBOs[1]);
199 glBlitFramebuffer(0, 0, window_width, window_height, 0, 0, window_width, window_height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
202 GLubyte data[window_width * window_height * 3];
203 glBindFramebuffer(GL_FRAMEBUFFER, FBOs[1]);
204 glPixelStorei(GL_PACK_ALIGNMENT, 1);
205 glReadPixels(0, 0, window_width, window_height, GL_RGB, GL_UNSIGNED_BYTE, data);
208 char filename[BUFSIZ];
209 time_t timep = time(0);
210 strftime(filename, BUFSIZ, "screenshot-%Y-%m-%d-%H:%M:%S.png", localtime(&timep));
213 stbi_flip_vertically_on_write(true);
214 stbi_write_png(filename, window_width, window_height, 3, data, window_width * 3);
217 glDeleteRenderbuffers(1, &RBO);
218 glDeleteTextures(2, textures);
219 glDeleteFramebuffers(2, FBOs);
222 void game_on_resize(int width, int height)
224 window_width = width;
225 window_height = height;