Selaa lähdekoodia

Embedding simple shader in the header

Vinicius Teshima 1 vuosi sitten
vanhempi
sitoutus
f7e30548d8
5 muutettua tiedostoa jossa 158 lisäystä ja 47 poistoa
  1. 0 7
      shaders/simple.frag
  2. 0 22
      shaders/simple.vert
  3. 6 3
      src/main.c
  4. 15 0
      src/shader.h
  5. 137 15
      src/simple_render.h

+ 0 - 7
shaders/simple.frag

@@ -1,7 +0,0 @@
-#version 330 core
-
-in vec4 out_color;
-
-void main() {
-	gl_FragColor = out_color;
-}

+ 0 - 22
shaders/simple.vert

@@ -1,22 +0,0 @@
-#version 330 core
-
-uniform vec2 resolution;
-uniform float time;
-uniform vec2 camera;
-
-layout(location = 0) in vec2 pos;
-layout(location = 1) in vec4 color;
-layout(location = 2) in vec2 uv;
-
-
-vec2 project_point(vec2 point)
-{
-  return (2.0 * (point - camera)) / resolution;
-}
-
-out vec4 out_color;
-
-void main() {
-	gl_Position = vec4(project_point(pos), 0, 1);
-	out_color = color;
-}

+ 6 - 3
src/main.c

@@ -93,9 +93,7 @@ main(int32_t argc, char **argv)
 		"./shaders/free_font.vert",
 		"./shaders/free_font.vert",
 		"./shaders/free_font.frag");
 		"./shaders/free_font.frag");
 
 
-	struct simple_render sr = sr_create(
-		"./shaders/simple.vert",
-		"./shaders/simple.frag");
+	struct simple_render sr = sr_create();
 	(void) sr;
 	(void) sr;
 
 
 	app.fgr = &fgr;
 	app.fgr = &fgr;
@@ -231,6 +229,7 @@ render_buffer_into_fgr(struct free_glyph_render *fgr, struct simple_render *sr,
 	}
 	}
 
 
 	sr_use(sr);
 	sr_use(sr);
+	sr_set_shader(sr, SIMPLE_SHADER_RAINBOW);
 	{
 	{
 		glUniform1f(sr_get_uniform(sr, "time"), time);
 		glUniform1f(sr_get_uniform(sr, "time"), time);
 		glUniform2f(sr_get_uniform(sr, "camera"),
 		glUniform2f(sr_get_uniform(sr, "camera"),
@@ -245,10 +244,14 @@ render_buffer_into_fgr(struct free_glyph_render *fgr, struct simple_render *sr,
 		/* 	vec4f(1,0,0,1), vec4f(0,1,0,1), vec4f(0,0,1,1), */
 		/* 	vec4f(1,0,0,1), vec4f(0,1,0,1), vec4f(0,0,1,1), */
 		/* 	X3_ARGS(uv)); */
 		/* 	X3_ARGS(uv)); */
 
 
+		#if 0
 		uint32_t t = ticks - app->last_press;
 		uint32_t t = ticks - app->last_press;
 		if ( t < 500 || (t/1000)%2 != 0 ) {
 		if ( t < 500 || (t/1000)%2 != 0 ) {
 			sr_solid_rect(sr, vec2_to_f(cur_pos), vec2f(3, 32), vec4fs(1));
 			sr_solid_rect(sr, vec2_to_f(cur_pos), vec2f(3, 32), vec4fs(1));
 		}
 		}
+		#else
+		sr_image_rect(sr, vec2_to_f(cur_pos), vec2f(3, 32), vec4fs(1));
+		#endif
 		sr_draw(sr);
 		sr_draw(sr);
 	}
 	}
 }
 }

+ 15 - 0
src/shader.h

@@ -18,6 +18,7 @@ struct ret_uint32_t_err {
 };
 };
 
 
 struct ret_uint32_t_err shader_compile_source(const char *src, GLenum type);
 struct ret_uint32_t_err shader_compile_source(const char *src, GLenum type);
+uint32_t shader_compile_source_or_exit(const char *src, GLenum type);
 struct ret_uint32_t_err shader_compile_file(const char *filepath, GLenum type);
 struct ret_uint32_t_err shader_compile_file(const char *filepath, GLenum type);
 uint32_t shader_compile_file_or_exit(const char *filepath, GLenum type);
 uint32_t shader_compile_file_or_exit(const char *filepath, GLenum type);
 
 
