summaryrefslogtreecommitdiff
path: root/gl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gl.c')
-rw-r--r--gl.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/gl.c b/gl.c
index 023b852..41e29e5 100644
--- a/gl.c
+++ b/gl.c
@@ -26,6 +26,7 @@
do(ENABLEVERTEXATTRIBARRAY, EnableVertexAttribArray)\
do(DISABLEVERTEXATTRIBARRAY, DisableVertexAttribArray)\
do(GENVERTEXARRAYS, GenVertexArrays)\
+ do(DELETEVERTEXARRAYS, DeleteVertexArrays)\
do(BINDVERTEXARRAY, BindVertexArray)\
do(UNIFORM1F, Uniform1f)\
do(UNIFORM2F, Uniform2f)\
@@ -125,3 +126,87 @@ static GLint gl_uniform_loc(GLuint program, char const *uniform) {
return loc;
}
+typedef struct {
+ v2 pos;
+ v4 color;
+} GLSimpleVertex;
+typedef struct {
+ GLSimpleVertex v1, v2, v3;
+} GLSimpleTriangle;
+
+static GLSimpleTriangle *gl_geometry_triangles;
+static GLuint gl_geometry_program;
+static GLuint gl_geometry_v_pos;
+static GLuint gl_geometry_v_color;
+static GLint gl_geometry_u_window_size;
+static GLuint gl_geometry_vbo, gl_geometry_vao;
+
+static void gl_geometry_init(void) {
+ char const *vshader_code = "#version 110\n\
+ attribute vec2 v_pos;\n\
+ attribute vec4 v_color;\n\
+ varying vec4 color;\n\
+ uniform vec2 window_size;\n\
+ void main() {\n\
+ float x = v_pos.x / window_size.x * 2.0 - 1.0;\n\
+ float y = 1.0 - v_pos.y / window_size.y * 2.0;\n\
+ gl_Position = vec4(x, y, 0.0, 1.0);\n\
+ color = v_color;\n\
+ }\n\
+ ";
+ char const *fshader_code = "#version 110\n\
+ varying vec4 color;\n\
+ void main() {\n\
+ gl_FragColor = color;\n\
+ }\n\
+ ";
+
+ gl_geometry_program = gl_compile_and_link_shaders(vshader_code, fshader_code);
+ gl_geometry_v_pos = gl_attrib_loc(gl_geometry_program, "v_pos");
+ gl_geometry_v_color = gl_attrib_loc(gl_geometry_program, "v_color");
+ gl_geometry_u_window_size = gl_uniform_loc(gl_geometry_program, "window_size");
+
+ glGenBuffers(1, &gl_geometry_vbo);
+ if (gl_version_major >= 3)
+ glGenVertexArrays(1, &gl_geometry_vao);
+}
+
+static void gl_geometry_rect(Rect r, u32 color_rgba) {
+ v4 color = rgba_u32_to_v4(color_rgba);
+
+ v2 p1 = r.pos;
+ v2 p2 = v2_add(r.pos, V2(0, r.size.y));
+ v2 p3 = v2_add(r.pos, V2(r.size.x, r.size.y));
+ v2 p4 = p3;
+ v2 p5 = v2_add(r.pos, V2(r.size.x, 0));
+ v2 p6 = p1;
+ GLSimpleTriangle triangle = {
+ {p1, color},
+ {p2, color},
+ {p3, color}
+ };
+ arr_add(gl_geometry_triangles, triangle);
+ triangle.v1.pos = p4;
+ triangle.v2.pos = p5;
+ triangle.v3.pos = p6;
+ arr_add(gl_geometry_triangles, triangle);
+}
+
+static void gl_geometry_draw(Ted *ted) {
+ size_t ntriangles = arr_len(gl_geometry_triangles);
+
+ if (gl_version_major >= 3)
+ glBindVertexArray(gl_geometry_vao);
+ glBindBuffer(GL_ARRAY_BUFFER, gl_geometry_vbo);
+ glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(ntriangles * sizeof(GLSimpleTriangle)), gl_geometry_triangles, GL_STREAM_DRAW);
+ glVertexAttribPointer(gl_geometry_v_pos, 2, GL_FLOAT, 0, sizeof(GLSimpleVertex), (void *)offsetof(GLSimpleVertex, pos));
+ glEnableVertexAttribArray(gl_geometry_v_pos);
+ glVertexAttribPointer(gl_geometry_v_color, 4, GL_FLOAT, 0, sizeof(GLSimpleVertex), (void *)offsetof(GLSimpleVertex, color));
+ glEnableVertexAttribArray(gl_geometry_v_color);
+
+ glUseProgram(gl_geometry_program);
+ glUniform2f(gl_geometry_u_window_size, ted->window_width, ted->window_height);
+ glDrawArrays(GL_TRIANGLES, 0, (GLsizei)(3 * ntriangles));
+
+ arr_clear(gl_geometry_triangles);
+}