From 776dfe46d2ec5fa184a316583fe96673d831a942 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Thu, 27 Apr 2023 16:45:25 -0700 Subject: [PATCH] sub-pixel rectangles with analytical anti-aliasing --- ...standalone_srgb_antialiasing_experiments.c | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/src/standalone_srgb_antialiasing_experiments.c b/src/standalone_srgb_antialiasing_experiments.c index 6cd7b0a..1a7e8cd 100644 --- a/src/standalone_srgb_antialiasing_experiments.c +++ b/src/standalone_srgb_antialiasing_experiments.c @@ -76,6 +76,10 @@ typedef struct Vertex{ F32 cg; F32 cb; F32 ca; + F32 rx0; + F32 ry0; + F32 rx1; + F32 ry1; } Vertex; @@ -84,6 +88,7 @@ static void opengl_render_init(void); static void opengl_draw_basic_geometry(Vertex *v, U64 count); static void opengl_draw_srgb_in_geometry(Vertex *v, U64 count); static void opengl_draw_texture_geometry(Vertex *v, U64 count, U32 texture); +static void opengl_draw_rect_geometry(Vertex *v, U64 count); //////////////////////////////// @@ -297,6 +302,7 @@ static GLint basic_u_view_xform = -1; + static char srgb_in_vshader[] = "#version 330\n" "\n" @@ -355,6 +361,45 @@ static GLint srgb_in_u_view_xform = -1; + +static char rect_vshader[] = +"#version 330\n" +"uniform vec2 u_view_xform;\n" +"layout (location = 0) in vec2 v_p;\n" +"layout (location = 1) in vec4 v_r;\n" +"out vec4 f_r;\n" +"void main(){\n" +"vec2 norm_pos = v_p*u_view_xform + vec2(-1.0, -1.0);\n" +"gl_Position = vec4(norm_pos, 0.0, 1.0);\n" +"f_r = v_r;\n" +"}\n" +; + +static char rect_fshader[] = +"#version 330\n" +"in vec4 gl_FragCoord;\n" +"in vec4 f_r;\n" +"out vec4 out_color;\n" +"void main(){\n" +"float pix_x0 = gl_FragCoord.x - 0.5;\n" +"float pix_y0 = gl_FragCoord.y - 0.5;\n" +"float pix_x1 = gl_FragCoord.x + 0.5;\n" +"float pix_y1 = gl_FragCoord.y + 0.5;\n" +"float int_x0 = max(pix_x0, f_r.x);\n" +"float int_y0 = max(pix_y0, f_r.y);\n" +"float int_x1 = min(pix_x1, f_r.z);\n" +"float int_y1 = min(pix_y1, f_r.w);\n" +"float cover = (int_x1 - int_x0)*(int_y1 - int_y0);\n" +"out_color = vec4(1, 1, 1, cover);\n" +"}\n" +; + +static GLuint rect_program = 0; +static GLint rect_u_view_xform = -1; + + + + static char texture_vshader[] = "#version 330\n" "uniform vec2 u_view_xform;\n" @@ -409,6 +454,15 @@ opengl_render_init(void){ srgb_in_u_view_xform = glGetUniformLocation(basic_program, "u_view_xform"); } + //- setup rect shader program + { + GLuint shaders[2] = {0}; + shaders[0] = opengl_helper_make_shader(rect_vshader, GL_VERTEX_SHADER); + shaders[1] = opengl_helper_make_shader(rect_fshader, GL_FRAGMENT_SHADER); + rect_program = opengl_helper_make_program(shaders, 2); + rect_u_view_xform = glGetUniformLocation(rect_program, "u_view_xform"); + } + //- setup texture shader program { GLuint shaders[2] = {0}; @@ -523,6 +577,24 @@ opengl_draw_srgb_in_geometry(Vertex *v, U64 count){ glDrawArrays(GL_TRIANGLES, 0, count); } +static void +opengl_draw_rect_geometry(Vertex *v, U64 count){ + glBufferData(GL_ARRAY_BUFFER, sizeof(*v)*count, v, GL_STREAM_DRAW); + + glUseProgram(rect_program); + glUniform2f(rect_u_view_xform, 2.f/graphics_w, 2.f/graphics_h); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, 0, + sizeof(Vertex), PtrOffsetOf(Vertex, px)); + + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 4, GL_FLOAT, 0, + sizeof(Vertex), PtrOffsetOf(Vertex, rx0)); + + glDrawArrays(GL_TRIANGLES, 0, count); +} + static void opengl_draw_texture_geometry(Vertex *v, U64 count, U32 texture){ glBufferData(GL_ARRAY_BUFFER, sizeof(*v)*count, v, GL_STREAM_DRAW); @@ -602,6 +674,7 @@ WinMain(HINSTANCE hInstance, F32 test3_y = graphics_h - 110.f; F32 test4_y = graphics_h - 160.f; F32 test5_y = graphics_h - 340.f; + F32 test6_y = graphics_h - 450.f; // render to canvas frame buffer { @@ -868,7 +941,40 @@ WinMain(HINSTANCE hInstance, opengl_draw_srgb_in_geometry(v, 6); } } + } + + // 6: sub-pixel rectangle anti-aliasing + { + F32 top_y = test6_y; + F32 bot_y = test6_y - 20.f; + F32 x_cursor = grad_x0; + for (U32 i = 0; i < 16; i += 1){ + F32 l = x_cursor + 4.0625*i; + F32 r = l + 2.f; + + F32 floor_l = (F32)(S32)l; + F32 ceil_r = (F32)(S32)r; + if (ceil_r < (F32)r){ + ceil_r += 1.f; + } + + Vertex v[6]; + v[0].px = floor_l; v[0].py = bot_y; + v[1].px = floor_l; v[1].py = top_y; + v[2].px = ceil_r; v[2].py = bot_y; + v[3].px = floor_l; v[3].py = top_y; + v[4].px = ceil_r; v[4].py = bot_y; + v[5].px = ceil_r; v[5].py = top_y; + for (U32 j = 0; j < 6; j += 1){ + v[j].rx0 = l; + v[j].ry0 = bot_y; + v[j].rx1 = r; + v[j].ry1 = top_y; + } + + opengl_draw_rect_geometry(v, 6); + } } }