]> git.lizzy.rs Git - dragonblocks_alpha.git/blob - src/client/sky.c
e648d8d5cea138abc828d1bc605f21a39d8889da
[dragonblocks_alpha.git] / src / client / sky.c
1 #include <stdio.h>
2 #include <GL/glew.h>
3 #include <GL/gl.h>
4 #include "client/camera.h"
5 #include "client/client.h"
6 #include "client/cube.h"
7 #include "client/gl_debug.h"
8 #include "client/mesh.h"
9 #include "client/shader.h"
10 #include "client/sky.h"
11 #include "client/texture.h"
12 #include "client/window.h"
13 #include "day.h"
14
15 static GLuint sun_prog;
16 static GLint sun_loc_MVP;
17 static GLuint sun_texture;
18 typedef struct {
19         v3f32 position;
20         v2f32 textureCoordinates;
21 } __attribute__((packed)) SunVertex;
22 static Mesh sun_mesh = {
23         .layout = &(VertexLayout) {
24                 .attributes = (VertexAttribute[]) {
25                         {GL_FLOAT, 3, sizeof(v3f32)}, // position
26                         {GL_FLOAT, 2, sizeof(v2f32)}, // textureCoordinates
27                 },
28                 .count = 2,
29                 .size = sizeof(SunVertex),
30         },
31         .vao = 0,
32         .vbo = 0,
33         .data = (SunVertex[]) {
34                 {{-0.5, -0.5, +0.0}, {+0.0, +0.0}},
35                 {{+0.5, -0.5, +0.0}, {+1.0, +0.0}},
36                 {{+0.5, +0.5, +0.0}, {+1.0, +1.0}},
37                 {{+0.5, +0.5, +0.0}, {+1.0, +1.0}},
38                 {{-0.5, +0.5, +0.0}, {+0.0, +1.0}},
39                 {{-0.5, -0.5, +0.0}, {+0.0, +0.0}},
40         },
41         .count = 6,
42         .free_data = false,
43 };
44
45 static GLuint skybox_prog;
46 static GLint skybox_loc_VP;
47 static GLint skybox_loc_daylight;
48 static GLuint skybox_texture_day;
49 static GLuint skybox_texture_night;
50 typedef struct {
51         v3f32 position;
52 } __attribute__((packed)) SkyboxVertex;
53 static Mesh skybox_mesh = {
54         .layout = &(VertexLayout) {
55                 .attributes = (VertexAttribute[]) {
56                         {GL_FLOAT, 3, sizeof(v3f32)}, // position
57                 },
58                 .count = 1,
59                 .size = sizeof(SkyboxVertex),
60         },
61         .vao = 0,
62         .vbo = 0,
63         .data = NULL,
64         .count = 36,
65         .free_data = false,
66 };
67
68 static GLuint clouds_prog;
69 static GLint clouds_loc_VP;
70 static GLint clouds_loc_daylight;
71 static Mesh clouds_mesh;
72
73 bool sky_init()
74 {
75         clouds_mesh = skybox_mesh;
76         SkyboxVertex skybox_vertices[6][6], clouds_vertices[6][6];
77         for (int f = 0; f < 6; f++) {
78                 for (int v = 0; v < 6; v++) {
79                         skybox_vertices[f][v].position =
80                                 clouds_vertices[f][v].position =
81                                 cube_vertices[f][v].position;
82
83                         clouds_vertices[f][v].position.y = fmax(clouds_vertices[f][v].position.y, 0.0);
84                 }
85         }
86
87         // skybox
88
89         if (!shader_program_create(RESSOURCE_PATH "shaders/sky/skybox", &skybox_prog, NULL)) {
90                 fprintf(stderr, "[error] failed to create skybox shader program\n");
91                 return false;
92         }
93
94         glProgramUniform1iv(skybox_prog, glGetUniformLocation(skybox_prog, "textures"), 2, (GLint[]) {0, 1}); GL_DEBUG
95
96         skybox_loc_VP = glGetUniformLocation(skybox_prog, "VP"); GL_DEBUG
97         skybox_loc_daylight = glGetUniformLocation(skybox_prog, "daylight"); GL_DEBUG
98         skybox_texture_day = texture_load_cubemap(RESSOURCE_PATH "textures/skybox/day")->txo;
99         skybox_texture_night = texture_load_cubemap(RESSOURCE_PATH "textures/skybox/night")->txo;
100         skybox_mesh.data = skybox_vertices;
101         mesh_upload(&skybox_mesh);
102
103         // sun
104
105         if (!shader_program_create(RESSOURCE_PATH "shaders/sky/sun", &sun_prog, NULL)) {
106                 fprintf(stderr, "[error] failed to create sun shader program\n");
107                 return false;
108         }
109
110         sun_loc_MVP = glGetUniformLocation(sun_prog, "MVP"); GL_DEBUG
111         sun_texture = texture_load(RESSOURCE_PATH "textures/sun.png", false)->txo;
112
113         // clouds
114
115         if (!shader_program_create(RESSOURCE_PATH "shaders/sky/clouds", &clouds_prog, NULL)) {
116                 fprintf(stderr, "[error] failed to create clouds shader program\n");
117                 return false;
118         }
119
120         clouds_loc_VP = glGetUniformLocation(clouds_prog, "VP"); GL_DEBUG
121         clouds_loc_daylight = glGetUniformLocation(clouds_prog, "daylight"); GL_DEBUG
122         clouds_mesh.data = clouds_vertices;
123         mesh_upload(&clouds_mesh);
124
125         return true;
126 }
127
128 void sky_deinit()
129 {
130         glDeleteProgram(sun_prog); GL_DEBUG
131         mesh_destroy(&sun_mesh);
132
133         glDeleteProgram(skybox_prog); GL_DEBUG
134         mesh_destroy(&skybox_mesh);
135
136         glDeleteProgram(clouds_prog); GL_DEBUG
137         mesh_destroy(&clouds_mesh);
138 }
139
140 void sky_render()
141 {
142         f64 daylight = get_daylight();
143         f64 sun_angle = get_sun_angle();
144
145         vec3 sun_pos = {0.0f, cos(sun_angle), sin(sun_angle)};
146         vec3_norm(sun_pos, sun_pos);
147         vec3_scale(sun_pos, sun_pos, 5.0f);
148
149         mat4x4 model;
150         mat4x4_translate(model, sun_pos[0], sun_pos[1], sun_pos[2]);
151         mat4x4_rotate(model, model, 1.0f, 0.0f, 0.0f, sun_angle + M_PI / 2.0f);
152
153         mat4x4 view;
154         mat4x4_dup(view, camera.view);
155         view[3][0] = 0.0f;
156         view[3][1] = 0.0f;
157         view[3][2] = 0.0f;
158
159         mat4x4 vp;
160         mat4x4_mul(vp, window.projection, view);
161
162         mat4x4 mvp;
163         mat4x4_mul(mvp, vp, model);
164
165         glDisable(GL_CULL_FACE); GL_DEBUG
166         glDepthFunc(GL_LEQUAL); GL_DEBUG
167
168         glUseProgram(skybox_prog); GL_DEBUG
169         glUniformMatrix4fv(skybox_loc_VP, 1, GL_FALSE, vp[0]); GL_DEBUG
170         glUniform1f(skybox_loc_daylight, daylight); GL_DEBUG
171         glBindTextureUnit(0, skybox_texture_day); GL_DEBUG
172         glBindTextureUnit(1, skybox_texture_night); GL_DEBUG
173         mesh_render(&skybox_mesh);
174
175         glUseProgram(sun_prog); GL_DEBUG
176         glUniformMatrix4fv(sun_loc_MVP, 1, GL_FALSE, mvp[0]); GL_DEBUG
177         glBindTextureUnit(0, sun_texture); GL_DEBUG
178         mesh_render(&sun_mesh);
179
180         glUseProgram(clouds_prog); GL_DEBUG
181         glUniformMatrix4fv(clouds_loc_VP, 1, GL_FALSE, vp[0]); GL_DEBUG
182         glUniform1f(clouds_loc_daylight, daylight); GL_DEBUG
183         glBindTextureUnit(0, skybox_texture_day); GL_DEBUG
184         mesh_render(&clouds_mesh);
185
186         glDepthFunc(GL_LESS); GL_DEBUG
187         glEnable(GL_CULL_FACE); GL_DEBUG
188 }