commit c2d82552009445893fd84e89c1722e7bb0e32818
parent abb67a77d710c242521dd9823bfa55ba55ac1ad1
Author: William Casarin <jb55@jb55.com>
Date: Sun, 4 Nov 2018 14:13:39 -0800
entity system, shadow refactors
Diffstat:
18 files changed, 408 insertions(+), 305 deletions(-)
diff --git a/etc/shaders/lighting.glsl b/etc/shaders/lighting.glsl
@@ -19,29 +19,28 @@ vec3 gamma_correct(vec3 color) {
return pow(color, vec3(1.0/2.2));
}
-vec3 standard_light(vec3 color, vec3 position, vec3 normal) {
- vec4 trans_normal = normal_matrix * vec4(normal, 1.0);
-
+vec3 standard_light(vec3 color, vec4 position, vec4 normal) {
// vec3 light_dir = vec3()
const float pi = 3.14159265;
const float shiny = 12.0;
const float exposure = 0.2;
- const float ambient_str = 0.2;
+ float ambient_str = 0.25;
float spec_str = 0.8 * light_intensity;
+ vec4 trans_normal = normal_matrix * normal;
+ vec3 L = light_dir;
+ vec3 N = normalize(trans_normal.xyz);
+ float cos_theta = max(0.0, dot(L,N));
+
// float light_intensity = light_intensity * 0.01;
// too much ambient during daytime is making things look weird
// ambient_str =- light_intensity * ambient_str;
- vec3 ray = camera_position - position;
+ vec3 ray = camera_position - position.xyz;
vec3 view_dir = normalize(ray);
- float distance = length(ray);
- float attenuation = 1.0 / distance;
- vec3 L = light_dir;
- vec3 N = normalize(trans_normal.xyz);
- float brightness = max(0.0, dot(L,N)) * light_intensity;
+ float brightness = cos_theta * light_intensity;
// brightness += clouds(position);
@@ -55,12 +54,12 @@ vec3 standard_light(vec3 color, vec3 position, vec3 normal) {
if (blinn) {
const float energy_conservation = ( 8.0 + shiny ) / ( 8.0 * pi );
vec3 halfway_dir = normalize(light_dir + view_dir); // blinn-phong
- spec = energy_conservation * pow(max(dot(normal, halfway_dir), 0.0), shiny);
+ spec = energy_conservation * pow(max(dot(normal.xyz, halfway_dir), 0.0), shiny);
}
else {
const float energy_conservation = ( 2.0 + shiny ) / ( 2.0 * pi );
- vec3 reflect_dir = reflect(-light_dir, normal); // phong
+ vec3 reflect_dir = reflect(-light_dir, normal.xyz); // phong
spec = energy_conservation * pow(max(dot(view_dir, reflect_dir), 0.0), shiny);
}
// spec += pow(max(dot(view_dir, reflect_dir), 0.0), 16.0) * 0.5;
diff --git a/etc/shaders/standard_vtxos.glsl b/etc/shaders/standard_vtxos.glsl
@@ -1,5 +1,7 @@
vec4 v4_pos = vec4(position, 1.0);
data_out.normal = normal;
+data_out.position = position;
data_out.color_smooth = data_out.color = color;
data_out.shadow_coord = depth_mvp * v4_pos;
data_out.frag_pos = (world * v4_pos).xyz;
+// TODO: move shadow coord calc from frag to here
diff --git a/etc/shaders/terrain.g.glsl b/etc/shaders/terrain.g.glsl
@@ -23,9 +23,9 @@ void main() {
vertex.color = vertices[i].color;
vertex.color_smooth = vertices[i].color_smooth;
vertex.normal = vertices[i].normal;
- vertex.shadow_coord = depth_mvp * v4_pos;
+ // vertex.shadow_coord = depth_mvp * v4_pos;
vertex.frag_pos = (world * v4_pos).xyz;
- // vertex.shadow_coord = vertices[i].shadow_coord;
+ vertex.shadow_coord = vertices[i].shadow_coord;
// vertex.frag_pos = vertices[i].frag_pos;
// gl_Position = mvp * vec4(400.0 + i * 50.0, 300.0 + i * 50.0, 200.0 + i * 50.0, 1.0);
diff --git a/etc/shaders/terrain.te.glsl b/etc/shaders/terrain.te.glsl
@@ -28,7 +28,7 @@ void main()
data_out.color = data_in[0].color;
data_out.color_smooth = data_in[0].color_smooth;
data_out.normal = data_in[0].normal;
- data_out.shadow_coord = depth_mvp * data_in[0].shadow_coord;
+ // data_out.shadow_coord = depth_mvp * data_in[0].shadow_coord;
data_out.frag_pos = (world * v).xyz;
}
diff --git a/etc/shaders/test.f.glsl b/etc/shaders/test.f.glsl
@@ -12,17 +12,18 @@ in shader_data {
uniform sampler2D shadow_map;
#include lighting.glsl
+#include shadows.glsl
#include fog.glsl
void main() {
const float smoothness = 0.0;
- float visibility = 1.0;
- vec4 shadow_sample = texture(shadow_map, vertex.shadow_coord.xy);
vec3 v_ray = camera_position - vertex.frag_pos;
+ vec4 v4_pos = vec4(vertex.position, 1.0);
+ vec4 v4_normal = vec4(vertex.normal, 1.0);
// vec3 color = vertex.color * (1.0-smoothness)
// + color_smooth * smoothness;
- vec3 color = standard_light(vertex.color, vertex.position, vertex.normal);
+ vec3 color = standard_light(vertex.color, v4_pos, v4_normal);
if (fog_on) {
vec3 fog = apply_fog(color, length(v_ray), camera_position, v_ray);
@@ -30,22 +31,7 @@ void main() {
color = fog;
}
- float bias = 0.006;
- bool in_shadow =
- shadow_sample.z < vertex.shadow_coord.z - bias
- && shadow_sample.y < 1.0;
-
- if (light_dir.z > 0.0 && in_shadow) {
- float factor = 1.0/(dot(light_dir, vec3(0.0, 0.0, 1.0)));
- // float factor = 1.0;
- visibility = clamp(0.2 * factor, 0.5, 1.0);
- // visibility = shadow_sample;
- }
-
- // float factor = 1.0/(dot(light_dir, vec3(0.0, 0.0, 1.0)));
- color *= visibility;
- // color += shadow_sample.z * factor;
- // float dist = length(camera_position - vertex.position);
+ color *= shadow_strength(v4_pos, v4_normal, vertex.shadow_coord);
frag_color = vec4(color, 1.0);
}
diff --git a/etc/shaders/uniforms.glsl b/etc/shaders/uniforms.glsl
@@ -4,7 +4,7 @@ uniform bool fog_on;
uniform float sky_intensity;
uniform float light_intensity;
uniform mat4 depth_mvp;
-uniform mat4 model_view;
+uniform mat4 depth_vp;
uniform mat4 mvp;
uniform mat4 normal_matrix;
uniform mat4 world;
diff --git a/src/entity.c b/src/entity.c
@@ -6,29 +6,99 @@
#define DEF_NUM_ENTITIES 1024
-struct entity_id {
- u32 index;
+struct entity_system {
+ struct entity *entities;
+ struct entity_id *ids;
+ u32 entity_count;
u32 generation;
};
-void init_entity(struct entity *ent) {
+static u64 entity_uuids = 0;
+
+static struct entity_system esys;
+
+struct entity *get_all_entities(u32 *count, struct entity_id **ids) {
+ if (count != NULL)
+ *count = esys.entity_count;
+ if (ids != NULL)
+ *ids = esys.ids;
+ return esys.entities;
+}
+
+struct entity *init_entity(struct entity *ent) {
node_init(&ent->node);
- ent->casts_shadows = 0;
+ init_model(&ent->model);
+ ent->casts_shadows = 1;
+ return ent;
}
-struct entity *get_entity(struct entity_system *system, struct entity_id id) {
- assert(id.generation <= system->generation);
- if (id.generation < system->generation)
+struct entity *get_entity_pure(struct entity_id id) {
+ struct entity_id pure_id;
+ pure_id = id;
+
+ return get_entity(&pure_id);
+}
+
+struct entity *get_entity(struct entity_id *id) {
+ struct entity_id *new_id;
+ // rollover is ok
+ /* assert(->generation <= esys.generation); */
+ if (id->generation != esys.generation) {
+ // try to find uuid in new memory layout
+ for (u32 i = 0; i < esys.entity_count; i++) {
+ new_id = &esys.ids[i];
+ if (new_id->uuid == id->uuid) {
+ id->index = new_id->index;
+ id->generation = esys.generation;
+ return &esys.entities[id->index];
+ }
+ }
+
+ // entity was deleted
return NULL;
- return &system->entities[id.index];
+ }
+ return &esys.entities[id->index];
+}
+
+static inline struct entity_id new_id() {
+ return (struct entity_id){
+ .index = esys.entity_count,
+ .uuid = entity_uuids++,
+ .generation = esys.generation,
+ };
+}
+
+static inline struct entity *new_uninitialized_entity(struct entity_id *id) {
+ struct entity_id fresh_id;
+ fresh_id = new_id();
+
+ if (id)
+ *id = fresh_id;
+
+ return &esys.entities[esys.entity_count++];
+}
+
+struct entity *new_entity(struct entity_id *id) {
+ return init_entity(new_uninitialized_entity(id));
+}
+
+struct entity *add_entity(struct entity *e, struct entity_id *id) {
+ struct entity *new = new_uninitialized_entity(id);
+ *new = *e;
+ return new;
+}
+
+
+void destroy_entity_system() {
+ free(esys.entities);
}
-void init_entity_system(struct entity_system *system) {
- system->generation = 0;
- system->entities = calloc(DEF_NUM_ENTITIES, sizeof(*system->entities));
+void init_entity_system() {
+ esys.generation = 0;
+ esys.entities = calloc(DEF_NUM_ENTITIES, sizeof(*esys.entities));
- system->handles =
- calloc(DEF_NUM_ENTITIES, sizeof(*system->handles));
+ esys.ids =
+ calloc(DEF_NUM_ENTITIES, sizeof(*esys.ids));
}
diff --git a/src/entity.h b/src/entity.h
@@ -5,26 +5,30 @@
#include "node.h"
#include "model.h"
+enum entity_flags {
+ ENT_FLAG_PLAYER = 1 << 0,
+};
+
struct entity {
struct node node;
struct model model;
+ u32 flags;
float velocity[3];
float accel[3];
int casts_shadows;
};
-struct entity_id;
-
-struct entity_system {
- struct entity *entities;
- struct entity_id *handles;
- int entity_count;
+struct entity_id {
+ u64 uuid;
+ u32 index;
u32 generation;
};
-void init_entity(struct entity *);
-void init_entity_system(struct entity_system *);
-struct entity *get_entity(struct entity_system *, struct entity_id);
+struct entity *init_entity(struct entity *);
+void init_entity_system();
+struct entity *get_entity(struct entity_id *);
+struct entity *get_all_entities(u32 *count, struct entity_id **ids);
+struct entity *new_entity(struct entity_id *id);
#endif /* ENTITY_H */
diff --git a/src/game.c b/src/game.c
@@ -25,17 +25,25 @@ static void camera_update(struct node *node) {
mat4_multiply(persp, mat, mat);
}
+struct entity *get_player(struct resources *res) {
+ struct entity *player = get_entity(&res->player_id);
+ assert(player);
+ return player;
+}
+
void game_init(struct game *game, int width, int height) {
init_gl(&game->test_resources, width, height);
+ init_entity_system();
check_gl();
+ float pos[3];
struct resources *res = &game->test_resources;
mat4 *mvp = res->test_mvp;
struct node *root = &res->root;
struct node *camera = &res->camera;
struct node *sun_camera = &res->sun_camera;
- struct entity *player = &res->player;
struct terrain *terrain = &game->terrain;
+ struct entity *player;
mat4 *light_dir = res->light_dir;
int ok = 0;
@@ -58,9 +66,7 @@ void game_init(struct game *game, int width, int height) {
check_gl();
- terrain_init(terrain);
- terrain->entity.model.shading = SHADING_TERRAIN;
- terrain->size = size;
+ init_terrain(terrain, size);
mat4_id(mvp);
@@ -79,16 +85,6 @@ void game_init(struct game *game, int width, int height) {
res->sun_color[1] = 0.6;
res->sun_color[2] = 0.7;
- /* vec3(0.5,0.6,0.7); */
-
- // BRB: shadow mapping next!
-
- // FBO STUFF
- init_fbo(&res->shadow_buffer);
- resize_fbos(game, width, height);
-
- // FBO STUFF END
-
game->test_resources.fog_on = 1;
game->test_resources.diffuse_on = 0;
@@ -100,32 +96,43 @@ void game_init(struct game *game, int width, int height) {
node_init(camera);
node_init(sun_camera);
- init_entity(&terrain->entity);
- init_entity(player);
- player->casts_shadows = 1;
- terrain->entity.casts_shadows = 0;
+ // ENTITIES
- // player init
+ // player entity
+ player = new_entity(&res->player_id);
ok = load_model(&player->model, "pirate-officer");
assert(ok);
- player->model.shading = SHADING_VERT_COLOR;
player->node.label = "player";
+ node_attach(&player->node, root);
+ node_translate(&player->node, V3(terrain->size/2.,terrain->size/2.,0.0));
+
+ struct entity *tower = new_entity(NULL);
+ ok = load_model(&tower->model, "tower");
+ assert(ok);
+ tower->node.label = "tower";
+ node_attach(&tower->node, &player->node);
+ node_translate(&tower->node, V3(0.0, 40.0, 0.0));
+
+
+ // END ENTITIES
+
+
+ // player init
root->label = "root";
camera->label = "camera";
- terrain->entity.node.label = "terrain_node";
- node_attach(&player->node, root);
node_attach(camera, &player->node);
quat_axis_angle(V3(1,0,0), -45, camera->orientation);
- node_translate(&player->node, V3(terrain->size/2.,terrain->size/2.,0.0));
-
node_rotate(camera, V3(100, 0, 0));
node_translate(camera, V3(0,-40,20));
- terrain->entity.node.pos[2] = 20.0;
-
input_init(&game->input);
+
+ // FBO STUFF
+ init_fbo(&res->shadow_buffer);
+ resize_fbos(player, &res->shadow_buffer, res->proj_ortho, width, height);
+ // FBO STUFF END
}
diff --git a/src/game.h b/src/game.h
@@ -43,6 +43,7 @@ struct resources {
GLint sun_color;
GLint mvp;
GLint depth_mvp;
+ GLint depth_vp;
GLint normal_matrix;
GLint view;
GLint time;
@@ -55,7 +56,7 @@ struct resources {
struct attributes attributes;
struct node root;
- struct entity player;
+ struct entity_id player_id;
struct orbit orbit_camera;
struct node camera;
struct node sun_camera;
@@ -81,6 +82,7 @@ struct game {
struct terrain terrain;
};
+struct entity *get_player(struct resources *);
void game_init(struct game *game, int width, int height);
void should_update(struct game *game);
diff --git a/src/model.c b/src/model.c
@@ -2,14 +2,16 @@
#include "model.h"
#include "ply.h"
+void init_model(struct model *model) {
+ model->shading = SHADING_VERT_COLOR;
+ init_geometry(&model->geom);
+}
int load_model(struct model *model, const char *name) {
static char path[128] = {0};
int ok = 0;
- init_geometry(&model->geom);
-
// Load mesh
snprintf(path, 128, "data/models/%s.ply", name);
ok = parse_ply(path, &model->geom);
diff --git a/src/model.h b/src/model.h
@@ -20,6 +20,7 @@ struct model {
};
+void init_model(struct model *model);
int load_model(struct model *model, const char *name);
diff --git a/src/render.c b/src/render.c
@@ -140,6 +140,10 @@ init_gl(struct resources *resources, int width, int height) {
glGetUniformLocation(handle, "camera_position");
check_gl();
+ resources->uniforms.depth_vp =
+ glGetUniformLocation(handle, "depth_vp");
+ check_gl();
+
resources->uniforms.depth_mvp =
glGetUniformLocation(handle, "depth_mvp");
check_gl();
@@ -250,11 +254,10 @@ void render (struct game *game, struct render_config *config) {
mat4 *light = res->light_dir;
float *camera = config->camera;
+ u32 num_entities;
- struct entity *entities[] =
- { &game->terrain.entity
- , &game->test_resources.player
- };
+ struct entity *entities =
+ get_all_entities(&num_entities, NULL);
struct gpu_program *current_program = NULL;
@@ -268,19 +271,19 @@ void render (struct game *game, struct render_config *config) {
mat4_multiply(projection, view, view_proj);
if (config->is_depth_pass) {
- /* glCullFace(GL_FRONT); */
+ glDisable(GL_CULL_FACE);
mat4_multiply(bias_matrix, view_proj, config->depth_vp);
}
else {
glCullFace(GL_BACK);
}
- for (size_t i = 0; i < ARRAY_SIZE(entities); ++i) {
- struct entity *entity = entities[i];
+ for (u32 i = 0; i < num_entities; ++i) {
+ struct entity *entity = &entities[i];
if (config->is_depth_pass && !entity->casts_shadows)
continue;
- // TODO this is a bit wonky, refactor this
+ // TODO this is a bit wonky, refactor this
current_program = i == 0 ? terrain_program : default_program;
glUseProgram(current_program->handle);
check_gl();
@@ -317,6 +320,8 @@ void render (struct game *game, struct render_config *config) {
check_gl();
glUniformMatrix4fv(res->uniforms.depth_mvp, 1, 0, depth_mvp);
check_gl();
+ glUniformMatrix4fv(res->uniforms.depth_vp, 1, 0, config->depth_vp);
+ check_gl();
glUniformMatrix4fv(res->uniforms.model_view, 1, 0, model_view);
check_gl();
glUniformMatrix4fv(res->uniforms.world, 1, 0, entity->node.mat);
diff --git a/src/terrain.c b/src/terrain.c
@@ -41,146 +41,166 @@ void deriv(noisefn fn, void* data, double x, double y, double z1, double *dx, do
*dy = (zy - z1)/h;
}
-void
-terrain_init(struct terrain *terrain) {
- terrain->samples = NULL;
- terrain->n_samples = 0;
- terrain->fn = 0;
- // TODO: init model
- init_geometry(&terrain->entity.model.geom);
+void reset_terrain(struct terrain *terrain, float size) {
+ terrain->samples = NULL;
+ terrain->n_samples = 0;
+ terrain->fn = 0;
+ terrain->size = size;
+
+ struct entity *ent = get_entity(&terrain->entity_id);
+ assert(ent);
+}
+
+void init_terrain(struct terrain *terrain, float size) {
+ struct entity *ent;
+
+ ent = new_entity(&terrain->entity_id);
+ assert(terrain->entity_id.uuid == 0);
+ ent->model.shading = SHADING_TERRAIN;
+ ent->node.label = "terrain_node";
+ ent->casts_shadows = 0;
+
+ // this is scale for some reason!?
+ ent->node.pos[2] = 20.0;
+
+ reset_terrain(terrain, size);
}
double offset_fn(struct terrain* terrain, double x, double y) {
- struct perlin_settings *perlin = &terrain->settings;
- double ox = perlin->ox;
- double oy = perlin->oy;
- return old_noisy_boi(terrain, ox+x, oy+y);
+ struct perlin_settings *perlin = &terrain->settings;
+ double ox = perlin->ox;
+ double oy = perlin->oy;
+ return old_noisy_boi(terrain, ox+x, oy+y);
}
-void
-terrain_create(struct terrain *terrain) {
- u32 i;
- const double size = terrain->size;
-
- float tmp1[3], tmp2[3];
- assert(terrain->n_samples > 0);
- del_point2d_t *points = calloc(terrain->n_samples, sizeof(*points));
-
- float *verts = calloc(terrain->n_samples * 3, sizeof(*verts));
- /* float *normals = calloc(terrain->n_samples * 3, sizeof(*verts)); */
-
- terrain->fn = offset_fn;
-
- // 100 random samples from our noise function
- for (i = 0; i < (u32)terrain->n_samples; i++) {
- int n = i*3;
- double x, y;
- /* double dx, dy; */
-
- x = terrain->samples[i].x;
- y = terrain->samples[i].y;
-
- double z = terrain->fn(terrain, x, y);
-
- points[i].x = x;
- points[i].y = y;
-
- verts[n] = (float)x;
- verts[n+1] = (float)y;
-
- static const double limit = 1.4;
- if (x < limit || x > size-limit || y < limit || y > size-limit)
- verts[n+2] = 0;
- else
- verts[n+2] = (float)z;
- }
-
- delaunay2d_t *del = delaunay2d_from(points, terrain->n_samples);
- tri_delaunay2d_t *tri = tri_delaunay2d_from(del);
-
- int num_verts = tri->num_triangles * 3;
- float *del_verts = calloc(num_verts * 3, sizeof(*del_verts));
- float *del_norms = calloc(num_verts * 3, sizeof(*del_norms));
- u32 *del_indices = calloc(num_verts, sizeof(*del_indices));
-
- /// XXX (perf): we should be able to do this directly from del instead of
- /// triangulating with tri
- for (i = 0; i < tri->num_triangles; ++i) {
- int nv = i * 3;
- int ndv = i * 9;
-
- int p[3] = {
- tri->tris[nv + 0],
- tri->tris[nv + 1],
- tri->tris[nv + 2],
- };
-
- float *v[3] = {
- &verts[p[0]*3],
- &verts[p[1]*3],
- &verts[p[2]*3]
- };
-
- del_verts[ndv+0] = v[0][0];
- del_verts[ndv+1] = v[0][1];
- del_verts[ndv+2] = v[0][2];
-
- del_verts[ndv+3] = v[1][0];
- del_verts[ndv+4] = v[1][1];
- del_verts[ndv+5] = v[1][2];
-
- del_verts[ndv+6] = v[2][0];
- del_verts[ndv+7] = v[2][1];
- del_verts[ndv+8] = v[2][2];
-
- // centroid normals
- /* float c[3]; */
- /* c[0] = (v[0][0] + v[1][0] + v[2][0]) / 3.0; */
- /* c[1] = (v[0][1] + v[1][1] + v[2][1]) / 3.0; */
- /* c[2] = (v[0][2] + v[1][2] + v[2][2]) / 3.0; */
- /* double dx, dy; */
- /* deriv((noisefn)terrain->fn, terrain, c[0], c[1], c[2], &dx, &dy); */
- /* vec3_subtract(v[1], c, tmp1); */
- /* vec3_subtract(v[2], c, tmp2); */
-
- // standard normals
- vec3_subtract(v[1], v[0], tmp1);
- vec3_subtract(v[2], v[0], tmp2);
-
- vec3_cross(tmp1, tmp2, tmp2);
- vec3_normalize(tmp2, tmp2);
-
- for (int j = 0; j < 9; ++j) {
- del_norms[ndv+j] = tmp2[j%3];
+void create_terrain(struct terrain *terrain) {
+ u32 i;
+ const double size = terrain->size;
+
+ float tmp1[3], tmp2[3];
+ assert(terrain->n_samples > 0);
+ del_point2d_t *points = calloc(terrain->n_samples, sizeof(*points));
+
+ float *verts = calloc(terrain->n_samples * 3, sizeof(*verts));
+ /* float *normals = calloc(terrain->n_samples * 3, sizeof(*verts)); */
+
+ terrain->fn = offset_fn;
+
+ // 100 random samples from our noise function
+ for (i = 0; i < (u32)terrain->n_samples; i++) {
+ int n = i*3;
+ double x, y;
+ /* double dx, dy; */
+
+ x = terrain->samples[i].x;
+ y = terrain->samples[i].y;
+
+ double z = terrain->fn(terrain, x, y);
+
+ points[i].x = x;
+ points[i].y = y;
+
+ verts[n] = (float)x;
+ verts[n+1] = (float)y;
+
+ static const double limit = 1.4;
+ if (x < limit || x > size-limit || y < limit || y > size-limit)
+ verts[n+2] = 0;
+ else
+ verts[n+2] = (float)z;
+ }
+
+ delaunay2d_t *del = delaunay2d_from(points, terrain->n_samples);
+ tri_delaunay2d_t *tri = tri_delaunay2d_from(del);
+
+ int num_verts = tri->num_triangles * 3;
+ float *del_verts = calloc(num_verts * 3, sizeof(*del_verts));
+ float *del_norms = calloc(num_verts * 3, sizeof(*del_norms));
+ u32 *del_indices = calloc(num_verts, sizeof(*del_indices));
+
+ /// XXX (perf): we should be able to do this directly from del instead of
+ /// triangulating with tri
+ for (i = 0; i < tri->num_triangles; ++i) {
+ int nv = i * 3;
+ int ndv = i * 9;
+
+ int p[3] = {
+ tri->tris[nv + 0],
+ tri->tris[nv + 1],
+ tri->tris[nv + 2],
+ };
+
+ float *v[3] = {
+ &verts[p[0]*3],
+ &verts[p[1]*3],
+ &verts[p[2]*3]
+ };
+
+ del_verts[ndv+0] = v[0][0];
+ del_verts[ndv+1] = v[0][1];
+ del_verts[ndv+2] = v[0][2];
+
+ del_verts[ndv+3] = v[1][0];
+ del_verts[ndv+4] = v[1][1];
+ del_verts[ndv+5] = v[1][2];
+
+ del_verts[ndv+6] = v[2][0];
+ del_verts[ndv+7] = v[2][1];
+ del_verts[ndv+8] = v[2][2];
+
+ // centroid normals
+ /* float c[3]; */
+ /* c[0] = (v[0][0] + v[1][0] + v[2][0]) / 3.0; */
+ /* c[1] = (v[0][1] + v[1][1] + v[2][1]) / 3.0; */
+ /* c[2] = (v[0][2] + v[1][2] + v[2][2]) / 3.0; */
+ /* double dx, dy; */
+ /* deriv((noisefn)terrain->fn, terrain, c[0], c[1], c[2], &dx, &dy); */
+ /* vec3_subtract(v[1], c, tmp1); */
+ /* vec3_subtract(v[2], c, tmp2); */
+
+ // standard normals
+ vec3_subtract(v[1], v[0], tmp1);
+ vec3_subtract(v[2], v[0], tmp2);
+
+ vec3_cross(tmp1, tmp2, tmp2);
+ vec3_normalize(tmp2, tmp2);
+
+ for (int j = 0; j < 9; ++j) {
+ del_norms[ndv+j] = tmp2[j%3];
+ }
+
+ del_indices[nv+0] = nv+0;
+ del_indices[nv+1] = nv+1;
+ del_indices[nv+2] = nv+2;
}
- del_indices[nv+0] = nv+0;
- del_indices[nv+1] = nv+1;
- del_indices[nv+2] = nv+2;
- }
+ /* printf("faces %d tris %d points %d\n", */
+ /* del->num_faces, tri->num_triangles, tri->num_points); */
- /* printf("faces %d tris %d points %d\n", */
- /* del->num_faces, tri->num_triangles, tri->num_points); */
+ struct entity *ent = get_entity(&terrain->entity_id);
+ assert(ent);
- terrain->entity.model.geom.num_verts = num_verts;
- terrain->entity.model.geom.vertices = (float*)del_verts;
- terrain->entity.model.geom.normals = (float*)del_norms;
- terrain->entity.model.geom.indices = (u32*)del_indices;
- terrain->entity.model.geom.num_indices = num_verts;
+ ent->model.geom.num_verts = num_verts;
+ ent->model.geom.vertices = (float*)del_verts;
+ ent->model.geom.normals = (float*)del_norms;
+ ent->model.geom.indices = (u32*)del_indices;
+ ent->model.geom.num_indices = num_verts;
- make_buffer_geometry(&terrain->entity.model.geom);
+ make_buffer_geometry(&ent->model.geom);
- delaunay2d_release(del);
- tri_delaunay2d_release(tri);
+ delaunay2d_release(del);
+ tri_delaunay2d_release(tri);
- free(points);
- free(verts);
- free(del_verts);
- free(del_norms);
- free(del_indices);
+ free(points);
+ free(verts);
+ free(del_verts);
+ free(del_norms);
+ free(del_indices);
}
-void terrain_destroy(struct terrain *terrain) {
- destroy_buffer_geometry(&terrain->entity.model.geom);
+void destroy_terrain(struct terrain *terrain) {
+ struct entity *ent = get_entity(&terrain->entity_id);
+ assert(ent);
+ destroy_buffer_geometry(&ent->model.geom);
}
diff --git a/src/terrain.h b/src/terrain.h
@@ -21,7 +21,7 @@ struct perlin_settings {
struct terrain {
- struct entity entity;
+ struct entity_id entity_id;
struct perlin_settings settings;
struct point *samples;
double (*fn)(struct terrain *, double, double);
@@ -31,9 +31,10 @@ struct terrain {
double old_noisy_boi(struct terrain *, double x, double y);
-void terrain_init(struct terrain *terrain);
-void terrain_create(struct terrain *terrain);
-void terrain_destroy(struct terrain *terrain);
+void init_terrain(struct terrain *terrain, float size);
+void reset_terrain(struct terrain *terrain, float size);
+void create_terrain(struct terrain *terrain);
+void destroy_terrain(struct terrain *terrain);
#endif /* POLYADVENT_TERRAIN_H */
diff --git a/src/update.c b/src/update.c
@@ -84,73 +84,73 @@ static void remap_samples(struct point *points, int n_samples,
}
}
-void update_terrain(struct game *game) {
- static int first = 1;
- static float last_scale = -1.0;
-
- struct perlin_settings *ts = &game->terrain.settings;
- struct node *tnode = &game->terrain.entity.node;
- struct terrain *terrain = &game->terrain;
-
- printf("updating terrain\n");
-
- if (first) {
- terrain_init(terrain);
- tnode->pos[0] = rand_0to1() * 100000.0;
- tnode->pos[1] = rand_0to1() * 100000.0;
- first = 0;
- }
-
- ts->ox = tnode->pos[0];
- ts->oy = tnode->pos[1];
+void update_terrain(struct terrain *terrain) {
+ static int first = 1;
+ static float last_scale = -1.0;
+
+ struct entity *ent = get_entity(&terrain->entity_id);
+ assert(ent);
+ struct perlin_settings *ts = &terrain->settings;
+ struct node *tnode = &ent->node;
+
+ printf("updating terrain\n");
+
+ if (first) {
+ reset_terrain(terrain, terrain->size);
+ tnode->pos[0] = rand_0to1() * terrain->size;
+ tnode->pos[1] = rand_0to1() * terrain->size;
+ first = 0;
+ }
- double scale = tnode->pos[2] * 0.0015;
- if (scale == 0) scale = 1.0;
+ ts->ox = tnode->pos[0];
+ ts->oy = tnode->pos[1];
- printf("terrain %f %f %f\n", tnode->pos[0], tnode->pos[1], tnode->pos[2]);
+ double scale = tnode->pos[2] * 0.0015;
+ if (scale == 0) scale = 1.0;
- /* ts.o1s = fabs(sin(1/n) * 0.25); */
- /* ts.o1 = fabs(cos(n*0.2) * 0.5); */
- /* ts.o2s = fabs(cos(n+2) * 0.5); */
- /* ts.o2 = fabs(sin(n*0.02) * 2); */
- ts->freq = scale * 0.05;
- ts->amplitude = 50.0;
+ printf("terrain %f %f %f\n", tnode->pos[0], tnode->pos[1], tnode->pos[2]);
- if (terrain->fn)
- terrain_destroy(&game->terrain);
+ /* ts.o1s = fabs(sin(1/n) * 0.25); */
+ /* ts.o1 = fabs(cos(n*0.2) * 0.5); */
+ /* ts.o2s = fabs(cos(n+2) * 0.5); */
+ /* ts.o2 = fabs(sin(n*0.02) * 2); */
+ ts->freq = scale * 0.05;
+ ts->amplitude = 50.0;
+ /* if (terrain->fn) */
+ /* destroy_terrain(terrain); */
- /* const double pdist = min(5.0, max(1.1, 1.0/scale*1.4)); */
+ /* const double pdist = min(5.0, max(1.1, 1.0/scale*1.4)); */
- /* printf("pdist %f\n", pdist); */
+ /* printf("pdist %f\n", pdist); */
- if (last_scale == -1.0 || fabs(scale - last_scale) > 0.00001) {
- printf("generating new samples\n");
+ if (last_scale == -1.0 || fabs(scale - last_scale) > 0.00001) {
+ printf("generating new samples\n");
- if (terrain->samples)
- free(terrain->samples);
+ if (terrain->samples)
+ free(terrain->samples);
- int n_samples =
- (terrain->size * game->terrain.size) / (scale * scale);
+ int n_samples =
+ (terrain->size * terrain->size) / (scale * scale);
- /* struct point *samples = */
- /* uniform_samples(n_samples, game->terrain.size); */
+ /* struct point *samples = */
+ /* uniform_samples(n_samples, game->terrain.size); */
- static const double pdist = 24.0;
+ static const double pdist = 24.0;
- struct point *samples =
- poisson_disk_samples(pdist, game->terrain.size, 30, &n_samples);
+ struct point *samples =
+ poisson_disk_samples(pdist, terrain->size, 30, &n_samples);
- /* remap_samples(samples, n_samples, game->terrain.size); */
+ /* remap_samples(samples, n_samples, game->terrain.size); */
- /* draw_samples(samples, pdist, n_samples, game->terrain.size); */
+ /* draw_samples(samples, pdist, n_samples, game->terrain.size); */
- terrain->samples = samples;
- terrain->n_samples = n_samples;
- }
+ terrain->samples = samples;
+ terrain->n_samples = n_samples;
+ }
- last_scale = scale;
- terrain_create(&game->terrain);
+ last_scale = scale;
+ create_terrain(terrain);
}
static void player_terrain_collision(struct terrain *terrain, struct entity *player) {
@@ -161,7 +161,7 @@ static void player_terrain_collision(struct terrain *terrain, struct entity *pla
float player_z = player->node.pos[2];
float terrain_z =
- terrain->fn(terrain, player->node.pos[0], player->node.pos[1]) + 5.0;
+ terrain->fn(terrain, player->node.pos[0], player->node.pos[1]);
float inset =
min(0.0, player_z - terrain_z);
@@ -172,9 +172,8 @@ static void player_terrain_collision(struct terrain *terrain, struct entity *pla
}
-static void player_movement(struct game *game) {
- struct resources *res = &game->test_resources;
- movement(game, &res->player.node, 2.0);
+static void player_movement(struct game *game, struct entity *player) {
+ movement(game, &player->node, 2.0);
/* vec3 *camera_world = node_world(&res->camera); */
/* float cam_terrain_z = */
@@ -210,37 +209,36 @@ static int try_reload_shaders(struct resources *res) {
}
#endif
-void resize_fbos(struct game *game, int width, int height) {
- struct resources *res = &game->test_resources;
-
- if (res->shadow_buffer.handle) {
+void resize_fbos(struct entity *player, struct fbo *shadow_buffer,
+ float *m4_ortho, int width, int height) {
+ if (shadow_buffer->handle) {
// TODO: remove once delete_fbo deletes attachments
- glDeleteTextures(1, &res->shadow_buffer.attachments[1]);
- glDeleteRenderbuffers(1, &res->shadow_buffer.attachments[0]);
- delete_fbo(&res->shadow_buffer);
+ glDeleteTextures(1, &shadow_buffer->attachments[1]);
+ glDeleteRenderbuffers(1, &shadow_buffer->attachments[0]);
+ delete_fbo(shadow_buffer);
}
// TODO: compute better bounds based
- const float factor = 10.0;
- float left = res->player.model.geom.min[0] - factor;
- float right = res->player.model.geom.max[0] + factor;
- float bottom = res->player.model.geom.min[1] - factor;
- float top = res->player.model.geom.max[1] + factor;
+ const float factor = 50.0;
+ float left = player->model.geom.min[0] - factor;
+ float right = player->model.geom.max[0] + factor;
+ float bottom = player->model.geom.min[1] - factor;
+ float top = player->model.geom.max[1] + factor;
- const float near = -50.0;
- const float far = 50.0;
+ const float near = -80.0;
+ const float far = 80.0;
// default ortho screenspace projection
- mat4_ortho(left, right, bottom, top, near, far, res->proj_ortho);
+ mat4_ortho(left, right, bottom, top, near, far, m4_ortho);
- create_fbo(&res->shadow_buffer, width, height);
+ create_fbo(shadow_buffer, width, height );
/* fbo_attach_renderbuffer(&res->shadow_buffer, GL_DEPTH24_STENCIL8, */
/* GL_DEPTH_STENCIL_ATTACHMENT); */
/* fbo_attach_color_texture(&res->shadow_buffer); */
- fbo_attach_depth_texture(&res->shadow_buffer);
+ fbo_attach_depth_texture(shadow_buffer);
- check_fbo(&res->shadow_buffer);
+ check_fbo(shadow_buffer);
/* fbo_attach_texture(&res->shadow_buffer, GL_DEPTH_COMPONENT16, */
/* GL_DEPTH_COMPONENT, GL_DEPTH_ATTACHMENT); */
@@ -251,7 +249,7 @@ void resize_fbos(struct game *game, int width, int height) {
static void day_night_cycle(float time, struct resources *res) {
float val = time * 0.0001;
float intensity = max(0.0, vec3_dot(res->light_dir, V3(0.0, 0.0, 0.8)));
- struct entity *player = &res->player;
+ struct entity *player = get_player(res);
float light_pos[3];
@@ -296,7 +294,7 @@ static void day_night_cycle(float time, struct resources *res) {
}
static void gravity(struct game *game) {
- struct entity *player = &game->test_resources.player;
+ struct entity *player = get_player(&game->test_resources);
node_translate(&player->node, V3(0.0, 0.0, -1.0));
}
@@ -316,19 +314,21 @@ void update (struct game *game) {
static int toggle_fog = 0;
static int first = 1;
struct resources *res = &game->test_resources;
- struct node *tnode = &game->terrain.entity.node;
+ struct terrain *terrain = &game->terrain;
+ struct node *tnode = &get_entity(&terrain->entity_id)->node;
struct node *root = &game->test_resources.root;
+ struct entity *player = get_player(res);
float *time = &res->time;
float *light = res->light_dir;
gravity(game);
if (first) {
- update_terrain(game);
+ update_terrain(terrain);
first = 0;
}
- player_update(game, &res->player);
+ player_update(game, player);
if (game->input.modifiers & KMOD_LALT) {
movement(game, &res->camera, 1.0);
@@ -337,7 +337,7 @@ void update (struct game *game) {
movement(game, tnode, 5.0);
}
else {
- player_movement(game);
+ player_movement(game, player);
}
diff --git a/src/update.h b/src/update.h
@@ -5,6 +5,7 @@
#include "game.h"
void update(struct game * game);
-void resize_fbos(struct game * game, int width, int height);
+void resize_fbos(struct entity *player, struct fbo *shadow_buffer,
+ float *mat4_ortho, int width, int height);
#endif /* PA_UPDATE_H */
diff --git a/src/window.c b/src/window.c
@@ -14,7 +14,10 @@ handle_resize(struct game *game, int width, int height) {
mat4_perspective(75 /* fov */, (float)width / height, 1, 20000,
game->test_resources.proj_persp);
- resize_fbos(game, width, height);
+ resize_fbos(get_entity(&game->test_resources.player_id),
+ &game->test_resources.shadow_buffer,
+ game->test_resources.proj_ortho,
+ width, height);
/* glMatrixMode( GL_PROJECTION ); //Switch to setting the camera perspective */
/* Set the camera perspective */