polyadvent

A game engine from scratch in C
git clone git://jb55.com/polyadvent
Log | Files | Refs | README

commit fd4f0eb83b28587f7f457aa0cdffdab0d882361b
parent 4df7fc68011e38534b7ad9fbab4b0ba5de0f5881
Author: William Casarin <jb55@jb55.com>
Date:   Wed,  2 May 2018 20:48:46 -0700

lighting updates

Diffstat:
Metc/shaders/test.f.glsl | 23+++++++++++++----------
Metc/shaders/test.v.glsl | 13++++++++-----
Msrc/debug.c | 2+-
Msrc/game.c | 6+++---
Msrc/game.h | 4++--
Msrc/render.c | 47++++++++++++++++++++++++++++-------------------
Msrc/terrain.c | 22+++++++++++++++++-----
Msrc/update.c | 8+++++++-
8 files changed, 79 insertions(+), 46 deletions(-)

diff --git a/etc/shaders/test.f.glsl b/etc/shaders/test.f.glsl @@ -8,14 +8,14 @@ in vec3 v_ray; out vec4 fragmentColor; uniform vec3 camera_position; -uniform mat4 normal; +uniform mat4 normal_matrix; vec3 apply_fog(in vec3 rgb, in float distance, in vec3 ray_orig, in vec3 ray_dir) { - const float b = 0.00004; + const float b = 0.00002; const float v = 1.0; const float zs = 1.0; - - + + const float c = 1.0; // float fog_amount = @@ -33,19 +33,22 @@ vec3 gamma_correct(vec3 color) { void main() { float distance = length(v_ray); - + // if (distance > 1000.0) // fragmentColor = vec4(1.0, 0.0, 0.0, 0.0); // else { // fragmentColor = (vec4(v_ray, 0.0) * 0.001 - v_color) * v_light; - + // fragmentColor = v_color * (1.0 - distance*0.0001) * v_light; - + // vec3 diffuse = dot() - vec3 fog = apply_fog((v_color * v_light * 0.1).xyz, distance, camera_position, v_ray); - fragmentColor = vec4(gamma_correct(fog), 1.0); - // fragmentColor = vec4((v_color * v_light).xyz, 0.0); + vec3 frag = (v_color * v_light).xyz; + // vec3 fog = apply_fog(frag, distance, camera_position, v_ray); + vec3 color = gamma_correct(frag); + // fragmentColor = vec4(fog, 1.0); + // vec3 color = (v_color * v_light).xyz; + fragmentColor = vec4(color, 0.0); // } } diff --git a/etc/shaders/test.v.glsl b/etc/shaders/test.v.glsl @@ -1,22 +1,25 @@ #version 320 es +precision mediump float; + in vec3 position; in vec3 normal; uniform mat4 world; uniform mat4 mvp; -uniform mat4 world_normal; +uniform mat4 model_view; +uniform mat4 normal_matrix; +uniform vec3 camera_position; +uniform vec3 light_dir; flat out float v_light; flat out vec4 v_color; out vec3 v_ray; -uniform vec3 camera_position; -uniform vec3 light_dir; void main() { - vec4 trans_normal = vec4(normal, 1); + vec4 trans_normal = normal_matrix * vec4(normal, 1); vec4 v4pos = vec4(position, 1.0); gl_Position = mvp * v4pos; v_light = dot(trans_normal, vec4(light_dir, 0)); @@ -32,5 +35,5 @@ void main() else v_color = vec4(1.0, 1.0, 1.0, 1.0); - v_ray = (vec4(camera_position, 1.0) - (world * v4pos)).xyz; + v_ray = camera_position - (world * v4pos).xyz; } diff --git a/src/debug.c b/src/debug.c @@ -12,7 +12,7 @@ show_info_log(GLuint shader) { char *buffer = malloc(msgLen); glGetShaderInfoLog(shader, msgLen, &msgLen, buffer); - printf("shader error: %s\n", buffer); + printf("shader error: (%d) %.*s\n", msgLen, msgLen, buffer); free(buffer); } diff --git a/src/game.c b/src/game.c @@ -48,9 +48,9 @@ void game_init(struct game *game) { mat4_id(mvp); - light_dir[0] = 1; - light_dir[1] = 1; - light_dir[2] = 0.8; + light_dir[0] = 0.2; + light_dir[1] = 0.07; + light_dir[2] = 0.2; node_init(root); node_init(player); diff --git a/src/game.h b/src/game.h @@ -21,9 +21,9 @@ struct resources { GLint camera_position; GLint light_dir; GLint mvp; - GLint mv; - GLint normal; + GLint normal_matrix; GLint view; + GLint model_view; GLint world; } uniforms; diff --git a/src/render.c b/src/render.c @@ -102,8 +102,8 @@ init_gl(struct resources *resources, int width, int height) { mat4_perspective(90 /* fov */, (float)width / height, 1, 5000, resources->camera_persp); // Shader program - resources->program = make_program(resources->vertex_shader, - resources->fragment_shader); + resources->program = + make_program(resources->vertex_shader, resources->fragment_shader); assert(resources->program != 0); @@ -114,14 +114,17 @@ init_gl(struct resources *resources, int width, int height) { resources->uniforms.light_dir = glGetUniformLocation(resources->program, "light_dir"); + resources->uniforms.world + = glGetUniformLocation(resources->program, "world"); + resources->uniforms.mvp = glGetUniformLocation(resources->program, "mvp"); - resources->uniforms.view - = glGetUniformLocation(resources->program, "view"); + resources->uniforms.model_view + = glGetUniformLocation(resources->program, "model_view"); - resources->uniforms.world - = glGetUniformLocation(resources->program, "world"); + resources->uniforms.normal_matrix + = glGetUniformLocation(resources->program, "normal_matrix"); resources->attributes.normal = (gpu_addr)glGetAttribLocation(resources->program, "normal"); @@ -134,9 +137,11 @@ init_gl(struct resources *resources, int width, int height) { static void -recalc_normals(mat4 *mvp, mat4 *normal) { - mat4_inverse(mvp, normal); +recalc_normals(GLint nm_uniform, mat4 *model_view, mat4 *normal) { + mat4_inverse(model_view, normal); mat4_transpose(normal, normal); + /* mat4_copy(model_view, normal); */ + glUniformMatrix4fv(nm_uniform, 1, 0, normal); } @@ -188,7 +193,9 @@ void render (struct game *game, struct geometry *geom) { static float id[MAT4_ELEMS] = { 0 }; static float view[MAT4_ELEMS] = { 0 }; - static float normal[MAT4_ELEMS] = { 0 }; + static float view_proj[MAT4_ELEMS] = { 0 }; + static float normal_matrix[MAT4_ELEMS] = { 0 }; + static float model_view[MAT4_ELEMS] = { 0 }; mat4_id(id); struct resources *res = &game->test_resources; @@ -207,15 +214,10 @@ void render (struct game *game, struct geometry *geom) { /* printf("camera_pos %f %f %f", camera_pos[0], camera_pos[1], camera_pos[2]); */ /* mat4_print(camera->mat); */ /* node_recalc(&res->camera); */ - /* mat4_multiply(persp, camera->mat, mvp); */ mat4_inverse(camera->mat, view); - mat4_multiply(persp, view, mvp); - recalc_normals(mvp, normal); - check_gl(); - glUniformMatrix4fv(res->uniforms.normal, 1, 0, normal); + mat4_multiply(persp, view, view_proj); /* mat4_multiply(mvp, tmp_matrix, tmp_matrix); */ - glUniformMatrix4fv(res->uniforms.view, 1, 0, view); glUniform3f(res->uniforms.camera_position, camera->mat[M_X], camera->mat[M_Y], @@ -224,16 +226,23 @@ void render (struct game *game, struct geometry *geom) { glUniform3f(res->uniforms.light_dir, light[0], light[1], light[2]); //player - mat4_multiply(mvp, player->mat, tmp_matrix); - glUniformMatrix4fv(res->uniforms.mvp, 1, 0, tmp_matrix); + mat4_multiply(view_proj, player->mat, mvp); + mat4_multiply(view, player->mat, model_view); + glUniformMatrix4fv(res->uniforms.mvp, 1, 0, mvp); + glUniformMatrix4fv(res->uniforms.model_view, 1, 0, model_view); glUniformMatrix4fv(res->uniforms.world, 1, 0, player->mat); - /* mat4_multiply(persp, tmp_matrix, mvp); */ - /* mat4_print(player->mat); */ + recalc_normals(res->uniforms.normal_matrix, model_view, normal_matrix); render_cube(res); // terrain + mat4_copy(view_proj, mvp); + mat4_copy(view, model_view); + glUniformMatrix4fv(res->uniforms.mvp, 1, 0, mvp); + glUniformMatrix4fv(res->uniforms.model_view, 1, 0, id); glUniformMatrix4fv(res->uniforms.world, 1, 0, id); + glUniformMatrix4fv(res->uniforms.normal_matrix, 1, 0, id); + /* recalc_normals(res->uniforms.normal_matrix, model_view, normal_matrix); */ render_geom(res, geom, GL_TRIANGLES); /* glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); */ /* render_geom(res, geom, GL_TRIANGLES); */ diff --git a/src/terrain.c b/src/terrain.c @@ -30,12 +30,13 @@ double old_noisy_boi(struct terrain *t, double x, double y) { return pow(e, s->exp) * s->amplitude; } -void deriv(double (*noisefn)(void*, double, double), void* data, double x, - double y, double z1, double *dx, double *dy) +typedef double (*noisefn)(void*,double,double); + +void deriv(noisefn fn, void* data, double x, double y, double z1, double *dx, double *dy) { static const double h = 0.01; - double zx = noisefn(data, x + h, y); - double zy = noisefn(data, x, y - h); + double zx = fn(data, x + h, y); + double zy = fn(data, x, y - h); *dx = (zx - z1)/h; *dy = (zy - z1)/h; } @@ -64,13 +65,14 @@ terrain_create(struct terrain *terrain) { 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 x, y, dx, dy; x = terrain->samples[i].x; y = terrain->samples[i].y; @@ -128,6 +130,16 @@ terrain_create(struct terrain *terrain) { 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); */ + vec3_subtract(v[1], v[0], tmp1); vec3_subtract(v[2], v[0], tmp2); vec3_cross(tmp1, tmp2, tmp2); diff --git a/src/update.c b/src/update.c @@ -195,7 +195,7 @@ void update (struct game *game, u32 dt) { } } - if (space_down || passed < last_gen_time) { + if (space_down || passed < 50) { passed += dt; } else { passed = 0; @@ -205,6 +205,7 @@ void update (struct game *game, u32 dt) { bool changed = last_ox != ox || last_oy != oy || last_oz != tnode->pos[2]; + if (!stopped && changed) { int t1 = SDL_GetTicks(); update_terrain(game); @@ -219,5 +220,10 @@ void update (struct game *game, u32 dt) { } + /* res->light_dir[0] = fabs(cos(n)*0.2); */ + /* res->light_dir[1] = fabs(cos(n+50.0)*0.07); */ + /* res->light_dir[2] = fabs(cos(n+100.0)*0.2); */ + /* n += 0.01f; */ + node_recalc(root); }