#include "client/client.h"
#include "client/cube.h"
#include "client/mesh.h"
-#include "client/scene.h"
#include "client/shader.h"
#include "client/sky.h"
#include "client/texture.h"
+#include "client/window.h"
#include "day.h"
-static struct
-{
- GLuint skybox_prog;
- GLint skybox_loc_VP;
- GLint skybox_loc_daylight;
- GLuint skybox_textures[2];
- Mesh *skybox_mesh;
- GLuint sun_prog;
- GLint sun_loc_MVP;
- Texture *sun_texture;
- Mesh *sun_mesh;
- GLuint clouds_prog;
- GLint clouds_loc_VP;
- GLint clouds_loc_daylight;
- Mesh *clouds_mesh;
-} sky;
-
-typedef struct
-{
- GLfloat x, y, z;
-} __attribute__((packed)) VertexSunPosition;
-
-typedef struct
-{
- GLfloat s, t;
-} __attribute__((packed)) VertexSunTextureCoordinates;
-
-typedef struct
-{
- VertexSunPosition position;
- VertexSunTextureCoordinates textureCoordinates;
-} __attribute__((packed)) VertexSun;
-
-static VertexAttribute sun_vertex_attributes[2] = {
- // position
- {
- .type = GL_FLOAT,
- .length = 3,
- .size = sizeof(VertexSunPosition),
+static GLuint sun_prog;
+static GLint sun_loc_MVP;
+static GLuint sun_texture;
+typedef struct {
+ v3f32 position;
+ v2f32 textureCoordinates;
+} __attribute__((packed)) SunVertex;
+static Mesh sun_mesh = {
+ .layout = &(VertexLayout) {
+ .attributes = (VertexAttribute[]) {
+ {GL_FLOAT, 3, sizeof(v3f32)}, // position
+ {GL_FLOAT, 2, sizeof(v2f32)}, // textureCoordinates
+ },
+ .count = 2,
+ .size = sizeof(SunVertex),
},
- // textureCoordinates
- {
- .type = GL_FLOAT,
- .length = 2,
- .size = sizeof(VertexSunTextureCoordinates),
+ .vao = 0,
+ .vbo = 0,
+ .data = (SunVertex[]) {
+ {{-0.5, -0.5, +0.0}, {+0.0, +0.0}},
+ {{+0.5, -0.5, +0.0}, {+1.0, +0.0}},
+ {{+0.5, +0.5, +0.0}, {+1.0, +1.0}},
+ {{+0.5, +0.5, +0.0}, {+1.0, +1.0}},
+ {{-0.5, +0.5, +0.0}, {+0.0, +1.0}},
+ {{-0.5, -0.5, +0.0}, {+0.0, +0.0}},
},
+ .count = 6,
+ .free_data = false,
};
-static VertexLayout sun_vertex_layout = {
- .attributes = sun_vertex_attributes,
- .count = 2,
- .size = sizeof(VertexSun),
-};
-
-static VertexSun sun_vertices[6] = {
- {{-0.5, -0.5, +0.0}, {+0.0, +0.0}},
- {{+0.5, -0.5, +0.0}, {+1.0, +0.0}},
- {{+0.5, +0.5, +0.0}, {+1.0, +1.0}},
- {{+0.5, +0.5, +0.0}, {+1.0, +1.0}},
- {{-0.5, +0.5, +0.0}, {+0.0, +1.0}},
- {{-0.5, -0.5, +0.0}, {+0.0, +0.0}},
-};
-
-typedef struct
-{
- GLfloat x, y, z;
-} __attribute__((packed)) VertexSkyboxPosition;
-
-typedef struct
-{
- VertexSkyboxPosition position;
-} __attribute__((packed)) VertexSkybox;
-
-static VertexAttribute skybox_vertex_attributes[2] = {
- // position
- {
- .type = GL_FLOAT,
- .length = 3,
- .size = sizeof(VertexSkyboxPosition),
+static GLuint skybox_prog;
+static GLint skybox_loc_VP;
+static GLint skybox_loc_daylight;
+static GLuint skybox_texture_day;
+static GLuint skybox_texture_night;
+typedef struct {
+ v3f32 position;
+} __attribute__((packed)) SkyboxVertex;
+static Mesh skybox_mesh = {
+ .layout = &(VertexLayout) {
+ .attributes = (VertexAttribute[]) {
+ {GL_FLOAT, 3, sizeof(v3f32)}, // position
+ },
+ .count = 1,
+ .size = sizeof(SkyboxVertex),
},
+ .vao = 0,
+ .vbo = 0,
+ .data = NULL,
+ .count = 36,
+ .free_data = false,
};
-static VertexLayout skybox_vertex_layout = {
- .attributes = skybox_vertex_attributes,
- .count = 1,
- .size = sizeof(VertexSkybox),
-};
-
-static VertexSkybox skybox_vertices[6][6];
-static VertexSkybox clouds_vertices[6][6];
+static GLuint clouds_prog;
+static GLint clouds_loc_VP;
+static GLint clouds_loc_daylight;
+static Mesh clouds_mesh;
bool sky_init()
{
- // skybox
-
- if (! shader_program_create(RESSOURCE_PATH "shaders/sky/skybox", &sky.skybox_prog, NULL)) {
- fprintf(stderr, "Failed to create skybox shader program\n");
- return false;
- }
-
- sky.skybox_loc_VP = glGetUniformLocation(sky.skybox_prog, "VP");
- sky.skybox_loc_daylight = glGetUniformLocation(sky.skybox_prog, "daylight");
-
- sky.skybox_textures[0] = texture_create_cubemap(RESSOURCE_PATH "textures/skybox/day");
- sky.skybox_textures[1] = texture_create_cubemap(RESSOURCE_PATH "textures/skybox/night");
-
- GLint texture_indices[2];
- for (GLint i = 0; i < 2; i++)
- texture_indices[i] = i;
-
- glProgramUniform1iv(sky.skybox_prog, glGetUniformLocation(sky.skybox_prog, "textures"), 2, texture_indices);
-
+ clouds_mesh = skybox_mesh;
+ SkyboxVertex skybox_vertices[6][6], clouds_vertices[6][6];
for (int f = 0; f < 6; f++) {
for (int v = 0; v < 6; v++) {
- skybox_vertices[f][v].position.x = cube_vertices[f][v].position.x;
- skybox_vertices[f][v].position.y = cube_vertices[f][v].position.y;
- skybox_vertices[f][v].position.z = cube_vertices[f][v].position.z;
+ skybox_vertices[f][v].position =
+ clouds_vertices[f][v].position =
+ cube_vertices[f][v].position;
+
+ clouds_vertices[f][v].position.y = fmax(clouds_vertices[f][v].position.y, 0.0);
}
}
- sky.skybox_mesh = mesh_create();
- sky.skybox_mesh->textures = sky.skybox_textures;
- sky.skybox_mesh->textures_count = 2;
- sky.skybox_mesh->free_textures = false;
- sky.skybox_mesh->vertices = skybox_vertices;
- sky.skybox_mesh->vertices_count = 36;
- sky.skybox_mesh->free_vertices = false;
- sky.skybox_mesh->layout = &skybox_vertex_layout;
-
- // sun
+ // skybox
- if (! shader_program_create(RESSOURCE_PATH "shaders/sky/sun", &sky.sun_prog, NULL)) {
- fprintf(stderr, "Failed to create sun shader program\n");
+ if (!shader_program_create(RESSOURCE_PATH "shaders/sky/skybox", &skybox_prog, NULL)) {
+ fprintf(stderr, "[error] failed to create skybox shader program\n");
return false;
}
- sky.sun_loc_MVP = glGetUniformLocation(sky.sun_prog, "MVP");
-
- sky.sun_texture = texture_load(RESSOURCE_PATH "textures/sun.png", false);
+ glProgramUniform1iv(skybox_prog, glGetUniformLocation(skybox_prog, "textures"), 2, (GLint[]) {0, 1});
- sky.sun_mesh = mesh_create();
- sky.sun_mesh->textures = &sky.sun_texture->id;
- sky.sun_mesh->textures_count = 1;
- sky.sun_mesh->free_textures = false;
- sky.sun_mesh->vertices = sun_vertices;
- sky.sun_mesh->vertices_count = 6;
- sky.sun_mesh->free_vertices = false;
- sky.sun_mesh->layout = &sun_vertex_layout;
+ skybox_loc_VP = glGetUniformLocation(skybox_prog, "VP");
+ skybox_loc_daylight = glGetUniformLocation(skybox_prog, "daylight");
+ skybox_texture_day = texture_load_cubemap(RESSOURCE_PATH "textures/skybox/day")->txo;
+ skybox_texture_night = texture_load_cubemap(RESSOURCE_PATH "textures/skybox/night")->txo;
+ skybox_mesh.data = skybox_vertices;
+ mesh_upload(&skybox_mesh);
- // clouds
+ // sun
- if (! shader_program_create(RESSOURCE_PATH "shaders/sky/clouds", &sky.clouds_prog, NULL)) {
- fprintf(stderr, "Failed to create clouds shader program\n");
+ if (!shader_program_create(RESSOURCE_PATH "shaders/sky/sun", &sun_prog, NULL)) {
+ fprintf(stderr, "[error] failed to create sun shader program\n");
return false;
}
- sky.clouds_loc_VP = glGetUniformLocation(sky.clouds_prog, "VP");
- sky.clouds_loc_daylight = glGetUniformLocation(sky.clouds_prog, "daylight");
+ sun_loc_MVP = glGetUniformLocation(sun_prog, "MVP");
+ sun_texture = texture_load(RESSOURCE_PATH "textures/sun.png", false)->txo;
- for (int f = 0; f < 6; f++) {
- for (int v = 0; v < 6; v++) {
- clouds_vertices[f][v].position.x = cube_vertices[f][v].position.x;
- clouds_vertices[f][v].position.y = fmax(cube_vertices[f][v].position.y, 0.0);
- clouds_vertices[f][v].position.z = cube_vertices[f][v].position.z;
- }
+ // clouds
+
+ if (!shader_program_create(RESSOURCE_PATH "shaders/sky/clouds", &clouds_prog, NULL)) {
+ fprintf(stderr, "[error] failed to create clouds shader program\n");
+ return false;
}
- sky.clouds_mesh = mesh_create();
- sky.clouds_mesh->textures = sky.skybox_textures;
- sky.clouds_mesh->textures_count = 1;
- sky.clouds_mesh->free_textures = false;
- sky.clouds_mesh->vertices = clouds_vertices;
- sky.clouds_mesh->vertices_count = 36;
- sky.clouds_mesh->free_vertices = false;
- sky.clouds_mesh->layout = &skybox_vertex_layout;
+ clouds_loc_VP = glGetUniformLocation(clouds_prog, "VP");
+ clouds_loc_daylight = glGetUniformLocation(clouds_prog, "daylight");
+ clouds_mesh.data = clouds_vertices;
+ mesh_upload(&clouds_mesh);
return true;
}
void sky_deinit()
{
- glDeleteProgram(sky.skybox_prog);
- glDeleteTextures(1, &sky.skybox_textures[0]);
- glDeleteTextures(1, &sky.skybox_textures[1]);
- mesh_delete(sky.skybox_mesh);
+ glDeleteProgram(sun_prog);
+ mesh_destroy(&sun_mesh);
- glDeleteProgram(sky.sun_prog);
- mesh_delete(sky.sun_mesh);
-}
+ glDeleteProgram(skybox_prog);
+ mesh_destroy(&skybox_mesh);
+ glDeleteProgram(clouds_prog);
+ mesh_destroy(&clouds_mesh);
+}
void sky_render()
{
view[3][1] = 0.0f;
view[3][2] = 0.0f;
- mat4x4 VP;
- mat4x4_mul(VP, scene.projection, view);
+ mat4x4 vp;
+ mat4x4_mul(vp, window.projection, view);
- mat4x4 MVP;
- mat4x4_mul(MVP, VP, model);
+ mat4x4 mvp;
+ mat4x4_mul(mvp, vp, model);
glDisable(GL_CULL_FACE);
glDepthFunc(GL_LEQUAL);
- glUseProgram(sky.skybox_prog);
- glUniformMatrix4fv(sky.skybox_loc_VP, 1, GL_FALSE, VP[0]);
- glUniform1f(sky.skybox_loc_daylight, daylight);
- mesh_render(sky.skybox_mesh);
-
- glUseProgram(sky.sun_prog);
- glUniformMatrix4fv(sky.sun_loc_MVP, 1, GL_FALSE, MVP[0]);
- mesh_render(sky.sun_mesh);
-
- glUseProgram(sky.clouds_prog);
- glUniformMatrix4fv(sky.clouds_loc_VP, 1, GL_FALSE, VP[0]);
- glUniform1f(sky.clouds_loc_daylight, daylight);
- mesh_render(sky.clouds_mesh);
+ glUseProgram(skybox_prog);
+ glUniformMatrix4fv(skybox_loc_VP, 1, GL_FALSE, vp[0]);
+ glUniform1f(skybox_loc_daylight, daylight);
+ glBindTextureUnit(0, skybox_texture_day);
+ glBindTextureUnit(1, skybox_texture_night);
+ mesh_render(&skybox_mesh);
+
+ glUseProgram(sun_prog);
+ glUniformMatrix4fv(sun_loc_MVP, 1, GL_FALSE, mvp[0]);
+ glBindTextureUnit(0, sun_texture);
+ mesh_render(&sun_mesh);
+
+ glUseProgram(clouds_prog);
+ glUniformMatrix4fv(clouds_loc_VP, 1, GL_FALSE, vp[0]);
+ glUniform1f(clouds_loc_daylight, daylight);
+ glBindTextureUnit(0, skybox_texture_day);
+ mesh_render(&clouds_mesh);
glDepthFunc(GL_LESS);
glEnable(GL_CULL_FACE);