#include <stdlib.h>
#include <stdio.h>
-#include <pthread.h>
-#include <linmath.h/linmath.h>
#include "client/camera.h"
#include "client/client.h"
#include "client/scene.h"
#include "client/shader.h"
-#include "list.h"
+#include "day.h"
+#include "util.h"
-static struct
-{
- List objects;
- pthread_mutex_t mtx;
- GLuint prog;
- GLint loc_model;
- GLint loc_view;
- GLint loc_projection;
- mat4x4 projection;
- f32 fov;
- f32 render_distance;
-} scene;
+struct Scene scene;
bool scene_init()
{
scene.objects = list_create(NULL),
pthread_mutex_init(&scene.mtx, NULL);
- if (! shader_program_create(RESSOURCEPATH "shaders/3d", &scene.prog)) {
+ glGetIntegerv(GL_MAX_TEXTURE_UNITS, &scene.max_texture_units);
+
+ char max_texture_units_def[BUFSIZ];
+ sprintf(max_texture_units_def, "#define MAX_TEXTURE_UNITS %d\n", scene.max_texture_units);
+
+ if (! shader_program_create(RESSOURCEPATH "shaders/3d", &scene.prog, max_texture_units_def)) {
fprintf(stderr, "Failed to create 3D shader program\n");
return false;
}
scene.loc_model = glGetUniformLocation(scene.prog, "model");
- scene.loc_view = glGetUniformLocation(scene.prog, "view");
- scene.loc_projection = glGetUniformLocation(scene.prog, "projection");
+ scene.loc_VP = glGetUniformLocation(scene.prog, "VP");
+ scene.loc_daylight = glGetUniformLocation(scene.prog, "daylight");
+ scene.loc_lightDir = glGetUniformLocation(scene.prog, "lightDir");
+ scene.loc_cameraPos = glGetUniformLocation(scene.prog, "cameraPos");
+
+ GLint texture_indices[scene.max_texture_units];
+ for (GLint i = 0; i < scene.max_texture_units; i++)
+ texture_indices[i] = i;
+
+ glProgramUniform1iv(scene.prog, glGetUniformLocation(scene.prog, "textures"), scene.max_texture_units, texture_indices);
scene.fov = 86.1f;
- scene.render_distance = 1000.0f;
+ scene.render_distance = 255.0f + 32.0f;
return true;
}
-static void list_delete_object(void *key, __attribute__((unused)) void *value, __attribute__((unused)) void *unused)
+static void list_delete_object(void *key, unused void *value, unused void *arg)
{
object_delete(key);
}
pthread_mutex_unlock(&scene.mtx);
}
-void scene_render()
+void scene_render(f64 dtime)
{
- glUseProgram(scene.prog);
- camera_enable(scene.loc_view);
- glUniformMatrix4fv(scene.loc_projection, 1, GL_FALSE, scene.projection[0]);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpedantic"
+ mat4x4_mul(scene.VP, scene.projection, camera.view);
- glActiveTexture(GL_TEXTURE0);
+ vec4 base_sunlight_dir = {0.0f, 0.0f, -1.0f, 1.0f};
+ vec4 sunlight_dir;
+ mat4x4 sunlight_mat;
+ mat4x4_identity(sunlight_mat);
+ mat4x4_rotate(sunlight_mat, sunlight_mat, 1.0f, 0.0f, 0.0f, get_sun_angle() + M_PI / 2.0f);
+ mat4x4_mul_vec4(sunlight_dir, sunlight_mat, base_sunlight_dir);
+#pragma GCC diagnostic pop
+
+ glUseProgram(scene.prog);
+ glUniformMatrix4fv(scene.loc_VP, 1, GL_FALSE, scene.VP[0]);
+ glUniform3f(scene.loc_lightDir, sunlight_dir[0], sunlight_dir[1], sunlight_dir[2]);
+ glUniform3f(scene.loc_cameraPos, camera.eye[0], camera.eye[1], camera.eye[2]);
+ glUniform1f(scene.loc_daylight, get_daylight());
for (ListPair **pairptr = &scene.objects.first; *pairptr != NULL; ) {
ListPair *pair = *pairptr;
free(pair);
object_delete(obj);
} else {
- object_render(obj, scene.loc_model);
+ object_render(obj, dtime);
pairptr = &pair->next;
}
}
{
mat4x4_perspective(scene.projection, scene.fov / 180.0f * M_PI, (float) width / (float) height, 0.01f, scene.render_distance);
}
+
+GLuint scene_get_max_texture_units()
+{
+ return scene.max_texture_units;
+}