diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2021-02-04 19:04:04 -0500 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2021-02-04 19:04:43 -0500 |
commit | a04565b7796fdfcff0b652644a0983145abbba87 (patch) | |
tree | 45d5ce88fe1a9915632211d765d07e3c83ce0166 /gl.c | |
parent | 9c96427ba61f17d4cb91235bef2a77483a0278bf (diff) |
small modern gl geometry api
Diffstat (limited to 'gl.c')
-rw-r--r-- | gl.c | 85 |
1 files changed, 85 insertions, 0 deletions
@@ -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); +} |