]> git.lizzy.rs Git - dragonblocks_alpha.git/blob - src/client/scene.c
cbacfea737e1a5c5d28acf15ec9d8ed4e9bf88b7
[dragonblocks_alpha.git] / src / client / scene.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include "client/camera.h"
4 #include "client/client.h"
5 #include "client/frustum.h"
6 #include "client/scene.h"
7 #include "client/shader.h"
8 #include "day.h"
9 #include "util.h"
10
11 struct Scene scene;
12
13 bool scene_init()
14 {
15         scene.objects = list_create(NULL),
16         pthread_mutex_init(&scene.mtx, NULL);
17
18         glGetIntegerv(GL_MAX_TEXTURE_UNITS, &scene.max_texture_units);
19
20         char max_texture_units_def[BUFSIZ];
21         sprintf(max_texture_units_def, "#define MAX_TEXTURE_UNITS %d\n", scene.max_texture_units);
22
23         if (! shader_program_create(RESSOURCEPATH "shaders/3d", &scene.prog, max_texture_units_def)) {
24                 fprintf(stderr, "Failed to create 3D shader program\n");
25                 return false;
26         }
27
28         scene.loc_model = glGetUniformLocation(scene.prog, "model");
29         scene.loc_VP = glGetUniformLocation(scene.prog, "VP");
30         scene.loc_daylight = glGetUniformLocation(scene.prog, "daylight");
31         scene.loc_lightDir = glGetUniformLocation(scene.prog, "lightDir");
32         scene.loc_cameraPos = glGetUniformLocation(scene.prog, "cameraPos");
33
34         GLint texture_indices[scene.max_texture_units];
35         for (GLint i = 0; i < scene.max_texture_units; i++)
36                 texture_indices[i] = i;
37
38         glProgramUniform1iv(scene.prog, glGetUniformLocation(scene.prog, "textures"), scene.max_texture_units, texture_indices);
39
40         scene.fov = 86.1f;
41         scene.render_distance = 255.0f + 32.0f;
42
43         return true;
44 }
45
46 static void list_delete_object(void *key, unused void *value, unused void *arg)
47 {
48         object_delete(key);
49 }
50
51 void scene_deinit()
52 {
53         list_clear_func(&scene.objects, &list_delete_object, NULL);
54         pthread_mutex_destroy(&scene.mtx);
55         glDeleteProgram(scene.prog);
56 }
57
58 void scene_add_object(Object *obj)
59 {
60         pthread_mutex_lock(&scene.mtx);
61         list_put(&scene.objects, obj, NULL);
62         pthread_mutex_unlock(&scene.mtx);
63 }
64
65 void scene_render(f64 dtime)
66 {
67 #pragma GCC diagnostic push
68 #pragma GCC diagnostic ignored "-Wpedantic"
69         mat4x4_mul(scene.VP, scene.projection, camera.view);
70
71         vec4 base_sunlight_dir = {0.0f, 0.0f, -1.0f, 1.0f};
72         vec4 sunlight_dir;
73         mat4x4 sunlight_mat;
74         mat4x4_identity(sunlight_mat);
75         mat4x4_rotate(sunlight_mat, sunlight_mat, 1.0f, 0.0f, 0.0f, get_sun_angle() + M_PI / 2.0f);
76         mat4x4_mul_vec4(sunlight_dir, sunlight_mat, base_sunlight_dir);
77 #pragma GCC diagnostic pop
78
79         frustum_update(scene.VP);
80
81         glUseProgram(scene.prog);
82         glUniformMatrix4fv(scene.loc_VP, 1, GL_FALSE, scene.VP[0]);
83         glUniform3f(scene.loc_lightDir, sunlight_dir[0], sunlight_dir[1], sunlight_dir[2]);
84         glUniform3f(scene.loc_cameraPos, camera.eye[0], camera.eye[1], camera.eye[2]);
85         glUniform1f(scene.loc_daylight, get_daylight());
86
87         for (ListPair **pairptr = &scene.objects.first; *pairptr != NULL; ) {
88                 ListPair *pair = *pairptr;
89                 Object *obj = pair->key;
90                 if (obj->remove) {
91                         pthread_mutex_lock(&scene.mtx);
92                         *pairptr = pair->next;
93                         pthread_mutex_unlock(&scene.mtx);
94                         free(pair);
95                         object_delete(obj);
96                 } else {
97                         object_render(obj, dtime);
98                         pairptr = &pair->next;
99                 }
100         }
101 }
102
103 void scene_on_resize(int width, int height)
104 {
105         mat4x4_perspective(scene.projection, scene.fov / 180.0f * M_PI, (float) width / (float) height, 0.01f, scene.render_distance);
106 }
107
108 GLuint scene_get_max_texture_units()
109 {
110         return scene.max_texture_units;
111 }