Parcourir la source

Adding Simple Renderer

Vinicius Teshima il y a 1 an
Parent
commit
3c66b151ef
13 fichiers modifiés avec 382 ajouts et 56 suppressions
  1. 7 0
      shaders/simple.frag
  2. 22 0
      shaders/simple.vert
  3. 1 0
      src/app.h
  4. 5 4
      src/buffer.h
  5. 2 0
      src/cursor.h
  6. 30 5
      src/da.h
  7. 2 0
      src/file.h
  8. 7 13
      src/ht.h
  9. 3 0
      src/keybind.h
  10. 65 34
      src/main.c
  11. 1 0
      src/shader.h
  12. 229 0
      src/simple_render.h
  13. 8 0
      src/util_macro.h

+ 7 - 0
shaders/simple.frag

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

+ 22 - 0
shaders/simple.vert

@@ -0,0 +1,22 @@
+#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;
+}

+ 1 - 0
src/app.h

@@ -19,6 +19,7 @@ struct app {
 	bool running;
 	bool running;
 	uint64_t target_fps;
 	uint64_t target_fps;
 	double dt;
 	double dt;
+	uint32_t last_press;
 	struct {
 	struct {
 		uint8_t tab_size;
 		uint8_t tab_size;
 	} cfg;
 	} cfg;

+ 5 - 4
src/buffer.h

@@ -1,6 +1,7 @@
 #ifndef BUFFER_H
 #ifndef BUFFER_H
 #define BUFFER_H
 #define BUFFER_H
 
 
+#include <stdbool.h>
 #include <stdlib.h>
 #include <stdlib.h>
 
 
 struct buffer_line {
 struct buffer_line {
@@ -133,11 +134,11 @@ struct buffer
 buffer_create(void)
 buffer_create(void)
 {
 {
 	struct buffer buf = {0};
 	struct buffer buf = {0};
-	DA_CREATE(buf.data, sizeof(char));
-	DA_CREATE(buf.lines, sizeof(struct buffer_line));
+	DA_CREATE(buf.data);
+	DA_CREATE(buf.lines);
 
 
-	DA_CREATE(buf.hooks.insert, sizeof(buffer_hook_func));
-	DA_CREATE(buf.hooks.remove, sizeof(buffer_hook_func));
+	DA_CREATE(buf.hooks.insert);
+	DA_CREATE(buf.hooks.remove);
 
 
 	DA_APPEND(buf.hooks.insert, buffer_parse_lines);
 	DA_APPEND(buf.hooks.insert, buffer_parse_lines);
 	DA_APPEND(buf.hooks.remove, buffer_parse_lines);
 	DA_APPEND(buf.hooks.remove, buffer_parse_lines);

+ 2 - 0
src/cursor.h

@@ -59,6 +59,8 @@ cursor_render_create(const char *vert_path, const char *frag_path)
 void
 void
 cursor_render_use(struct cursor_render cr)
 cursor_render_use(struct cursor_render cr)
 {
 {
+	/* glBindVertexArray(cr.vao); */
+	/* glBindBuffer(GL_ARRAY_BUFFER, cr.vbo); */
 	glUseProgram(cr.prog);
 	glUseProgram(cr.prog);
 }
 }
 
 

+ 30 - 5
src/da.h

@@ -1,6 +1,7 @@
 #ifndef DA_H
 #ifndef DA_H
 #define DA_H
 #define DA_H
 
 
+#include <stddef.h>
 #include <stdlib.h>
 #include <stdlib.h>
 
 
 #define CONCAT(a, b) CONCAT_INNER(a, b)
 #define CONCAT(a, b) CONCAT_INNER(a, b)
@@ -8,7 +9,6 @@
 
 
 #define UNIQUE_NAME(base) CONCAT(base, __COUNTER__)
 #define UNIQUE_NAME(base) CONCAT(base, __COUNTER__)
 
 
-
 #define DA_DEF_STRUCT(type, name)		\
 #define DA_DEF_STRUCT(type, name)		\
 	struct name {				\
 	struct name {				\
 		type *items;			\
 		type *items;			\
@@ -23,11 +23,11 @@
 		size_t cap;			\
 		size_t cap;			\
 	} name
 	} name
 
 
-#define DA_CREATE(da, item_size)				\
+#define DA_CREATE(da)						\
 	do {							\
 	do {							\
 		(da).cap = 16;					\
 		(da).cap = 16;					\
 		(da).size = 0;					\
 		(da).size = 0;					\
-		(da).items = calloc((da).cap, item_size);	\
+		(da).items = calloc((da).cap, sizeof(*(da).items));	\
 	} while(0)
 	} while(0)
 
 
 #define DA_DESTROY(da)					\
 #define DA_DESTROY(da)					\
@@ -75,9 +75,11 @@
 #define DA_APPEND(da, item)						\
 #define DA_APPEND(da, item)						\
 	do {								\
 	do {								\
 		if ( (da).size+1 >= (da).cap ) {			\
 		if ( (da).size+1 >= (da).cap ) {			\
+			(da).items = _realloc((da).items,		\
+					      (da).cap,		\
+					      ((da).cap*2)		\
+					      * sizeof(*(da).items));	\
 			(da).cap *= 2;					\
 			(da).cap *= 2;					\
-			(da).items = realloc((da).items,		\
-					     (da).cap * sizeof(*(da).items)); \
 		}							\
 		}							\
 		(da).items[(da).size++] = item;			\
 		(da).items[(da).size++] = item;			\
 	} while(0)
 	} while(0)
@@ -89,4 +91,27 @@
 	(dst).size = (src).size;		\
 	(dst).size = (src).size;		\
 	(dst).cap = (src).cap;
 	(dst).cap = (src).cap;
 
 
+#include <stddef.h>
+
+void * _realloc(void *old, size_t old_size, size_t new_size);
+
+#if defined(DA_IMP) || defined(IMP)
+
+#include <stdlib.h>
+#include <string.h>
+
+void *
+_realloc(void *old, size_t old_size, size_t new_size)
+{
+	return realloc(old, new_size);
+	void *new = malloc(new_size);
+	memset(new, 0, new_size);
+	memcpy(new, old, old_size);
+	free(old);
+	return new;
+}
+
+#endif /* defined(DA_IMP) || defined(IMP) */
+
+
 #endif
 #endif

+ 2 - 0
src/file.h

@@ -1,6 +1,7 @@
 #ifndef FILE_H
 #ifndef FILE_H
 #define FILE_H
 #define FILE_H
 
 
+#include <stddef.h>
 #include <stdint.h>
 #include <stdint.h>
 
 
 #define CONCAT(a, b) CONCAT_INNER(a, b)
 #define CONCAT(a, b) CONCAT_INNER(a, b)
@@ -29,6 +30,7 @@ void file_err_set(enum file_err *err, enum file_err err_);
 
 
 #if defined(BMP_IMP) || defined(IMP)
 #if defined(BMP_IMP) || defined(IMP)
 
 
+#include <stdlib.h>
 #include <unistd.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <sys/stat.h>

+ 7 - 13
src/ht.h

@@ -42,13 +42,19 @@ uint64_t ht_default_hash(const char *str, size_t str_size);
 #define HT_DEF_STRUCT_ITEM(type, name)			\
 #define HT_DEF_STRUCT_ITEM(type, name)			\
 	struct {					\
 	struct {					\
 		struct {				\
 		struct {				\
+			struct {			\
+				const char *data;	\
+				size_t size;		\
+			} key_str;			\
 			uint64_t key;			\
 			uint64_t key;			\
 			type data;			\
 			type data;			\
 			void *next;			\
 			void *next;			\
 		} *items;				\
 		} *items;				\
 		size_t size;				\
 		size_t size;				\
 		size_t cap;				\
 		size_t cap;				\
+		DA_DEF_STRUCT_ITEM(uint64_t, keys);	\
 		ht_hash_func hash;			\
 		ht_hash_func hash;			\
+		size_t collisions;			\
 	} name
 	} name
 
 
 
 
@@ -61,24 +67,12 @@ uint64_t ht_default_hash(const char *str, size_t str_size);
 		DA_CREATE((ht).keys);					\
 		DA_CREATE((ht).keys);					\
 	} while(0)
 	} while(0)
 
 
-#define _HT_DESTROY(ht, _t, _hi)					\
+#define HT_DESTROY(ht)							\
 	do{								\
 	do{								\
-		void *_t = NULL;					\
-		for ( i = 0; i < (ht).cap; ++i ) {			\
-			typeof(*(ht).items) *_hi = &(ht).items[i];	\
-			while( _hi->next != NULL ) {			\
-				_t = _hi;				\
-				_hi = _hi->next;			\
-				free(_t);				\
-			}						\
-		}							\
 		free((ht).items);					\
 		free((ht).items);					\
 		free((ht).keys.items);					\
 		free((ht).keys.items);					\
 	} while(0)
 	} while(0)
 
 
-#define HT_DESTROY(ht)		\
-	_HT_DESTROY(ht, UNIQUE_NAME(_t), UNIQUE_NAME(_hi))
-
 
 
 #define _HT_INC_CAP(ht, _ht, _it, _i, _j, _k)				\
 #define _HT_INC_CAP(ht, _ht, _it, _i, _j, _k)				\
 	do {								\
 	do {								\

+ 3 - 0
src/keybind.h

@@ -78,6 +78,9 @@ keybind_delete_char(struct app app, union keybind_args args)
 		buffer_remove_char(&app.buf, app.buf.cur);
 		buffer_remove_char(&app.buf, app.buf.cur);
 	}
 	}
 	if ( args.dir == DIR_BACKWARD ) {
 	if ( args.dir == DIR_BACKWARD ) {
+		if ( app.buf.cur == 0 ) {
+			return app;
+		}
 		buffer_remove_char(&app.buf, --app.buf.cur);
 		buffer_remove_char(&app.buf, --app.buf.cur);
 	}
 	}
 	app.buf.high_col = buffer_calc_cur_col(&app.buf);
 	app.buf.high_col = buffer_calc_cur_col(&app.buf);

+ 65 - 34
src/main.c

@@ -1,3 +1,19 @@
+#define IMP
+#include "simple_render.h"
+#include "app.h"
+#include "vec2.h"
+#include "vec4.h"
+#include "da.h"
+#include "unwrap.h"
+#include "file.h"
+#include "keybind.h"
+#include "config.h"
+#include "shader.h"
+#include "gl_util.h"
+#include "free_glyph.h"
+#include "cursor.h"
+#include "util_macro.h"
+
 #include <stdio.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdlib.h>
 #include <stdint.h>
 #include <stdint.h>
@@ -13,25 +29,12 @@
 #include <ft2build.h>
 #include <ft2build.h>
 #include FT_FREETYPE_H
 #include FT_FREETYPE_H
 
 
-#define IMP
-#include "app.h"
-#include "vec2.h"
-#include "vec4.h"
-#include "da.h"
-#include "unwrap.h"
-#include "file.h"
-#include "keybind.h"
-#include "config.h"
-#include "shader.h"
-#include "gl_util.h"
-#include "free_glyph.h"
-#include "cursor.h"
-
 
 
 void handle_events(struct app *app, struct cursor_render *cr);
 void handle_events(struct app *app, struct cursor_render *cr);
 
 
 void render_buffer_into_fgr(struct free_glyph_render *fgr,
 void render_buffer_into_fgr(struct free_glyph_render *fgr,
 			    struct cursor_render *cr,
 			    struct cursor_render *cr,
+			    struct simple_render *sr,
 			    struct app *app);
 			    struct app *app);
 
 
 FT_Library library;
 FT_Library library;
@@ -96,6 +99,11 @@ main(int32_t argc, char **argv)
 		"./shaders/cur.vert",
 		"./shaders/cur.vert",
 		"./shaders/cur.frag");
 		"./shaders/cur.frag");
 
 
+	struct simple_render sr = sr_create(
+		"./shaders/simple.vert",
+		"./shaders/simple.frag");
+	(void) sr;
+
 	app.fgr = &fgr;
 	app.fgr = &fgr;
 	app.cr = &cr;
 	app.cr = &cr;
 
 
@@ -125,7 +133,7 @@ main(int32_t argc, char **argv)
 		glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
 		glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
 		glClear(GL_COLOR_BUFFER_BIT);
 		glClear(GL_COLOR_BUFFER_BIT);
 
 
-		render_buffer_into_fgr(&fgr, &cr, &app);
+		render_buffer_into_fgr(&fgr, &cr, &sr, &app);
 
 
 		SDL_GL_SwapWindow(app.win.ptr);
 		SDL_GL_SwapWindow(app.win.ptr);
 
 
@@ -143,6 +151,7 @@ main(int32_t argc, char **argv)
 void
 void
 handle_events(struct app *app, struct cursor_render *cr)
 handle_events(struct app *app, struct cursor_render *cr)
 {
 {
+	(void) cr;
 	SDL_Event e = {0};
 	SDL_Event e = {0};
 	bool done = false;
 	bool done = false;
 	while ( SDL_PollEvent(&e) ) {
 	while ( SDL_PollEvent(&e) ) {
@@ -151,9 +160,7 @@ handle_events(struct app *app, struct cursor_render *cr)
 			app->running = false;
 			app->running = false;
 		} break;
 		} break;
 		case SDL_KEYDOWN: {
 		case SDL_KEYDOWN: {
-			uint32_t ticks = SDL_GetTicks();
-			glUniform1f(cr->uniforms.last_press,
-				    ((float) ticks) / 1000);
+			app->last_press = SDL_GetTicks();
 
 
 			SDL_KeyboardEvent key = e.key;
 			SDL_KeyboardEvent key = e.key;
 			SDL_Keysym ks = key.keysym;
 			SDL_Keysym ks = key.keysym;
@@ -195,8 +202,11 @@ handle_events(struct app *app, struct cursor_render *cr)
 
 
 void
 void
 render_buffer_into_fgr(struct free_glyph_render *fgr, struct cursor_render *cr,
 render_buffer_into_fgr(struct free_glyph_render *fgr, struct cursor_render *cr,
-		       struct app *app)
+		       struct simple_render *sr, struct app *app)
 {
 {
+	(void) fgr;
+	(void) cr;
+	(void) app;
 	uint32_t ticks = SDL_GetTicks();
 	uint32_t ticks = SDL_GetTicks();
 	float cur_row = (float)(buffer_calc_cur_row(&app->buf)
 	float cur_row = (float)(buffer_calc_cur_row(&app->buf)
 				* fgr->atlas_dim.y);
 				* fgr->atlas_dim.y);
@@ -210,10 +220,10 @@ render_buffer_into_fgr(struct free_glyph_render *fgr, struct cursor_render *cr,
 	app->buf.cam.pos = cpos;
 	app->buf.cam.pos = cpos;
 	app->buf.cam.vel = cvel;
 	app->buf.cam.vel = cvel;
 
 
+	float time = ((float) ticks) / 1000.0f;
 	free_glyph_render_use(*fgr);
 	free_glyph_render_use(*fgr);
 	{
 	{
-		glUniform1f(fgr->uniforms.time,
-			    ((float) ticks) / 1000.0f);
+		glUniform1f(fgr->uniforms.time, time);
 		glUniform2f(fgr->uniforms.camera,
 		glUniform2f(fgr->uniforms.camera,
 			    (float)cpos.x,
 			    (float)cpos.x,
 			    (float)cpos.y);
 			    (float)cpos.y);
@@ -229,19 +239,40 @@ render_buffer_into_fgr(struct free_glyph_render *fgr, struct cursor_render *cr,
 				      (int32_t) fgr->glyphs.size);
 				      (int32_t) fgr->glyphs.size);
 	}
 	}
 
 
-	cursor_render_use(*cr);
+	/* cursor_render_use(*cr); */
+	/* { */
+	/* 	glUniform1f(cr->uniforms.time, ((float) ticks) / 1000.0f); */
+	/* 	glUniform2f(cr->uniforms.camera, (float)cpos.x, (float)cpos.y); */
+	/* 	glUniform2f(cr->uniforms.resolution, */
+	/* 		    (float) app->win.w, */
+	/* 		    (float) app->win.h); */
+	/* 	glUniform1f(cr->uniforms.h, (float) 32); */
+	/* 	glUniform1f(cr->uniforms.w, (float) 3); */
+
+	/* 	struct vec2 c_pos = vec2(cur_pos.x, cur_pos.y); */
+	/* 	cursor_render_mv_to(*cr, vec2_to_f(c_pos)); */
+	/* 	cursor_render_draw(*cr); */
+	/* } */
+
+	sr_use(sr);
 	{
 	{
-		glUniform1f(cr->uniforms.time, ((float) ticks) / 1000.0f);
-		glUniform2f(cr->uniforms.camera, (float)cpos.x, (float)cpos.y);
-		glUniform2f(cr->uniforms.resolution,
-			    (float) app->win.w,
-			    (float) app->win.h);
-		glUniform1f(cr->uniforms.h, (float) 32);
-		glUniform1f(cr->uniforms.w, (float) 3);
-
-		struct vec2 c_pos = vec2(cur_pos.x, cur_pos.y);
-		cursor_render_mv_to(*cr, vec2_to_f(c_pos));
-		cursor_render_draw(*cr);
+		glUniform1f(sr_get_uniform(sr, "time"), time);
+		glUniform2f(sr_get_uniform(sr, "camera"),
+			    (float)cpos.x, (float)cpos.y);
+		glUniform2f(sr_get_uniform(sr, "resolution"),
+			    (float) app->win.w, (float) app->win.h);
+		/* struct vec2f uv = vec2fs(0); */
+		sr->vertexs.size = 0;
+		/* sr_triangle( */
+		/* 	sr, */
+		/* 	vec2f(-50.f,-50.f), vec2f(50.f,-50.f), vec2f(0.0f,50.f), */
+		/* 	vec4f(1,0,0,1), vec4f(0,1,0,1), vec4f(0,0,1,1), */
+		/* 	X3_ARGS(uv)); */
+
+		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));
+		}
+		sr_draw(sr);
 	}
 	}
-
 }
 }

+ 1 - 0
src/shader.h

@@ -31,6 +31,7 @@ const char *shader_type_to_cstr(GLenum type);
 
 
 #include <stdio.h>
 #include <stdio.h>
 
 
+#include "unwrap.h"
 #include "file.h"
 #include "file.h"
 
 
 struct ret_uint32_t_err
 struct ret_uint32_t_err

+ 229 - 0
src/simple_render.h

@@ -0,0 +1,229 @@
+#ifndef SIMPLE_RENDER_H
+#define SIMPLE_RENDER_H
+
+#include <stdint.h>
+
+#include <SDL2/SDL.h>
+#define GLEW_STATIC
+#include <GL/glew.h>
+#define GL_GLEXT_PROTOTYPES
+#include <SDL2/SDL_opengl.h>
+
+#include "ht.h"
+#include "da.h"
+#include "vec2.h"
+#include "vec4.h"
+#include "glyph_attr.h"
+
+enum simple_vertex_attr {
+	SIMPLE_VERTEX_ATTR_POS = 0,
+	SIMPLE_VERTEX_ATTR_COLOR,
+	SIMPLE_VERTEX_ATTR_UV,
+	SIMPLE_VERTEX_ATTR_TOTAL,
+};
+
+struct simple_vertex {
+	struct vec2f pos;
+	struct vec4f color;
+	struct vec2f uv;
+};
+
+struct simple_render {
+	HT_DEF_STRUCT_ITEM(int32_t, uniforms);
+	DA_DEF_STRUCT_ITEM(struct simple_vertex, vertexs);
+
+	uint32_t vao;
+	uint32_t vbo;
+	struct {
+		uint32_t vert;
+		uint32_t frag;
+	} shaders;
+	uint32_t prog;
+};
+
+struct simple_render sr_create(const char *vert_path, const char *frag_path);
+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_triangle(struct simple_render *sr,
+		 struct vec2f p0, struct vec2f p1, struct vec2f p2,
+		 struct vec4f c0, struct vec4f c1, struct vec4f c2,
+		 struct vec2f uv0, struct vec2f uv1, struct vec2f uv2);
+void sr_quad(struct simple_render *sr,
+	     struct vec2f p0, struct vec2f p1, struct vec2f p2, struct vec2f p3,
+	     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_solid_rect(struct simple_render *sr, struct vec2f pos,
+		   struct vec2f size, struct vec4f color);
+void sr_draw(const struct simple_render *sr);
+
+#if defined(SIMPLE_RENDER_IMP) || defined(IMP)
+
+#include "shader.h"
+#include "gl_util.h"
+
+#include "util_macro.h"
+
+struct simple_render
+sr_create(const char *vert_path, const char *frag_path)
+{
+	struct simple_render sr = {0};
+	HT_CREATE(sr.uniforms, 32);
+	DA_CREATE(sr.vertexs);
+
+	/* sr.vertexs.cap = 1024 * 1024; */
+	/* sr.vertexs.size = 0; */
+	/* sr.vertexs.items = calloc(sr.vertexs.cap, sizeof(struct simple_vertex)); */
+
+	{
+		glGenVertexArrays(1, &sr.vao);
+		glBindVertexArray(sr.vao);
+
+		glGenBuffers(1, &sr.vbo);
+		glBindBuffer(GL_ARRAY_BUFFER, sr.vbo);
+
+		/* glBufferData(GL_ARRAY_BUFFER, */
+		/* 	     (ssize_t) (sizeof(struct simple_vertex) */
+		/* 			* sr.vertexs.cap), */
+		/* 	     sr.vertexs.items, */
+		/* 	     GL_DYNAMIC_DRAW); */
+#if 0
+		static const struct glyph_attr
+			simple_vertex_attr[SIMPLE_VERTEX_ATTR_TOTAL] = {
+			[SIMPLE_VERTEX_ATTR_POS] = {
+				.size = 2,
+				.type = GL_FLOAT,
+				.norm = GL_FALSE,
+				.stride = sizeof(struct simple_vertex),
+				.offset = offsetof(struct simple_vertex,
+						   pos)
+			},
+			[SIMPLE_VERTEX_ATTR_COLOR] = {
+				.size = 4,
+				.type = GL_FLOAT,
+				.norm = GL_FALSE,
+				.stride = sizeof(struct simple_vertex),
+				.offset = offsetof(struct simple_vertex,
+						   color)
+			},
+			[SIMPLE_VERTEX_ATTR_UV] = {
+				.size = 2,
+				.type = GL_FLOAT,
+				.norm = GL_FALSE,
+				.stride = sizeof(struct simple_vertex),
+				.offset = offsetof(struct simple_vertex,
+						   uv)
+			}
+		};
+		glyph_attr_declare(simple_vertex_attr,
+				   SIMPLE_VERTEX_ATTR_TOTAL);
+#else
+		glEnableVertexAttribArray(0);
+		glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE,
+				      sizeof(struct simple_vertex),
+				      (void *) offsetof(struct simple_vertex,
+							pos));
+		glEnableVertexAttribArray(1);
+		glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE,
+				      sizeof(struct simple_vertex),
+				      (void *) offsetof(struct simple_vertex,
+							color));
+		glEnableVertexAttribArray(2);
+		glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE,
+				      sizeof(struct simple_vertex),
+				      (void *) offsetof(struct simple_vertex,
+							uv));
+#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_set_uniform(&sr, "resolution");
+	sr_set_uniform(&sr, "time");
+	sr_set_uniform(&sr, "camera");
+	return sr;
+}
+
+int32_t
+sr_set_uniform(struct simple_render *sr, const char *uniform_name)
+{
+	int32_t uni = get_uniform(sr->prog, 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;
+}
+int32_t
+sr_get_uniform(const struct simple_render *sr, const char *uniform_name)
+{
+	int32_t uni = -1;
+	HT_GET(sr->uniforms, uniform_name, strlen(uniform_name), uni);
+	return uni;
+}
+
+void
+sr_use(const struct simple_render *sr)
+{
+	glBindVertexArray(sr->vao);
+	glBindBuffer(GL_ARRAY_BUFFER, sr->vbo);
+	glUseProgram(sr->prog);
+}
+
+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,
+	    struct vec2f uv0, struct vec2f uv1, struct vec2f uv2)
+{
+	struct simple_vertex sv0 = {p0, c0, uv0};
+	struct simple_vertex sv1 = {p1, c1, uv1};
+	struct simple_vertex sv2 = {p2, c2, uv2};
+	DA_APPEND(sr->vertexs, sv0);
+	DA_APPEND(sr->vertexs, sv1);
+	DA_APPEND(sr->vertexs, sv2);
+}
+
+void
+sr_quad(struct simple_render *sr,
+	struct vec2f p0, struct vec2f p1, struct vec2f p2, struct vec2f p3,
+	struct vec4f c0, struct vec4f c1, struct vec4f c2, struct vec4f c3,
+	struct vec2f uv0, struct vec2f uv1, struct vec2f uv2, struct vec2f uv3)
+{
+	sr_triangle(sr, p0, p1, p2, c0, c1, c2, uv0, uv1, uv2);
+	sr_triangle(sr, p1, p2, p3, c1, c2, c3, uv1, uv2, uv3);
+}
+
+void
+sr_solid_rect(struct simple_render *sr, struct vec2f pos, struct vec2f size,
+	      struct vec4f color)
+{
+	struct vec2f uv = vec2fs(0);
+	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),
+		X4_ARGS(uv));
+}
+
+void
+sr_draw(const struct simple_render *sr)
+{
+	glBufferData(GL_ARRAY_BUFFER,
+		     (ssize_t) (sizeof(struct simple_vertex)
+				* sr->vertexs.cap),
+		     sr->vertexs.items,
+		     GL_DYNAMIC_DRAW);
+	glDrawArrays(GL_TRIANGLES, 0, (int32_t) sr->vertexs.size);
+}
+
+
+#endif /* defined(SIMPLE_RENDER_IMP) || defined(IMP) */
+
+#endif

+ 8 - 0
src/util_macro.h

@@ -0,0 +1,8 @@
+#ifndef UTIL_MACRO_H
+#define UTIL_MACRO_H
+
+#define X2_ARGS(t) t, t
+#define X3_ARGS(t) t, t, t
+#define X4_ARGS(t) t, t, t, t
+
+#endif