sub-pixel rectangles with analytical anti-aliasing
parent
97d8c7430e
commit
776dfe46d2
|
@ -76,6 +76,10 @@ typedef struct Vertex{
|
||||||
F32 cg;
|
F32 cg;
|
||||||
F32 cb;
|
F32 cb;
|
||||||
F32 ca;
|
F32 ca;
|
||||||
|
F32 rx0;
|
||||||
|
F32 ry0;
|
||||||
|
F32 rx1;
|
||||||
|
F32 ry1;
|
||||||
} Vertex;
|
} 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_basic_geometry(Vertex *v, U64 count);
|
||||||
static void opengl_draw_srgb_in_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_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[] =
|
static char srgb_in_vshader[] =
|
||||||
"#version 330\n"
|
"#version 330\n"
|
||||||
"\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[] =
|
static char texture_vshader[] =
|
||||||
"#version 330\n"
|
"#version 330\n"
|
||||||
"uniform vec2 u_view_xform;\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");
|
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
|
//- setup texture shader program
|
||||||
{
|
{
|
||||||
GLuint shaders[2] = {0};
|
GLuint shaders[2] = {0};
|
||||||
|
@ -523,6 +577,24 @@ opengl_draw_srgb_in_geometry(Vertex *v, U64 count){
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 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
|
static void
|
||||||
opengl_draw_texture_geometry(Vertex *v, U64 count, U32 texture){
|
opengl_draw_texture_geometry(Vertex *v, U64 count, U32 texture){
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(*v)*count, v, GL_STREAM_DRAW);
|
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 test3_y = graphics_h - 110.f;
|
||||||
F32 test4_y = graphics_h - 160.f;
|
F32 test4_y = graphics_h - 160.f;
|
||||||
F32 test5_y = graphics_h - 340.f;
|
F32 test5_y = graphics_h - 340.f;
|
||||||
|
F32 test6_y = graphics_h - 450.f;
|
||||||
|
|
||||||
// render to canvas frame buffer
|
// render to canvas frame buffer
|
||||||
{
|
{
|
||||||
|
@ -868,7 +941,40 @@ WinMain(HINSTANCE hInstance,
|
||||||
opengl_draw_srgb_in_geometry(v, 6);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue