TransWikia.com

Border Radius in OpenGL

Code Review Asked by michaelsnowden on November 28, 2020

I’m a total noob to OpenGL just following the tutorial at learnopengl.com. Anyway, I’m trying to build a GUI that involves rectangles that have border radiuses. I figured I could do this using the fragment shader. Essentially, I’m masking each corner with a circle that is r units away from each wall for that corner. I then check if the point is between the circle’s center and the corner. If the point is between those two, then I check if it’s outside of the circle’s radius. If so, I discard the point.

#version 330 core

// the xy position of the fragment (in world coordinates?)
in vec2 xy;

// the bottom left corner of the rectangle
uniform vec2 u_position;

// the width and height of the rectangle
uniform vec2 u_dimensions;

// the border radius (how far the mask circle's center we be from either wall of the corner)
uniform float u_radius;

out vec4 FragColor;

void main(void) {
    // xy = test point coordinates
    // rc = rectangle corner
    // ec = ellipse center
    // uv = test point coordinates relative to ellipse center
    if (xy.x - u_position.x < u_dimensions.x / 2) {
        if (xy.y - u_position.y < u_dimensions.y / 2) {
            // bottom left
            vec2 rc = u_position;
            vec2 ec = rc + vec2(u_radius, u_radius);
            vec2 uv = xy - ec;
            if (uv.x < 0 && uv.y < 0 && pow(uv.x/u_radius, 2) + pow(uv.y/u_radius, 2) > 1) {
                discard;
            }
        } else {
            // top left
            vec2 rc = u_position + vec2(0, u_dimensions.y);
            vec2 ec = rc + vec2(u_radius, -u_radius);
            vec2 uv = xy - ec;
            if (uv.x < 0 && uv.y > 0 && pow(uv.x/u_radius, 2) + pow(uv.y/u_radius, 2) > 1) {
                discard;
            }
        }
    } else {
        if (xy.y - u_position.y < u_dimensions.y / 2) {
            // bottom right
            vec2 rc = u_position + vec2(u_dimensions.x, 0);
            vec2 ec = rc + vec2(-u_radius, u_radius);
            vec2 uv = xy - ec;
            if (uv.x > 0 && uv.y < 0 && pow(uv.x/u_radius, 2) + pow(uv.y/u_radius, 2) > 1) {
                discard;
            }
        } else {
            // top right
            vec2 rc = u_position + vec2(u_dimensions.x, u_dimensions.y);
            vec2 ec = rc + vec2(-u_radius, -u_radius);
            vec2 uv = xy - ec;
            if (uv.x > 0 && uv.y > 0 && pow(uv.x/u_radius, 2) + pow(uv.y/u_radius, 2) > 1) {
                discard;
            }
        }
    }
    FragColor = vec4(0.0f, 0.0f, 0.0f, 1.0f);
}

The result looks like this (the corners are really jagged):
enter image description here

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP