1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
#include <GLFW/glfw3.h>
#include <threads.h>
#include "voxel.h"
#include "window.h"
World world;
Camera camera;
void sleep(double seconds)
{
struct timespec req, rem;
req.tv_sec = seconds;
req.tv_nsec = 0;
if (seconds < 0)
return;
while (thrd_sleep(&req, &rem) == thrd_error)
req = rem;
}
/// handles rendering
VOXEL_RESULT render_main(void *)
{
Renderer renderer;
if (window_init_gl() != VOXEL_OK)
return VOXEL_ERROR;
if (renderer_init(&renderer) != VOXEL_OK)
return VOXEL_ERROR;
while (!window_closed()) {
if (window.resize) {
glViewport(0, 0, window.width, window.height);
window.resize = false;
}
renderer_start(&renderer, &camera);
world_render(&world, &renderer);
renderer_stop(&renderer);
window_swap();
}
renderer_free(&renderer);
return VOXEL_OK;
}
#define TPS 20
/// handles game logic
VOXEL_RESULT logic_main(void *)
{
double last_tick, next_tick;
last_tick = 0;
next_tick = 0;
while (!window_closed()) {
world_update(&world, &camera);
next_tick = last_tick + (1.0 / TPS);
sleep(next_tick - last_tick);
last_tick = next_tick;
}
return VOXEL_OK;
}
/// handles user input
VOXEL_RESULT input_main(void *)
{
double last_tick, next_tick;
last_tick = 0;
next_tick = 0;
while (!window_closed()) {
window_update();
if (key_down(GLFW_KEY_ESCAPE)) {
window.close = true;
break;
}
camera_update(&camera);
next_tick = last_tick + (1.0 / TPS);
sleep(next_tick - last_tick);
last_tick = next_tick;
}
return VOXEL_OK;
}
VOXEL_RESULT main(void)
{
thrd_t render_thread, logic_thread, input_thread;
if (window_init() != VOXEL_OK)
return VOXEL_ERROR;
camera_init(&camera);
world_init(&world, 0);
thrd_create(&logic_thread, logic_main, NULL);
thrd_create(&input_thread, input_main, NULL);
thrd_create(&render_thread, render_main, NULL);
thrd_join(logic_thread, NULL);
thrd_join(input_thread, NULL);
thrd_join(render_thread, NULL);
world_free(&world);
window_close();
return VOXEL_OK;
}
|