polyadvent

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

commit 9a39e4589301ac551c3d59d000d4c3aa6de2f2fd
parent 033d790f9d3a2eb31c90608d7e64d8422aac0601
Author: William Casarin <jb55@jb55.com>
Date:   Mon, 29 Oct 2018 12:49:19 -0700

implement shader includes

Diffstat:
Aetc/shaders/lighting.glsl | 16++++++++++++++++
Metc/shaders/terrain.glsl | 16+---------------
Metc/shaders/vertex-color.glsl | 22+---------------------
Msrc/file.c | 4+++-
Msrc/shader.c | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Msrc/update.c | 6+++---
6 files changed, 79 insertions(+), 46 deletions(-)

diff --git a/etc/shaders/lighting.glsl b/etc/shaders/lighting.glsl @@ -0,0 +1,16 @@ + +vec3 standard_light(vec3 color) { + vec4 v4_normal = vec4(normal , 1); + vec4 trans_normal = normal_matrix * v4_normal; + + vec3 L = light_dir; + vec3 N = normalize(trans_normal.xyz); + + float costheta = clamp(dot(L,N), 0.3, 1.0) * light_intensity; + + return color * costheta; +} + +vec3 gamma_correct(vec3 color) { + return pow(color, vec3(1.0/2.2)); +} diff --git a/etc/shaders/terrain.glsl b/etc/shaders/terrain.glsl @@ -21,21 +21,7 @@ out vec4 shadow_coord; const int nlands = 6; -vec3 standard_light(vec3 color) { - vec4 v4_normal = vec4(normal , 1); - vec4 trans_normal = normal_matrix * v4_normal; - - vec3 L = light_dir; - vec3 N = normalize(trans_normal.xyz); - - float costheta = clamp(dot(L,N), 0.3, 1.0) * light_intensity; - - return color * costheta; -} - -vec3 gamma_correct(vec3 color) { - return pow(color, vec3(1.0/2.2)); -} +#include lighting.glsl const vec4 land[nlands] = vec4[]( vec4(0.0, 0.5, 0.79, 0.0), // 0 - water diff --git a/etc/shaders/vertex-color.glsl b/etc/shaders/vertex-color.glsl @@ -22,27 +22,7 @@ flat out vec3 v_normal; out vec3 v_ray; out vec4 shadow_coord; -// TODO: includes -// #include "lighting.glsl" - - - -vec3 standard_light(vec3 color) { - vec4 v4_normal = vec4(normal , 1); - vec4 trans_normal = normal_matrix * v4_normal; - - vec3 L = light_dir; - vec3 N = normalize(trans_normal.xyz); - - float costheta = clamp(dot(L,N), 0.3, 1.0) * light_intensity; - - return color * costheta; -} - -vec3 gamma_correct(vec3 color) { - return pow(color, vec3(1.0/2.2)); -} - +#include lighting.glsl void main() { diff --git a/src/file.c b/src/file.c @@ -15,7 +15,7 @@ time_t file_mtime(const char *filename) { void *file_contents(const char *filename, size_t *length) { FILE *f = fopen(filename, "r"); - void *buffer; + char *buffer; if (!f) { fprintf(stderr, "Unable to open %s for reading\n", filename); @@ -30,5 +30,7 @@ void *file_contents(const char *filename, size_t *length) { *length = fread(buffer, 1, *length, f); fclose(f); + buffer[*length] = 0; + return buffer; } diff --git a/src/shader.c b/src/shader.c @@ -7,25 +7,74 @@ #include "gl.h" #include "debug.h" #include "shader.h" +#include "common.h" + +#define MAX_LINES 4096 + +static int file_buf_count = 0; +static char *file_buffers[12]; +static char *line_buff[MAX_LINES]; +static u32 line_lens[MAX_LINES]; + +static char *strsep(char **stringp, const char *delim) { + if (*stringp == NULL) { return NULL; } + char *token_start = *stringp; + *stringp = strpbrk(token_start, delim); + if (*stringp) + (*stringp)++; + return token_start; +} - +static char **resolve_imports(char *contents, int *nlines) { + char *line; + size_t file_len; + char *resolved_contents; + static char fname_buf[32]; + + while ((line = strsep(&contents, "\n"))) { + int line_len = contents - line; + int size = sizeof("#include"); + if (memcmp(line, "#include ", size) == 0) { + char *filename = line + size; + snprintf(fname_buf, 32, SHADER("%.*s"), line_len-size-1, filename); + /* printf("got include %s\n", fname_buf); */ + resolved_contents = file_contents(fname_buf, &file_len); + file_buffers[file_buf_count++] = resolved_contents; + resolve_imports(resolved_contents, nlines); + } + else { + line_buff[*nlines] = line; + line_lens[*nlines] = line_len; + (*nlines)++; + } + } + + return line_buff; +} int make_shader(GLenum type, const char *filename, struct shader *shader) { size_t length; + int nlines = 0; GLchar *source = (GLchar *)file_contents(filename, &length); - GLint shader_ok; - if (!source) - return 0; + return 0; + + char **lines = resolve_imports(source, &nlines); - source[length] = '\0'; + GLint shader_ok; shader->filename = filename; shader->type = type; shader->handle = glCreateShader(type); - glShaderSource(shader->handle, 1, (const GLchar**)&source, (GLint*)&length); + glShaderSource(shader->handle, nlines, (const char**)lines, + (const int*)line_lens); + free(source); + for (int i = 0; i < file_buf_count; ++i) + free(file_buffers[i]); + file_buf_count = 0; + glCompileShader(shader->handle); glGetShaderiv(shader->handle, GL_COMPILE_STATUS, &shader_ok); diff --git a/src/update.c b/src/update.c @@ -227,7 +227,7 @@ void resize_fbos(struct game *game, int width, int height) { // TODO: match based on some real concept of time static void day_night_cycle(float n, struct resources *res) { float darkest = 0.3; - float val = n*200.0; + float val = n*100.0; float roots = vec3_dot(res->light_dir, V3(0.0, 0.0, 1.0)); float intensity = clamp(roots, darkest, 1.0); float light_pos[3]; @@ -248,8 +248,8 @@ static void day_night_cycle(float n, struct resources *res) { vec3_normalize(res->light_dir, res->light_dir); - printf("intensity %f(%f) n %f light_dir %f %f\n", roots, intensity, - n, res->light_dir[1], res->light_dir[2]); + /* printf("intensity %f(%f) n %f light_dir %f %f\n", roots, intensity, */ + /* n, res->light_dir[1], res->light_dir[2]); */ vec3_add(&res->player.node.mat[M_X], res->light_dir, light_pos);