@@ -73,6 +74,20 @@ err: ;
 	};
 	};
 }
 }
 
 
+uint32_t
+shader_compile_source_or_exit(const char *src, GLenum type)
+{
+	enum shader_err err;
+	uint32_t shader;
+	RET_UNWRAP2(shader, err, struct ret_uint32_t_err,
+		    shader_compile_source(src, type));
+	if ( err != SHADER_ERR_OK ) {
+		fprintf(stderr, "Failed to compile shader %s\n", src);
+		exit(EXIT_FAILURE);
+	}
+	return shader;
+}
+
 struct ret_uint32_t_err
 struct ret_uint32_t_err
 shader_compile_file(const char *filepath, GLenum type)
 shader_compile_file(const char *filepath, GLenum type)
 {
 {

+ 137 - 15
src/simple_render.h

@@ -22,12 +22,20 @@ enum simple_vertex_attr {
 	SIMPLE_VERTEX_ATTR_TOTAL,
 	SIMPLE_VERTEX_ATTR_TOTAL,
 };
 };
 
 
+
 struct simple_vertex {
 struct simple_vertex {
 	struct vec2f pos;
 	struct vec2f pos;
 	struct vec4f color;
 	struct vec4f color;
 	struct vec2f uv;
 	struct vec2f uv;
 };
 };
 
 
+enum simple_shader {
+	SIMPLE_SHADER_COLOR,
+	SIMPLE_SHADER_IMAGE,
+	SIMPLE_SHADER_RAINBOW,
+	SIMPLE_SHADER_TOTAL,
+};
+
 struct simple_render {
 struct simple_render {
 	HT_DEF_STRUCT_ITEM(int32_t, uniforms);
 	HT_DEF_STRUCT_ITEM(int32_t, uniforms);
 	DA_DEF_STRUCT_ITEM(struct simple_vertex, vertexs);
 	DA_DEF_STRUCT_ITEM(struct simple_vertex, vertexs);
@@ -36,16 +44,23 @@ struct simple_render {
 	uint32_t vbo;
 	uint32_t vbo;
 	struct {
 	struct {
 		uint32_t vert;
 		uint32_t vert;
-		uint32_t frag;
+		uint32_t frag_color;
+		uint32_t frag_image;
+		uint32_t frag_rainbow;
 	} shaders;
 	} shaders;
-	uint32_t prog;
+	uint32_t progs[SIMPLE_SHADER_TOTAL];
+	enum simple_shader cur_shader;
 };
 };
 
 
-struct simple_render sr_create(const char *vert_path, const char *frag_path);
+
+struct simple_render sr_create(void);
+void sr_compile_shaders(struct simple_render *sr);
+void sr_set_all_uniforms(struct simple_render *sr);
 int32_t sr_set_uniform(struct simple_render *sr, const char *uniform_name);
 int32_t sr_set_uniform(struct simple_render *sr, const char *uniform_name);
 int32_t sr_get_uniform(const struct simple_render *sr,
 int32_t sr_get_uniform(const struct simple_render *sr,
 		       const char *uniform_name);
 		       const char *uniform_name);
 void sr_use(const struct simple_render *sr);
 void sr_use(const struct simple_render *sr);
+void sr_set_shader(struct simple_render *sr, enum simple_shader shader);
 void sr_triangle(struct simple_render *sr,
 void sr_triangle(struct simple_render *sr,
 		 struct vec2f p0, struct vec2f p1, struct vec2f p2,
 		 struct vec2f p0, struct vec2f p1, struct vec2f p2,
 		 struct vec4f c0, struct vec4f c1, struct vec4f c2,
 		 struct vec4f c0, struct vec4f c1, struct vec4f c2,
@@ -55,6 +70,8 @@ void sr_quad(struct simple_render *sr,
 	     struct vec4f c0, struct vec4f c1, struct vec4f c2, struct vec4f c3,
 	     struct vec4f c0, struct vec4f c1, struct vec4f c2, struct vec4f c3,
 	     struct vec2f uv0, struct vec2f uv1,
 	     struct vec2f uv0, struct vec2f uv1,
 	     struct vec2f uv2, struct vec2f uv3);
 	     struct vec2f uv2, struct vec2f uv3);
+void sr_image_rect(struct simple_render *sr, struct vec2f pos,
+		   struct vec2f size, struct vec4f color);
 void sr_solid_rect(struct simple_render *sr, struct vec2f pos,
 void sr_solid_rect(struct simple_render *sr, struct vec2f pos,
 		   struct vec2f size, struct vec4f color);
 		   struct vec2f size, struct vec4f color);
 void sr_draw(const struct simple_render *sr);
 void sr_draw(const struct simple_render *sr);
@@ -67,7 +84,7 @@ void sr_draw(const struct simple_render *sr);
 #include "util_macro.h"
 #include "util_macro.h"
 
 
 struct simple_render
 struct simple_render
-sr_create(const char *vert_path, const char *frag_path)
+sr_create(void)
 {
 {
 	struct simple_render sr = {0};
 	struct simple_render sr = {0};
 	HT_CREATE(sr.uniforms, 32);
 	HT_CREATE(sr.uniforms, 32);
@@ -138,24 +155,35 @@ sr_create(const char *vert_path, const char *frag_path)
 #endif
 #endif
 	}
 	}
 
 
-	sr.shaders.vert = shader_compile_file_or_exit(
-		vert_path, GL_VERTEX_SHADER);
-	sr.shaders.frag = shader_compile_file_or_exit(
-		frag_path, GL_FRAGMENT_SHADER);
-	sr.prog = program_link_or_exit(sr.shaders.vert, sr.shaders.frag);
 
 
-	glUseProgram(sr.prog);
+	sr_compile_shaders(&sr);
+	sr.progs[SIMPLE_SHADER_COLOR]
+		= program_link_or_exit(sr.shaders.vert, sr.shaders.frag_color);
+	sr.progs[SIMPLE_SHADER_IMAGE]
+		= program_link_or_exit(sr.shaders.vert, sr.shaders.frag_image);
+	sr.progs[SIMPLE_SHADER_RAINBOW]
+		= program_link_or_exit(sr.shaders.vert,
+				       sr.shaders.frag_rainbow);
 
 
-	sr_set_uniform(&sr, "resolution");
-	sr_set_uniform(&sr, "time");
-	sr_set_uniform(&sr, "camera");
+	sr.cur_shader = SIMPLE_SHADER_COLOR;
+	glUseProgram(sr.progs[sr.cur_shader]);
+
+	sr_set_all_uniforms(&sr);
 	return sr;
 	return sr;
 }
 }
 
 
+void
+sr_set_all_uniforms(struct simple_render *sr)
+{
+	sr_set_uniform(sr, "resolution");
+	sr_set_uniform(sr, "time");
+	sr_set_uniform(sr, "camera");
+}
+
 int32_t
 int32_t
 sr_set_uniform(struct simple_render *sr, const char *uniform_name)
 sr_set_uniform(struct simple_render *sr, const char *uniform_name)
 {
 {
-	int32_t uni = get_uniform(sr->prog, uniform_name);
+	int32_t uni = get_uniform(sr->progs[sr->cur_shader], uniform_name);
 	printf("%s: Got Uniform %s -> %d\n", __func__, uniform_name, uni);
 	printf("%s: Got Uniform %s -> %d\n", __func__, uniform_name, uni);
 	HT_SET(sr->uniforms, uniform_name, strlen(uniform_name), uni);
 	HT_SET(sr->uniforms, uniform_name, strlen(uniform_name), uni);
 	return uni;
 	return uni;
@@ -173,7 +201,18 @@ sr_use(const struct simple_render *sr)
 {
 {
 	glBindVertexArray(sr->vao);
 	glBindVertexArray(sr->vao);
 	glBindBuffer(GL_ARRAY_BUFFER, sr->vbo);
 	glBindBuffer(GL_ARRAY_BUFFER, sr->vbo);
-	glUseProgram(sr->prog);
+	glUseProgram(sr->progs[sr->cur_shader]);
+}
+
+void
+sr_set_shader(struct simple_render *sr, enum simple_shader shader)
+{
+	if ( sr->cur_shader == shader ) {
+		return;
+	}
+	sr->cur_shader = shader;
+	glUseProgram(sr->progs[sr->cur_shader]);
+	sr_set_all_uniforms(sr);
 }
 }
 
 
 void
 void
@@ -190,6 +229,9 @@ sr_triangle(struct simple_render *sr,
 	DA_APPEND(sr->vertexs, sv2);
 	DA_APPEND(sr->vertexs, sv2);
 }
 }
 
 
+/* 2-3 */
+/* |\| */
+/* 0-1 */
 void
 void
 sr_quad(struct simple_render *sr,
 sr_quad(struct simple_render *sr,
 	struct vec2f p0, struct vec2f p1, struct vec2f p2, struct vec2f p3,
 	struct vec2f p0, struct vec2f p1, struct vec2f p2, struct vec2f p3,
@@ -200,6 +242,17 @@ sr_quad(struct simple_render *sr,
 	sr_triangle(sr, p1, p2, p3, c1, c2, c3, uv1, uv2, uv3);
 	sr_triangle(sr, p1, p2, p3, c1, c2, c3, uv1, uv2, uv3);
 }
 }
 
 
+void
+sr_image_rect(struct simple_render *sr, struct vec2f pos, struct vec2f size,
+	      struct vec4f color)
+{
+	sr_quad(sr,
+		pos, vec2f_add(pos, vec2f(size.x, 0)),
+		vec2f_add(pos, vec2f(0, size.y)), vec2f_add(pos, size),
+		X4_ARGS(color),
+		vec2f(0, 0), vec2f(1, 0), vec2f(0, 1), vec2f(1, 1));
+}
+
 void
 void
 sr_solid_rect(struct simple_render *sr, struct vec2f pos, struct vec2f size,
 sr_solid_rect(struct simple_render *sr, struct vec2f pos, struct vec2f size,
 	      struct vec4f color)
 	      struct vec4f color)
@@ -224,6 +277,75 @@ sr_draw(const struct simple_render *sr)
 }
 }
 
 
 
 
+
+void
+sr_compile_shaders(struct simple_render *sr)
+{
+#define GL_VER "#version 330 core\n"
+	sr->shaders.vert = shader_compile_source_or_exit(
+		GL_VER
+		"uniform vec2 resolution;\n"
+		"uniform float time;\n"
+		"uniform vec2 camera;\n"
+		"layout(location = 0) in vec2 pos;\n"
+		"layout(location = 1) in vec4 color;\n"
+		"layout(location = 2) in vec2 uv;\n"
+		"vec2 project_point(vec2 point)\n"
+		"{\n"
+		"  return (2.0 * (point - camera)) / resolution;\n"
+		"}\n"
+		"out vec4 out_color;\n"
+		"out vec2 out_uv;\n"
+		"void main() {\n"
+		"	gl_Position = vec4(project_point(pos), 0, 1);\n"
+		"	out_color = color;\n"
+		"	out_uv = uv;\n"
+		"}\n",
+		GL_VERTEX_SHADER);
+	sr->shaders.frag_color = shader_compile_source_or_exit(
+		GL_VER
+		"in vec4 out_color;\n"
+		"void main() {\n"
+		"	gl_FragColor = out_color;\n"
+		"}\n"
+		, GL_FRAGMENT_SHADER);
+	sr->shaders.frag_image = shader_compile_source_or_exit(
+		GL_VER
+		"uniform sampler2D image;\n"
+		"in vec2 out_uv;\n"
+		"void main() {\n"
+		"	gl_FragColor = texture(image, out_uv);\n"
+		"}\n", GL_FRAGMENT_SHADER);
+	sr->shaders.frag_rainbow = shader_compile_source_or_exit(
+		GL_VER
+		"uniform sampler2D font;\n"
+		"uniform float time;\n"
+		"uniform vec2 resolution;\n"
+		"in vec2 out_uv;\n"
+		"float map01(float x)\n"
+		"{\n"
+		"	return (x + 1) / 2;\n"
+		"}\n"
+		"vec3 hsl2rgb( in vec3 c )\n"
+		"{\n"
+		"	vec3 rgb = clamp( abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),6.0)-3.0)-1.0,\n"
+		"			  0.0, 1.0 );\n"
+		"	return c.z + c.y * (rgb-0.5)*(1.0-abs(2.0*c.z-1.0));\n"
+		"}\n"
+		"void main() {\n"
+		"	vec4 tc = texture(font, out_uv);\n"
+		"	vec2 frag_uv = gl_FragCoord.xy / resolution;\n"
+		"	vec4 rainbow = vec4(hsl2rgb(vec3((time + frag_uv.x + frag_uv.y), 0.5, 0.5)), 1.0);\n"
+		"	gl_FragColor =  (1.0 - tc.x) + tc.x * rainbow;\n"
+		"}\n"
+		, GL_FRAGMENT_SHADER);
+
+
+
+#undef GL_VER
+}
+
+
 #endif /* defined(SIMPLE_RENDER_IMP) || defined(IMP) */
 #endif /* defined(SIMPLE_RENDER_IMP) || defined(IMP) */
 
 
 #endif
 #endif