diff --git a/Makefile.am b/Makefile.am index a7538ef..4efc05f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -22,14 +22,16 @@ else AM_CFLAGS += -O2 endif -EXTRA_DIST += src/output_shader.vert src/output_shader.frag +EXTRA_DIST += src/output_shader_def.vert src/output_shader_def.frag \ + src/output_shader_tex.vert src/output_shader_tex.frag CLEANFILES += src/output_shaders.c genshader_SOURCES = \ src/genshader.c -src/output_shaders.c: src/output_shader.vert src/output_shader.frag genshader$(EXEEXT) - ./genshader$(EXEEXT) src/output_shaders.c src/output_shader.vert src/output_shader.frag +src/output_shaders.c: src/output_shader_def.vert src/output_shader_def.frag \ + src/output_shader_tex.vert src/output_shader_tex.frag genshader$(EXEEXT) + ./genshader$(EXEEXT) nodist_libkmscon_core_la_SOURCES = \ src/output_shaders.c diff --git a/src/genshader.c b/src/genshader.c index 25c7bf7..418a7e7 100644 --- a/src/genshader.c +++ b/src/genshader.c @@ -97,13 +97,16 @@ static void write_seq(FILE *out, const char *src, size_t len) } static void write_file(const char *path, const char *vs, size_t l1, - const char *fs, size_t l2) + const char *fs, size_t l2, const char *tvs, size_t l3, + const char *tfs, size_t l4) { FILE *out; static const char c1[] = "/* This file is generated by genshader.c */\n" - "const char *kmscon_vert_shader = \""; - static const char c2[] = "\";\nconst char *kmscon_frag_shader = \""; - static const char c3[] = "\";"; + "const char *kmscon_vert_def = \""; + static const char c2[] = "\";\nconst char *kmscon_frag_def = \""; + static const char c3[] = "\";\nconst char *kmscon_vert_tex = \""; + static const char c4[] = "\";\nconst char *kmscon_frag_tex = \""; + static const char c5[] = "\";"; out = fopen(path, "wb"); if (!out) { @@ -116,26 +119,31 @@ static void write_file(const char *path, const char *vs, size_t l1, fwrite(c2, sizeof(c2) - 1, 1, out); write_seq(out, fs, l2); fwrite(c3, sizeof(c3) - 1, 1, out); + write_seq(out, tvs, l3); + fwrite(c4, sizeof(c4) - 1, 1, out); + write_seq(out, tfs, l4); + fwrite(c5, sizeof(c5) - 1, 1, out); fclose(out); } int main(int argc, char *argv[]) { - char *vert, *frag; - size_t vs, fs; + char *def_vert, *def_frag, *tex_vert, *tex_frag; + size_t vs, fs, tvs, tfs; - if (argc < 4) { - fprintf(stderr, "genshader: missing parameters\n"); - return EXIT_FAILURE; - } + def_vert = read_file("./src/output_shader_def.vert", &vs); + def_frag = read_file("./src/output_shader_def.frag", &fs); + tex_vert = read_file("./src/output_shader_tex.vert", &tvs); + tex_frag = read_file("./src/output_shader_tex.frag", &tfs); - vert = read_file(argv[2], &vs); - frag = read_file(argv[3], &fs); + write_file("./src/output_shaders.c", def_vert, vs, def_frag, fs, + tex_vert, tvs, tex_frag, tfs); - write_file(argv[1], vert, vs, frag, fs); - free(vert); - free(frag); + free(tex_vert); + free(tex_frag); + free(def_vert); + free(def_frag); return EXIT_SUCCESS; } diff --git a/src/output_context.c b/src/output_context.c index ded82fd..f1c3e55 100644 --- a/src/output_context.c +++ b/src/output_context.c @@ -88,11 +88,16 @@ struct kmscon_context { EGLDisplay display; EGLContext context; - GLuint program; - GLuint vshader; - GLuint fshader; - GLuint uni_projection; - GLuint uni_texture; + GLuint def_program; + GLuint def_vshader; + GLuint def_fshader; + GLuint def_uni_projection; + + GLuint tex_program; + GLuint tex_vshader; + GLuint tex_fshader; + GLuint tex_uni_projection; + GLuint tex_uni_texture; PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC proc_rbuf_storage; PFNEGLCREATEIMAGEKHRPROC proc_create_image; @@ -160,8 +165,10 @@ static bool has_gl_error() } /* external shader sources; generated during build */ -extern const char *kmscon_vert_shader; -extern const char *kmscon_frag_shader; +extern const char *kmscon_vert_def; +extern const char *kmscon_frag_def; +extern const char *kmscon_vert_tex; +extern const char *kmscon_frag_tex; static int compile_shader(struct kmscon_context *ctx, GLenum type, const char *source) @@ -185,7 +192,7 @@ static int compile_shader(struct kmscon_context *ctx, GLenum type, return s; } -static int init_shader(struct kmscon_context *ctx) +static int init_def_shader(struct kmscon_context *ctx) { char msg[512]; GLint status = 1; @@ -194,58 +201,131 @@ static int init_shader(struct kmscon_context *ctx) if (!ctx) return -EINVAL; - ctx->vshader = compile_shader(ctx, GL_VERTEX_SHADER, - kmscon_vert_shader); - if (ctx->vshader == GL_NONE) + ctx->def_vshader = compile_shader(ctx, GL_VERTEX_SHADER, + kmscon_vert_def); + if (ctx->def_vshader == GL_NONE) return -EFAULT; - ctx->fshader = compile_shader(ctx, GL_FRAGMENT_SHADER, - kmscon_frag_shader); - if (ctx->fshader == GL_NONE) { + ctx->def_fshader = compile_shader(ctx, GL_FRAGMENT_SHADER, + kmscon_frag_def); + if (ctx->def_fshader == GL_NONE) { ret = -EFAULT; goto err_vshader; } - ctx->program = ctx->proc_create_program(); - ctx->proc_attach_shader(ctx->program, ctx->vshader); - ctx->proc_attach_shader(ctx->program, ctx->fshader); - ctx->proc_bind_attrib_location(ctx->program, 0, "position"); - ctx->proc_bind_attrib_location(ctx->program, 1, "texture_position"); + ctx->def_program = ctx->proc_create_program(); + ctx->proc_attach_shader(ctx->def_program, ctx->def_vshader); + ctx->proc_attach_shader(ctx->def_program, ctx->def_fshader); + ctx->proc_bind_attrib_location(ctx->def_program, 0, "position"); + ctx->proc_bind_attrib_location(ctx->def_program, 1, "color"); - ctx->proc_link_program(ctx->program); - ctx->proc_get_program_iv(ctx->program, GL_LINK_STATUS, &status); + ctx->proc_link_program(ctx->def_program); + ctx->proc_get_program_iv(ctx->def_program, GL_LINK_STATUS, &status); if (status == GL_FALSE) { msg[0] = 0; - ctx->proc_get_program_info_log(ctx->program, sizeof(msg), + ctx->proc_get_program_info_log(ctx->def_program, sizeof(msg), NULL, msg); log_warning("context: cannot link shader: %s\n", msg); ret = -EFAULT; goto err_link; } - ctx->uni_projection = - ctx->proc_get_uniform_location(ctx->program, "projection"); - ctx->uni_texture = - ctx->proc_get_uniform_location(ctx->program, "texture"); + ctx->def_uni_projection = + ctx->proc_get_uniform_location(ctx->def_program, "projection"); return 0; err_link: - ctx->proc_delete_program(ctx->program); - ctx->proc_delete_shader(ctx->fshader); + ctx->proc_delete_program(ctx->def_program); + ctx->proc_delete_shader(ctx->def_fshader); err_vshader: - ctx->proc_delete_shader(ctx->vshader); + ctx->proc_delete_shader(ctx->def_vshader); return ret; } +static int init_tex_shader(struct kmscon_context *ctx) +{ + char msg[512]; + GLint status = 1; + int ret; + + if (!ctx) + return -EINVAL; + + ctx->tex_vshader = compile_shader(ctx, GL_VERTEX_SHADER, + kmscon_vert_tex); + if (ctx->tex_vshader == GL_NONE) + return -EFAULT; + + ctx->tex_fshader = compile_shader(ctx, GL_FRAGMENT_SHADER, + kmscon_frag_tex); + if (ctx->tex_fshader == GL_NONE) { + ret = -EFAULT; + goto err_vshader; + } + + ctx->tex_program = ctx->proc_create_program(); + ctx->proc_attach_shader(ctx->tex_program, ctx->tex_vshader); + ctx->proc_attach_shader(ctx->tex_program, ctx->tex_fshader); + ctx->proc_bind_attrib_location(ctx->tex_program, 0, "position"); + ctx->proc_bind_attrib_location(ctx->tex_program, 1, "texture_position"); + + ctx->proc_link_program(ctx->tex_program); + ctx->proc_get_program_iv(ctx->tex_program, GL_LINK_STATUS, &status); + if (status == GL_FALSE) { + msg[0] = 0; + ctx->proc_get_program_info_log(ctx->tex_program, sizeof(msg), + NULL, msg); + log_warning("context: cannot link shader: %s\n", msg); + ret = -EFAULT; + goto err_link; + } + + ctx->tex_uni_projection = + ctx->proc_get_uniform_location(ctx->tex_program, "projection"); + ctx->tex_uni_texture = + ctx->proc_get_uniform_location(ctx->tex_program, "texture"); + + return 0; + +err_link: + ctx->proc_delete_program(ctx->tex_program); + ctx->proc_delete_shader(ctx->tex_fshader); +err_vshader: + ctx->proc_delete_shader(ctx->tex_vshader); + return ret; +} + +static int init_shader(struct kmscon_context *ctx) +{ + int ret; + + ret = init_def_shader(ctx); + if (ret) + return ret; + + ret = init_tex_shader(ctx); + if (ret) { + ctx->proc_delete_program(ctx->def_program); + ctx->proc_delete_shader(ctx->def_fshader); + ctx->proc_delete_shader(ctx->def_vshader); + return ret; + } + + return 0; +} + static void destroy_shader(struct kmscon_context *ctx) { if (!ctx) return; - ctx->proc_delete_program(ctx->program); - ctx->proc_delete_shader(ctx->fshader); - ctx->proc_delete_shader(ctx->vshader); + ctx->proc_delete_program(ctx->tex_program); + ctx->proc_delete_shader(ctx->tex_fshader); + ctx->proc_delete_shader(ctx->tex_vshader); + ctx->proc_delete_program(ctx->def_program); + ctx->proc_delete_shader(ctx->def_fshader); + ctx->proc_delete_shader(ctx->def_vshader); } /* diff --git a/src/output_shader_def.frag b/src/output_shader_def.frag new file mode 100644 index 0000000..c480b61 --- /dev/null +++ b/src/output_shader_def.frag @@ -0,0 +1,37 @@ +/* + * kmscon - Fragment Shader + * + * Copyright (c) 2011 David Herrmann + * Copyright (c) 2011 University of Tuebingen + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Default Fragement Shader + * A basic fragment shader which applies a color directly. + */ + +varying vec4 col; + +void main() +{ + gl_FragColor = col; +} diff --git a/src/output_shader_def.vert b/src/output_shader_def.vert new file mode 100644 index 0000000..3931f11 --- /dev/null +++ b/src/output_shader_def.vert @@ -0,0 +1,42 @@ +/* + * kmscon - Vertex Shader + * + * Copyright (c) 2011 David Herrmann + * Copyright (c) 2011 University of Tuebingen + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Default Vertex Shader + * This shader is a very basic vertex shader which forwards all data and + * performs basic matrix multiplications. + */ + +uniform mat4 projection; +attribute vec2 position; +attribute vec4 color; +varying vec4 col; + +void main() +{ + col = color; + gl_Position = projection * vec4(position, 0.0, 1.0); +} diff --git a/src/output_shader.frag b/src/output_shader_tex.frag similarity index 100% rename from src/output_shader.frag rename to src/output_shader_tex.frag diff --git a/src/output_shader.vert b/src/output_shader_tex.vert similarity index 100% rename from src/output_shader.vert rename to src/output_shader_tex.vert