polyadvent

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

commit dcf01285acec1b3b5d3ee1da827979d535c1512b
parent e88c7101e0ae07146c48c314a4723e3190527505
Author: William Casarin <jb55@jb55.com>
Date:   Fri,  9 Nov 2018 20:08:36 -0800

env mapping

Diffstat:
Metc/shaders/standard_vtxos.glsl | 6+++---
Metc/shaders/test.f.glsl | 22+++++++++++++---------
Metc/shaders/uniforms.glsl | 2+-
Msrc/entity.h | 3++-
Msrc/game.c | 6++++--
Msrc/game.h | 20++++++++++----------
Msrc/geometry.c | 6+++---
Msrc/render.c | 39++++++++++++++++++++-------------------
Msrc/update.c | 16+++++++++-------
Msrc/window.c | 2+-
10 files changed, 66 insertions(+), 56 deletions(-)

diff --git a/etc/shaders/standard_vtxos.glsl b/etc/shaders/standard_vtxos.glsl @@ -1,7 +1,7 @@ vec4 v4_pos = vec4(position, 1.0); -data_out.normal = normal; -data_out.position = position; +data_out.normal = mat3(transpose(inverse(model))) * normal; +data_out.position = vec3(model * v4_pos); data_out.color_smooth = data_out.color = color; data_out.shadow_coord = depth_mvp * v4_pos; -data_out.frag_pos = (world * v4_pos).xyz; +data_out.frag_pos = (model * v4_pos).xyz; // TODO: move shadow coord calc from frag to here diff --git a/etc/shaders/test.f.glsl b/etc/shaders/test.f.glsl @@ -9,6 +9,7 @@ in shader_data { } vertex; uniform sampler2D shadow_map; +uniform samplerCube skybox; #include lighting.glsl #include shadows.glsl @@ -21,15 +22,18 @@ void main() { // vec3 color = vertex.color * (1.0-smoothness) // + color_smooth * smoothness; - 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); - // vec3 fog = depth_fog(color, shadow_sample); - color = fog; - } - - color *= shadow_strength(v4_pos, v4_normal, vertex.shadow_coord); + // 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); + // // vec3 fog = depth_fog(color, shadow_sample); + // color = fog; + // } + + // color *= shadow_strength(v4_pos, v4_normal, vertex.shadow_coord); + vec3 I = normalize(vertex.position - camera_position); + vec3 R = reflect(I, normalize(vertex.normal)); + vec3 color = texture(skybox, R).rgb; frag_color = vec4(gamma_correct(color), 1.0); } diff --git a/etc/shaders/uniforms.glsl b/etc/shaders/uniforms.glsl @@ -5,9 +5,9 @@ uniform float sky_intensity; uniform float light_intensity; uniform mat4 depth_mvp; // uniform mat4 depth_vp; +uniform mat4 model; uniform mat4 mvp; uniform mat4 normal_matrix; -uniform mat4 world; // uniform float time; // uniform float ambient_str; uniform vec3 sun_color; diff --git a/src/entity.h b/src/entity.h @@ -6,7 +6,8 @@ #include "model.h" enum entity_flags { - ENT_FLAG_PLAYER = 1 << 0, + ENT_IS_PLAYER = 1 << 0, + ENT_INVISIBLE = 1 << 1, }; struct entity { diff --git a/src/game.c b/src/game.c @@ -75,6 +75,8 @@ void game_init(struct game *game, int width, int height) { check_gl(); init_terrain(terrain, size); + get_entity(&terrain->entity_id)->flags |= ENT_INVISIBLE; + create_skybox(&res->skybox, &res->programs[SKYBOX_PROGRAM]); /* node_translate(&res->skybox.node, V3(-100.0, -100.0, 0.0)); */ /* node_scale(&res->skybox.node, size/4.0); */ @@ -107,7 +109,7 @@ void game_init(struct game *game, int width, int height) { // player entity player = new_entity(&res->player_id); - ok = load_model(&player->model, "pirate-officer"); + ok = load_model(&player->model, "ico-sphere"); assert(ok); player->node.label = "player"; node_attach(&player->node, root); @@ -117,7 +119,7 @@ void game_init(struct game *game, int width, int height) { res->camera.coords.azimuth = -quat_yaw(player->node.orientation) - RAD(90.0); res->camera.coords.inclination = RAD(60); - res->camera.coords.radius = 100.0; + res->camera.coords.radius = 2.0; struct entity *tower = new_entity(NULL); ok = load_model(&tower->model, "tower"); diff --git a/src/game.h b/src/game.h @@ -38,22 +38,22 @@ struct resources { struct gpu_program programs[NUM_PROGRAMS]; struct uniforms { + GLint ambient_str; GLint camera_position; + GLint depth_mvp; + GLint depth_vp; + GLint diffuse_on; + GLint fog_on; GLint light_dir; GLint light_intensity; - GLint sky_intensity; - GLint ambient_str; - GLint sun_color; + GLint model; + GLint model_view; GLint mvp; - GLint depth_mvp; - GLint depth_vp; GLint normal_matrix; - GLint view; + GLint sky_intensity; + GLint sun_color; GLint time; - GLint fog_on; - GLint diffuse_on; - GLint model_view; - GLint world; + GLint view_proj; } uniforms; struct attributes attributes; diff --git a/src/geometry.c b/src/geometry.c @@ -27,15 +27,15 @@ destroy_buffer_geometry(struct geometry *geom) { void bind_geometry(struct geometry *geom, struct attributes *attrs) { bind_vbo(&geom->vbos.vertex, attrs->position); check_gl(); - if (geom->vbos.normal.handle) { + if (geom->vbos.normal.handle && attrs->normal != 0xFFFFFFFF) { bind_vbo(&geom->vbos.normal, attrs->normal); check_gl(); } - if (geom->vbos.color.handle) { + if (geom->vbos.color.handle && attrs->color != 0xFFFFFFFF) { bind_vbo(&geom->vbos.color, attrs->color); check_gl(); } - if (geom->vbos.tex_coord.handle) { + if (geom->vbos.tex_coord.handle && attrs->tex_coord != 0xFFFFFFFF) { bind_vbo(&geom->vbos.tex_coord, attrs->tex_coord); check_gl(); } diff --git a/src/render.c b/src/render.c @@ -175,10 +175,6 @@ check_gl(); glGetUniformLocation(handle, "sun_color"); check_gl(); - resources->uniforms.world = - glGetUniformLocation(handle, "world"); - check_gl(); - resources->uniforms.fog_on = glGetUniformLocation(handle, "fog_on"); check_gl(); @@ -187,6 +183,10 @@ check_gl(); /* glGetUniformLocation(handle, "diffuse_on"); */ /* check_gl(); */ + resources->uniforms.model = + glGetUniformLocation(handle, "model"); + check_gl(); + resources->uniforms.mvp = glGetUniformLocation(handle, "mvp"); check_gl(); @@ -212,6 +212,7 @@ check_gl(); resources->attributes.color = (gpu_addr)glGetAttribLocation(resources->programs[DEFAULT_PROGRAM] .handle, "color"); + /* assert(resources->attributes.color != 0xFFFFFFFF); */ check_gl(); } @@ -289,8 +290,14 @@ void render (struct game *game, struct render_config *config) { mat4_inverse(camera, view); mat4_multiply(projection, view, view_proj); - for (u32 i = 1; i < num_entities; ++i) { + glBindTexture(GL_TEXTURE_CUBE_MAP, res->skybox.model.texture); + + for (u32 i = 0; i < num_entities; ++i) { struct entity *entity = &entities[i]; + + if (entity->flags & ENT_INVISIBLE) + continue; + if (config->is_depth_pass && !entity->casts_shadows) continue; @@ -307,16 +314,16 @@ void render (struct game *game, struct render_config *config) { glUniform1i(res->uniforms.fog_on, res->fog_on); check_gl(); - /* glUniform1i(res->uniforms.diffuse_on, res->diffuse_on); */ - /* check_gl(); */ + glUniform3f(res->uniforms.light_dir, light[0], light[1], light[2]); check_gl(); + glUniform1f(res->uniforms.light_intensity, res->light_intensity); check_gl(); - /* glUniform1f(res->uniforms.time, res->time); */ - check_gl(); + glUniform1f(res->uniforms.sky_intensity, sky_intensity); check_gl(); + glUniform3f(res->uniforms.sun_color, res->sun_color[0], res->sun_color[1], @@ -325,20 +332,14 @@ void render (struct game *game, struct render_config *config) { mat4_multiply(view_proj, entity->node.mat, mvp); mat4_copy(entity->node.mat, model_view); - - /* if (i == 1) */ - /* mat4_multiply(bias_matrix, mvp, config->depth_mvp); */ mat4_multiply(config->depth_vp, model_view, depth_mvp); + glUniformMatrix4fv(res->uniforms.depth_mvp, 1, 0, depth_mvp); + check_gl(); glUniformMatrix4fv(res->uniforms.mvp, 1, 0, mvp); 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); + + glUniformMatrix4fv(res->uniforms.model, 1, 0, entity->node.mat); check_gl(); recalc_normals(res->uniforms.normal_matrix, model_view, normal_matrix); diff --git a/src/update.c b/src/update.c @@ -176,14 +176,16 @@ static void player_terrain_collision(struct terrain *terrain, struct entity *pla static void player_movement(struct game *game, struct entity *player) { movement(game, &player->node, 2.0); - vec3 *camera_world = node_world(&game->test_resources.camera.node); - float cam_terrain_z = - game->terrain.fn(&game->terrain, camera_world[0], camera_world[1]); + if (!(get_entity(&game->terrain.entity_id)->flags & ENT_INVISIBLE)) { + vec3 *camera_world = node_world(&game->test_resources.camera.node); + float cam_terrain_z = + game->terrain.fn(&game->terrain, camera_world[0], camera_world[1]); - const float bias = 20.0; + const float bias = 20.0; - if (camera_world[2] < cam_terrain_z + bias) - camera_world[2] = cam_terrain_z + bias; + if (camera_world[2] < cam_terrain_z + bias) + camera_world[2] = cam_terrain_z + bias; + } } @@ -309,7 +311,7 @@ void orbit_update_from_mouse(struct orbit *camera, struct input *input, node_recalc(target_node); vec3_copy(node_world(target_node), target); - /* vec3_add(target, V3(0.0, 0.0, 100.0), target); */ + vec3_add(target, V3(0.0, 0.0, player->model.geom.max[2]), target); float mx = 0.0, my = 0.0; if (input_is_dragging(input, SDL_BUTTON_LEFT) || diff --git a/src/window.c b/src/window.c @@ -11,7 +11,7 @@ void handle_resize(struct game *game, int width, int height) { /* printf("resizing %d %d\n", width, height); */ glViewport( 0, 0, width, height ); - mat4_perspective(75 /* fov */, (float)width / height, 10.0, 10000.0, + mat4_perspective(75 /* fov */, (float)width / height, 1.0, 10000.0, game->test_resources.proj_persp); resize_fbos(get_entity(&game->test_resources.player_id),