polyadvent

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

commit bbc32c2710ea83011c69100784d8dc284554270a
parent b8699114390f7d006277084c73f04e9a39d3d87e
Author: William Casarin <jb55@jb55.com>
Date:   Fri,  2 Nov 2018 01:51:10 -0700

geom shader kinda working

Diffstat:
Metc/shaders/fog.glsl | 1+
Metc/shaders/lighting.glsl | 3+--
Aetc/shaders/profile | 1+
Aetc/shaders/shadervars.glsl | 14++++++++++++++
Metc/shaders/standard_vtxos.glsl | 5++---
Aetc/shaders/terrain.g.glsl | 40++++++++++++++++++++++++++++++++++++++++
Aetc/shaders/terrain.tc.glsl | 35+++++++++++++++++++++++++++++++++++
Aetc/shaders/terrain.te.glsl | 32++++++++++++++++++++++++++++++++
Aetc/shaders/terrain.v.glsl | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Metc/shaders/test.f.glsl | 12+-----------
Metc/shaders/uniforms.glsl | 6+++---
Metc/shaders/vertex-color.glsl | 9+++++----
Msrc/buffer.c | 2++
Msrc/geometry.c | 7+++++--
Msrc/geometry.h | 1+
Msrc/gl.h | 3+++
Msrc/main.c | 6+++++-
Msrc/render.c | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
Msrc/shader.c | 5++---
19 files changed, 275 insertions(+), 46 deletions(-)

