1 #define STB_IMAGE_WRITE_IMPLEMENTATION
4 #include <GLFW/glfw3.h>
5 #include <stb/stb_image_write.h>
8 #include "client/camera.h"
9 #include "client/client.h"
10 #include "client/client_entity.h"
11 #include "client/client_node.h"
12 #include "client/client_player.h"
13 #include "client/client_terrain.h"
14 #include "client/debug_menu.h"
15 #include "client/font.h"
16 #include "client/frustum.h"
17 #include "client/game.h"
18 #include "client/gl_debug.h"
19 #include "client/gui.h"
20 #include "client/input.h"
21 #include "client/interact.h"
22 #include "client/sky.h"
23 #include "client/window.h"
25 #include "interrupt.h"
29 static void crosshair_init()
31 gui_add(NULL, (GUIElementDefinition) {
36 .align = {0.5f, 0.5f},
37 .scale = {1.0f, 1.0f},
38 .scale_type = SCALE_IMAGE,
39 .affect_parent_scale = false,
41 .image = texture_load(RESSOURCE_PATH "textures/crosshair.png", false),
42 .text_color = {0.0f, 0.0f, 0.0f, 0.0f},
43 .bg_color = {0.0f, 0.0f, 0.0f, 0.0f},
47 static void render(f64 dtime)
49 glEnable(GL_DEPTH_TEST); GL_DEBUG
50 glEnable(GL_BLEND); GL_DEBUG
51 glEnable(GL_MULTISAMPLE); GL_DEBUG
52 glEnable(GL_CULL_FACE); GL_DEBUG
54 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GL_DEBUG
55 glCullFace(GL_BACK); GL_DEBUG
56 glFrontFace(GL_CCW); GL_DEBUG
58 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); GL_DEBUG
62 client_entity_gfx_update();
65 model_scene_render(dtime);
70 static void game_loop()
72 f64 fps_update_timer = 1.0f;
73 unsigned int frames = 0;
75 struct timespec ts, ts_old;
76 clock_gettime(CLOCK_REALTIME, &ts_old);
78 while (!glfwWindowShouldClose(window.handle) && !interrupt.set) {
79 clock_gettime(CLOCK_REALTIME, &ts);
80 f64 dtime = (f64) (ts.tv_sec - ts_old.tv_sec) + (f64) (ts.tv_nsec - ts_old.tv_nsec) / 1.0e9;
83 if ((fps_update_timer -= dtime) <= 0.0) {
84 debug_menu_changed(ENTRY_FPS);
86 fps_update_timer += 1.0;
93 client_player_tick(dtime);
96 debug_menu_changed(ENTRY_TIME);
97 debug_menu_changed(ENTRY_DAYLIGHT);
98 debug_menu_changed(ENTRY_SUN_ANGLE);
103 glfwSwapBuffers(window.handle);
108 bool game(Flag *gfx_init)
121 if (!terrain_gfx_init())
124 if (!client_entity_gfx_init())
127 client_player_gfx_init();
129 if (!interact_init())
133 client_terrain_start();
135 camera_set_position((v3f32) {0.0f, 0.0f, 0.0f});
136 camera_set_angle(0.0f, 0.0f);
148 client_terrain_stop();
154 terrain_gfx_deinit();
155 client_entity_gfx_deinit();
156 client_player_gfx_deinit();
162 char *game_take_screenshot()
164 // renderbuffer for depth & stencil buffer
166 glGenRenderbuffers(1, &rbo); GL_DEBUG
167 glBindRenderbuffer(GL_RENDERBUFFER, rbo); GL_DEBUG
168 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_DEPTH24_STENCIL8, window.width, window.height); GL_DEBUG
170 // 2 textures, one with AA, one without
173 glGenTextures(2, txos); GL_DEBUG
175 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, txos[0]); GL_DEBUG
176 glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 8, GL_RGB, window.width, window.height, GL_TRUE); GL_DEBUG
178 glBindTexture(GL_TEXTURE_2D, txos[1]); GL_DEBUG
179 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, window.width, window.height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); GL_DEBUG
181 // 2 framebuffers, one with AA, one without
184 glGenFramebuffers(2, fbos); GL_DEBUG
186 glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]); GL_DEBUG
187 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, txos[0], 0); GL_DEBUG
188 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); GL_DEBUG
190 glBindFramebuffer(GL_FRAMEBUFFER, fbos[1]); GL_DEBUG
191 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, txos[1], 0); GL_DEBUG
194 glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]); GL_DEBUG
196 glBindFramebuffer(GL_FRAMEBUFFER, 0); GL_DEBUG
198 // blit AA-buffer into no-AA buffer
199 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbos[0]); GL_DEBUG
200 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[1]); GL_DEBUG
201 glBlitFramebuffer(0, 0, window.width, window.height, 0, 0, window.width, window.height, GL_COLOR_BUFFER_BIT, GL_NEAREST); GL_DEBUG
204 GLubyte data[window.width * window.height * 3];
205 glBindFramebuffer(GL_FRAMEBUFFER, fbos[1]); GL_DEBUG
206 glPixelStorei(GL_PACK_ALIGNMENT, 1); GL_DEBUG
207 glReadPixels(0, 0, window.width, window.height, GL_RGB, GL_UNSIGNED_BYTE, data); GL_DEBUG
210 char filename[BUFSIZ];
211 time_t timep = time(0);
212 strftime(filename, BUFSIZ, "screenshot-%Y-%m-%d-%H:%M:%S.png", localtime(&timep));
215 stbi_flip_vertically_on_write(true);
216 stbi_write_png(filename, window.width, window.height, 3, data, window.width * 3);
219 glDeleteRenderbuffers(1, &rbo); GL_DEBUG
220 glDeleteTextures(2, txos); GL_DEBUG
221 glDeleteFramebuffers(2, fbos); GL_DEBUG
223 return strdup(filename);