Ver Fonte

Embedding simple shader in the header

Vinicius Teshima há 1 ano atrás
pai
commit
f7e30548d8
5 ficheiros alterados com 158 adições e 47 exclusões
  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.frag");
 
-	struct simple_render sr = sr_create(
-		"./shaders/simple.vert",
-		"./shaders/simple.frag");
+	struct simple_render sr = sr_create();
 	(void) sr;
 
 	app.fgr = &fgr;
@@ -231,6 +229,7 @@ render_buffer_into_fgr(struct free_glyph_render *fgr, struct simple_render *sr,
 	}
 
 	sr_use(sr);
+	sr_set_shader(sr, SIMPLE_SHADER_RAINBOW);
 	{
 		glUniform1f(sr_get_uniform(sr, "time"), time);
 		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), */
 		/* 	X3_ARGS(uv)); */
 
+		#if 0
 		uint32_t t = ticks - app->last_press;
 		if ( t < 500 || (t/1000)%2 != 0 ) {
 			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);
 	}
 }

+ 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);
+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);
 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
 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,
 };
 
+
 struct simple_vertex {
 	struct vec2f pos;
 	struct vec4f color;
 	struct vec2f uv;
 };
 
+enum simple_shader {
+	SIMPLE_SHADER_COLOR,
+	SIMPLE_SHADER_IMAGE,
+	SIMPLE_SHADER_RAINBOW,
+	SIMPLE_SHADER_TOTAL,
+};
+
 struct simple_render {
 	HT_DEF_STRUCT_ITEM(int32_t, uniforms);
 	DA_DEF_STRUCT_ITEM(struct simple_vertex, vertexs);
@@ -36,16 +44,23 @@ struct simple_render {
 	uint32_t vbo;
 	struct {
 		uint32_t vert;
-		uint32_t frag;
+		uint32_t frag_color;
+		uint32_t frag_image;
+		uint32_t frag_rainbow;
 	} 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_get_uniform(const struct simple_render *sr,
 		       const char *uniform_name);
 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,
 		 struct vec2f p0, struct vec2f p1, struct vec2f p2,
 		 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 vec2f uv0, struct vec2f uv1,
 	     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,
 		   struct vec2f size, struct vec4f color);
 void sr_draw(const struct simple_render *sr);
@@ -67,7 +84,7 @@ void sr_draw(const struct simple_render *sr);
 #include "util_macro.h"
 
 struct simple_render
-sr_create(const char *vert_path, const char *frag_path)
+sr_create(void)
 {
 	struct simple_render sr = {0};
 	HT_CREATE(sr.uniforms, 32);
@@ -138,24 +155,35 @@ sr_create(const char *vert_path, const char *frag_path)
 #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;
 }
 
+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
 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);
 	HT_SET(sr->uniforms, uniform_name, strlen(uniform_name), uni);
 	return uni;
@@ -173,7 +201,18 @@ sr_use(const struct simple_render *sr)
 {
 	glBindVertexArray(sr->vao);
 	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
@@ -190,6 +229,9 @@ sr_triangle(struct simple_render *sr,
 	DA_APPEND(sr->vertexs, sv2);
 }
 
+/* 2-3 */
+/* |\| */
+/* 0-1 */
 void
 sr_quad(struct simple_render *sr,
 	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);
 }
 
+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
 sr_solid_rect(struct simple_render *sr, struct vec2f pos, struct vec2f size,
 	      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