diff --git a/etc/shaders/fog.glsl b/etc/shaders/fog.glsl @@ -8,6 +8,7 @@ vec3 apply_fog(in vec3 rgb, in float distance, in vec3 ray_orig, in vec3 ray_dir // sun_amount = pow(sun_amount, 0.0); vec3 fog_color = sun_color * sky_intensity; + // vec3 fog_color = sun_color; // vec3 fog_color = mix(vec3(0.5,0.6,0.7), // vec3(1.0,0.9,0.8), diff --git a/etc/shaders/lighting.glsl b/etc/shaders/lighting.glsl @@ -20,8 +20,7 @@ vec3 gamma_correct(vec3 color) { } vec3 standard_light(vec3 color, vec3 position, vec3 normal) { - vec4 v4_normal = vec4(normal, 1); - vec4 trans_normal = normal_matrix * v4_normal; + vec4 trans_normal = vec4(normal, 1); // vec3 light_dir = vec3() const float pi = 3.14159265; diff --git a/etc/shaders/profile b/etc/shaders/profile @@ -0,0 +1 @@ +#version 440 core diff --git a/etc/shaders/shadervars.glsl b/etc/shaders/shadervars.glsl @@ -0,0 +1,14 @@ +flat vec3 color; +vec3 color_smooth; +vec3 normal; +vec3 position; +vec4 shadow_coord; +vec3 frag_pos; + +// out flat vec3 v_color; +// out vec3 v_color_smooth; +// out vec3 v_ray; +// out vec3 v_normal; +// out vec3 v_position; +// out vec4 v_shadow_coord; +// out vec3 v_frag_pos; diff --git a/etc/shaders/standard_vtxos.glsl b/etc/shaders/standard_vtxos.glsl @@ -1,7 +1,6 @@ vec4 v4_pos = vec4(position, 1.0); -gl_Position = mvp * v4_pos; vertex.normal = normal; -vertex.color = vertex.color_smooth = color; +vertex.color_smooth = vertex.color = color; vertex.shadow_coord = depth_mvp * v4_pos; -vertex.position = position; +vertex.position = v4_pos.xyz; vertex.frag_pos = (world * v4_pos).xyz; diff --git a/etc/shaders/terrain.g.glsl b/etc/shaders/terrain.g.glsl @@ -0,0 +1,40 @@ +#include profile + +layout (triangles) in; +layout (triangle_strip, max_vertices = 3) out; + +layout(location = 10) in v_data { +#include shadervars.glsl +} vertices[]; + +out shader_data { +#include shadervars.glsl +} vertex; + +#include uniforms.glsl + +void main() { + int i; + + for(i = 0;i < gl_in.length();i++)// gl_in.length() = 1 though! + { + vec4 v4_pos = vec4(vertices[i].position, 1.0); + vertex.position = vertices[i].position; + 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.frag_pos = (world * v4_pos).xyz; + vertex.shadow_coord = vertices[i].shadow_coord; + vertex.frag_pos = vertices[i].frag_pos; + + gl_Position = gl_in[i].gl_Position; + // gl_Position = vec4(vertices[i].position, 1.0); + + EmitVertex(); + } + + EndPrimitive(); + + +} diff --git a/etc/shaders/terrain.tc.glsl b/etc/shaders/terrain.tc.glsl @@ -0,0 +1,35 @@ +#include profile + +layout(vertices = 3) out; + +in shader_data { +#include shadervars.glsl +} vertex[]; + +out shader_data { +#include shadervars.glsl +} tc_vertices[]; + +#include uniforms.glsl + +// uniform float TessLevelInner; +// uniform float TessLevelOuter; + + +void main() +{ + tc_vertices[gl_InvocationID].position = vertex[gl_InvocationID].position; + tc_vertices[gl_InvocationID].color = vertex[gl_InvocationID].color; + tc_vertices[gl_InvocationID].color_smooth = vertex[gl_InvocationID].color_smooth; + tc_vertices[gl_InvocationID].normal = vertex[gl_InvocationID].normal; + + const float inner = 5.0; + const float outer = 8.0; + if (gl_InvocationID == 0) { + gl_TessLevelInner[0] = inner; + gl_TessLevelOuter[0] = outer; + gl_TessLevelOuter[1] = outer; + gl_TessLevelOuter[2] = outer; + } + gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position; +} diff --git a/etc/shaders/terrain.te.glsl b/etc/shaders/terrain.te.glsl @@ -0,0 +1,32 @@ +#include profile + +layout(triangles, equal_spacing, cw) in; + +in shader_data { +#include shadervars.glsl +} tc_vertices[]; + +out shader_data { +#include shadervars.glsl +} vertex; + +#include uniforms.glsl + +// out vec3 tePatchDistance = gl_TessCoord; + + +void main() +{ + vertex.color = tc_vertices[0].color; + vertex.color_smooth = tc_vertices[0].color_smooth; + vertex.normal = tc_vertices[0].normal; + vertex.shadow_coord = tc_vertices[0].shadow_coord; + + vec4 p0 = gl_TessCoord.x * gl_in[0].gl_Position; + vec4 p1 = gl_TessCoord.y * gl_in[1].gl_Position; + vec4 p2 = gl_TessCoord.z * gl_in[2].gl_Position; + // tePatchDistance = gl_TessCoord; + vec4 te_position = normalize(p0 + p1 + p2); + vertex.position = te_position.xyz; + gl_Position = te_position; +} diff --git a/etc/shaders/terrain.v.glsl b/etc/shaders/terrain.v.glsl @@ -0,0 +1,52 @@ +#include profile + +precision mediump float; + +in vec3 position; +in vec3 normal; + +#include uniforms.glsl + +layout(location = 10) out v_data { +#include shadervars.glsl +} vertices; + + +void main() +{ + const int nlands = 6; + + + const vec4 land[nlands] = vec4[]( + vec4(0.0, 0.5, 0.79, 0.0), // 0 - water + vec4(0.9176, 0.8156, 0.6588, 1.0), // 1 - sand + vec4(0.7, 0.7, 0.156, 2.0), // 2 - grass + vec4(0.4627, 0.3333, 0.1686, 20.0), // 3 - dirt + vec4(0.5, 0.5, 0.5, 80.0), // 4 - stone + vec4(1.0, 1.0, 1.0, 380.0) // 5 - snow + ); + + vec3 color = land[0].xyz; + for (int i = 0; i < nlands-1; i++) { + color = + mix(color, + land[i+1].xyz, + smoothstep(land[i].w, land[i+1].w, position.z)); + } + + // vec3 color = vec3(position.z*0.05, position.z*0.0095, position.z*0.0001) * 0.5; + + + // v_color = vec3(position.z, position.z, position.z) * 0.005; + +// #include standard_vtxos.glsl + vec4 v4_pos = vec4(position, 1.0); + vertices.normal = normal; + vertices.color_smooth = vertices.color = color; + vertices.shadow_coord = depth_mvp * v4_pos; + vertices.position = v4_pos.xyz; + vertices.frag_pos = (world * v4_pos).xyz; + + gl_Position = mvp * v4_pos; + vertices.position = gl_Position.xyz; +} diff --git a/etc/shaders/test.f.glsl b/etc/shaders/test.f.glsl @@ -1,23 +1,13 @@ #include profile -precision mediump float; - out vec4 frag_color; #include uniforms.glsl -in f_data { +in shader_data { #include shadervars.glsl } vertex; -// in flat vec3 v_color; -// in vec3 v_color_smooth; -// in vec3 v_ray; -// in vec3 v_normal; -// in vec3 v_position; -// in vec4 v_shadow_coord; -// in vec3 v_frag_pos; - uniform sampler2D shadow_map; #include lighting.glsl diff --git a/etc/shaders/uniforms.glsl b/etc/shaders/uniforms.glsl @@ -1,14 +1,14 @@ uniform bool diffuse_on; uniform bool fog_on; -uniform float light_intensity; uniform float sky_intensity; +uniform float light_intensity; uniform mat4 depth_mvp; -uniform mat4 model_view; +// uniform mat4 model_view; uniform mat4 mvp; uniform mat4 normal_matrix; uniform mat4 world; -uniform float time; +// uniform float time; // uniform float ambient_str; uniform vec3 sun_color; uniform vec3 camera_position; diff --git a/etc/shaders/vertex-color.glsl b/etc/shaders/vertex-color.glsl @@ -4,15 +4,16 @@ in vec3 position; in vec3 normal; in vec3 color; -#include uniforms.glsl - -out f_data { +out shader_data { #include shadervars.glsl } vertex; -flat out vec3 v_color; +#include uniforms.glsl + void main() { #include standard_vtxos.glsl + + gl_Position = mvp * v4_pos; } diff --git a/src/buffer.c b/src/buffer.c @@ -45,7 +45,9 @@ void bind_ibo(struct vbo *vbo) { static void bind_vbo_internal(struct vbo *vbo, gpu_addr slot, int size) { glEnableVertexAttribArray(slot); + check_gl(); glBindBuffer(vbo->type, vbo->handle); + check_gl(); glVertexAttribPointer(slot, // attribute size, // size GL_FLOAT, // type diff --git a/src/geometry.c b/src/geometry.c @@ -24,8 +24,7 @@ destroy_buffer_geometry(struct geometry *geom) { check_gl(); } -void render_geometry(struct geometry *geom, struct attributes *attrs) -{ +void bind_geometry(struct geometry *geom, struct attributes *attrs) { bind_vbo(&geom->vbos.vertex, attrs->position); check_gl(); if (geom->vbos.normal.handle) { @@ -42,7 +41,11 @@ void render_geometry(struct geometry *geom, struct attributes *attrs) } bind_ibo(&geom->vbos.index); check_gl(); +} +void render_geometry(struct geometry *geom, struct attributes *attrs) +{ + bind_geometry(geom, attrs); glDrawElements(GL_TRIANGLES, geom->num_indices, /* count */ GL_UNSIGNED_INT, /* type */ diff --git a/src/geometry.h b/src/geometry.h @@ -25,6 +25,7 @@ struct geometry { }; void render_geometry(struct geometry *geom, struct attributes *); +void bind_geometry(struct geometry *geom, struct attributes *); void init_geometry(struct geometry *geom); void make_buffer_geometry(struct geometry *geom); void destroy_buffer_geometry(struct geometry *geom); diff --git a/src/gl.h b/src/gl.h @@ -97,4 +97,7 @@ void glFramebufferTexture( GLenum target, GLuint texture, GLint level); +void glPatchParameteri( GLenum pname, + GLint value); + #endif /* POLYADVENT_GL_H */ diff --git a/src/main.c b/src/main.c @@ -35,10 +35,14 @@ int main(void) int width = 640; int height = 480; + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + SDL_Window *window = SDL_CreateWindow( "SDL2/OpenGL Demo", 0, 0, width, height, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE); + SDL_GL_CreateContext(window); game_init(&game, width, height); @@ -56,7 +60,7 @@ int main(void) }; struct render_config default_config = { - .draw_ui = 0, + .draw_ui = 1, .is_depth_pass = 0, .camera = game.test_resources.camera.mat, .projection = game.test_resources.proj_persp, diff --git a/src/render.c b/src/render.c @@ -63,6 +63,7 @@ static const float bias_matrix[] = { void init_gl(struct resources *resources, int width, int height) { struct shader vertex, terrain_vertex, terrain_geom, fragment, fragment_smooth; + struct shader terrain_teval, terrain_tc; float tmp_matrix[16]; int ok = 0; @@ -82,6 +83,14 @@ init_gl(struct resources *resources, int width, int height) { &terrain_geom); assert(ok && "terrain geometry shader"); + ok = make_shader(GL_TESS_CONTROL_SHADER, SHADER("terrain.tc.glsl"), + &terrain_tc); + assert(ok && "terrain tessellation control shader"); + + ok = make_shader(GL_TESS_EVALUATION_SHADER, SHADER("terrain.te.glsl"), + &terrain_teval); + assert(ok && "terrain tessellation eval shader"); + ok = make_shader(GL_FRAGMENT_SHADER, SHADER("test.f.glsl"), &fragment); assert(ok && "default fragment shader"); @@ -92,9 +101,18 @@ init_gl(struct resources *resources, int width, int height) { 5000, resources->proj_persp); - // Shader program - struct shader *shaders[] = { &terrain_vertex, &fragment, &terrain_geom }; - ok = make_program_from_shaders(shaders, 3, &resources->programs[TERRAIN_PROGRAM]); + /* Shader program */ + /* struct shader *terrain_shaders[] = */ + /* { &terrain_vertex, &fragment, &terrain_tc, &terrain_teval, */ + /* &terrain_geom }; */ + + struct shader *terrain_shaders[] = + { &terrain_vertex, &fragment, &terrain_geom }; + + /* struct shader *terrain_shaders[] = */ + /* { &terrain_vertex, &fragment }; */ + ok = make_program_from_shaders(terrain_shaders, ARRAY_SIZE(terrain_shaders), + &resources->programs[TERRAIN_PROGRAM]); assert(ok && "terrain program"); check_gl(); @@ -115,51 +133,62 @@ init_gl(struct resources *resources, int width, int height) { // Program variables resources->uniforms.camera_position = glGetUniformLocation(handle, "camera_position"); - - resources->uniforms.ambient_str = - glGetUniformLocation(handle, "ambient_str"); + check_gl(); resources->uniforms.depth_mvp = glGetUniformLocation(handle, "depth_mvp"); + check_gl(); resources->uniforms.light_intensity = glGetUniformLocation(handle, "light_intensity"); + check_gl(); resources->uniforms.sky_intensity = glGetUniformLocation(handle, "sky_intensity"); + check_gl(); resources->uniforms.time = glGetUniformLocation(handle, "time"); + check_gl(); resources->uniforms.light_dir = glGetUniformLocation(handle, "light_dir"); + check_gl(); resources->uniforms.sun_color = glGetUniformLocation(handle, "sun_color"); + check_gl(); resources->uniforms.world = glGetUniformLocation(handle, "world"); + check_gl(); resources->uniforms.fog_on = glGetUniformLocation(handle, "fog_on"); + check_gl(); resources->uniforms.diffuse_on = glGetUniformLocation(handle, "diffuse_on"); + check_gl(); resources->uniforms.mvp = glGetUniformLocation(handle, "mvp"); + check_gl(); - resources->uniforms.model_view = - glGetUniformLocation(handle, "model_view"); + /* resources->uniforms.model_view = */ + /* glGetUniformLocation(handle, "model_view"); */ resources->uniforms.normal_matrix = glGetUniformLocation(handle, "normal_matrix"); + check_gl(); resources->attributes.normal = (gpu_addr)glGetAttribLocation(handle, "normal"); + check_gl(); resources->attributes.position = (gpu_addr)glGetAttribLocation(handle, "position"); + check_gl(); } @@ -167,7 +196,6 @@ init_gl(struct resources *resources, int width, int height) { resources->attributes.color = (gpu_addr)glGetAttribLocation(resources->programs[DEFAULT_PROGRAM] .handle, "color"); - check_gl(); } @@ -200,7 +228,7 @@ void render (struct game *game, struct render_config *config) { glClearColor( gtmp[0], gtmp[1], gtmp[2], 1.0 ); //clear background screen to black /* glClearColor( 0.5294f * adjust, 0.8078f * adjust, 0.9216f * adjust, 1.0f ); //clear background screen to black */ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); - /* glEnable(GL_CULL_FACE); */ + glDisable(GL_CULL_FACE); check_gl(); @@ -233,6 +261,7 @@ void render (struct game *game, struct render_config *config) { if (config->is_depth_pass && !entity->casts_shadows) continue; // TODO this is a bit wonky, refactor this + if (i == 0) glUseProgram(terrain_program); else if (i == 1) @@ -244,43 +273,67 @@ void render (struct game *game, struct render_config *config) { if (config->is_depth_pass) { mat4_multiply(bias_matrix, view_proj, config->depth_mvp); - glCullFace(GL_FRONT); + /* glCullFace(GL_FRONT); */ } else { glUniformMatrix4fv(res->uniforms.depth_mvp, 1, 0, config->depth_mvp); - glCullFace(GL_BACK); + /* glCullFace(GL_BACK); */ } + check_gl(); glUniform3f(res->uniforms.camera_position, camera[M_X], camera[M_Y], camera[M_Z]); + printf("%d depth ? %d\n", (int)i, config->is_depth_pass); glUniform1i(res->uniforms.fog_on, res->fog_on); glUniform1i(res->uniforms.diffuse_on, res->diffuse_on); glUniform3f(res->uniforms.light_dir, light[0], light[1], light[2]); glUniform1f(res->uniforms.light_intensity, res->light_intensity); - glUniform1f(res->uniforms.time, res->time); + check_gl(); + printf("light_intensity uniform %d\n", res->uniforms.light_intensity); + /* glUniform1f(res->uniforms.time, res->time); */ + check_gl(); + printf("sky_intensity uniform %d\n", res->uniforms.sky_intensity); glUniform1f(res->uniforms.sky_intensity, sky_intensity); + check_gl(); glUniform3f(res->uniforms.sun_color, res->sun_color[0], res->sun_color[1], res->sun_color[2]); - + check_gl(); mat4_multiply(view_proj, entity->node.mat, mvp); mat4_copy(entity->node.mat, model_view); glUniformMatrix4fv(res->uniforms.mvp, 1, 0, mvp); + check_gl(); glUniformMatrix4fv(res->uniforms.depth_mvp, 1, 0, config->depth_mvp); - glUniformMatrix4fv(res->uniforms.model_view, 1, 0, model_view); + check_gl(); + /* glUniformMatrix4fv(res->uniforms.model_view, 1, 0, model_view); */ + check_gl(); glUniformMatrix4fv(res->uniforms.world, 1, 0, entity->node.mat); + check_gl(); recalc_normals(res->uniforms.normal_matrix, model_view, normal_matrix); + check_gl(); - render_geometry(&entity->model.geom, &res->attributes); + if (i != 0) { + render_geometry(&entity->model.geom, &res->attributes); + check_gl(); + } + else { + /* glPatchParameteri(GL_PATCH_VERTICES, 3); */ + check_gl(); + bind_geometry(&entity->model.geom, &res->attributes); + check_gl(); + glDrawElements(GL_TRIANGLES, + entity->model.geom.num_indices, + GL_UNSIGNED_INT, 0); + check_gl(); + } - check_gl(); } if (config->draw_ui) diff --git a/src/shader.c b/src/shader.c @@ -52,7 +52,7 @@ static char **resolve_imports(char *contents, int *nlines) { line_buff[*nlines] = line; line_lens[*nlines] = line_len; (*nlines)++; - /* printf("%d %.*s", *nlines, line_len, line); */ + printf("%d %.*s", *nlines, line_len, line); } } @@ -199,8 +199,7 @@ make_program_from_shaders(struct shader **shaders, int n_shaders, struct gpu_pro for (int i = 0; i < n_shaders; i++) { program->shaders[i] = *shaders[i]; struct shader *shader = &program->shaders[i]; - - glAttachShader(program->handle, shader->handle); + glAttachShader(program->handle, shaders[i]->handle); } glLinkProgram(program->handle);