rounded quads baby!
This commit is contained in:
parent
3a0904023a
commit
177e52b0d0
@ -1,9 +1,55 @@
|
|||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
layout(location = 0) in vec4 col;
|
layout(location = 0) in vec4 color;
|
||||||
|
layout(location = 1) in vec2 local_position;
|
||||||
|
layout(location = 2) in vec2 global_position;
|
||||||
|
layout(location = 3) in float radius;
|
||||||
|
|
||||||
layout(location = 0) out vec4 fragColor;
|
layout(location = 0) out vec4 fragColor;
|
||||||
|
|
||||||
|
// SDF for a rounded rectangle given the centerpoint, half size and radius, all in pixels
|
||||||
|
float sdf_rr(vec2 p, vec2 center, vec2 half_size, float radius) {
|
||||||
|
// Translate fragment position to rectangle's coordinate system
|
||||||
|
p -= center;
|
||||||
|
// Adjust for rounded corners: shrink the rectangle by the radius
|
||||||
|
vec2 q = abs(p) - half_size + radius;
|
||||||
|
// Combine distance components:
|
||||||
|
// - max(q, 0.0) handles regions outside the rounded corners
|
||||||
|
// - min(max(q.x, q.y), 0.0) handles regions inside the rectangle
|
||||||
|
return length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - radius;
|
||||||
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
fragColor = col;
|
// local_position are normalized coordinates in the rectangle, passed from the
|
||||||
|
// vertex shader
|
||||||
|
/*
|
||||||
|
* Window
|
||||||
|
* +-----------------------+
|
||||||
|
* | (1,1) |
|
||||||
|
* | +----------x |
|
||||||
|
* | | | |
|
||||||
|
* | | | |
|
||||||
|
* | | Rect | |
|
||||||
|
* | | | |
|
||||||
|
* | | | |
|
||||||
|
* | x----------+ |
|
||||||
|
* | (-1,-1) |
|
||||||
|
* | |
|
||||||
|
* +-----------------------+
|
||||||
|
*/
|
||||||
|
|
||||||
|
vec2 dx = dFdx(local_position);
|
||||||
|
vec2 dy = dFdy(local_position);
|
||||||
|
// Conversion from normalized coordinates to pixels
|
||||||
|
vec2 norm_to_px = 1.0 / vec2(length(dx), length(dy));
|
||||||
|
|
||||||
|
vec2 centerpoint = global_position - local_position * norm_to_px;
|
||||||
|
// the half size of the rectangle is also norm_to_px
|
||||||
|
vec2 half_size = 1.0 * norm_to_px;
|
||||||
|
|
||||||
|
float distance = sdf_rr(global_position, centerpoint, half_size, radius);
|
||||||
|
float alpha = 1.0 - smoothstep(0.0, 1.0, max(distance, 0.0));
|
||||||
|
|
||||||
|
fragColor = vec4(color.rgb, color.a * alpha);
|
||||||
}
|
}
|
@ -10,6 +10,9 @@ layout(location = 1) in ivec2 uv;
|
|||||||
layout(location = 2) in ivec4 color;
|
layout(location = 2) in ivec4 color;
|
||||||
|
|
||||||
layout(location = 0) out vec4 col;
|
layout(location = 0) out vec4 col;
|
||||||
|
layout(location = 1) out vec2 local_position;
|
||||||
|
layout(location = 2) out vec2 global_position;
|
||||||
|
layout(location = 3) out float radius;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
@ -24,5 +27,10 @@ void main()
|
|||||||
pos.y = -(float(position.y)*2.0 / view.y - 1.0);
|
pos.y = -(float(position.y)*2.0 / view.y - 1.0);
|
||||||
|
|
||||||
gl_Position = vec4(pos+shift, 0.0, 1.0);
|
gl_Position = vec4(pos+shift, 0.0, 1.0);
|
||||||
|
|
||||||
|
local_position = vec2(sign(uv));
|
||||||
|
global_position = gl_Position.xy;
|
||||||
|
radius = abs(float(uv.x));
|
||||||
|
|
||||||
col = vec4(color) / 255.0;
|
col = vec4(color) / 255.0;
|
||||||
}
|
}
|
||||||
|
@ -566,7 +566,7 @@ fn bool Renderer.push_sprite(&self, short x, short y, short w, short h, short u,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Push a quad into the quad buffer, return true on success and false on failure
|
// Push a quad into the quad buffer, return true on success and false on failure
|
||||||
fn bool Renderer.push_quad(&self, short x, short y, short w, short h, uint color)
|
fn bool Renderer.push_quad(&self, short x, short y, short w, short h, uint color, ushort radius = 0)
|
||||||
{
|
{
|
||||||
if (self.quad_buffer.count >= MAX_QUAD_BATCH) {
|
if (self.quad_buffer.count >= MAX_QUAD_BATCH) {
|
||||||
return false;
|
return false;
|
||||||
@ -600,11 +600,14 @@ fn bool Renderer.push_quad(&self, short x, short y, short w, short h, uint color
|
|||||||
* |/ |
|
* |/ |
|
||||||
* +-------------+
|
* +-------------+
|
||||||
* v2 v3
|
* v2 v3
|
||||||
*/
|
*/
|
||||||
quad.vertices.v1 = {.pos = {.x = x, .y = y}, .col.u = color};
|
// the wanted radius is pushed into the uv coordinates, the vertex shader then extracts the absolute value
|
||||||
quad.vertices.v2 = {.pos = {.x = x, .y = y+h}, .col.u = color};
|
// and passes it to the fragment shader, then it uses the sign to give the fragment shader local coordinates
|
||||||
quad.vertices.v3 = {.pos = {.x = x+w, .y = y+h}, .col.u = color};
|
// into the quad.
|
||||||
quad.vertices.v4 = {.pos = {.x = x+w, .y = y}, .col.u = color};
|
quad.vertices.v1 = {.pos = {.x = x, .y = y}, .uv = {.u = -radius, .v = +radius}, .col.u = color};
|
||||||
|
quad.vertices.v2 = {.pos = {.x = x, .y = y+h}, .uv = {.u = -radius, .v = -radius}, .col.u = color};
|
||||||
|
quad.vertices.v3 = {.pos = {.x = x+w, .y = y+h}, .uv = {.u = +radius, .v = -radius}, .col.u = color};
|
||||||
|
quad.vertices.v4 = {.pos = {.x = x+w, .y = y}, .uv = {.u = +radius, .v = +radius}, .col.u = color};
|
||||||
// triangle 1 indices
|
// triangle 1 indices
|
||||||
quad.indices.i1 = 0; // v1
|
quad.indices.i1 = 0; // v1
|
||||||
quad.indices.i2 = 1; // v2
|
quad.indices.i2 = 1; // v2
|
||||||
|
@ -62,7 +62,7 @@ fn int main()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// rect 1
|
// rect 1
|
||||||
ren.push_quad(100,100,100,100,0xff00ff00);
|
ren.push_quad(100,100,100,100,0xff00ff00, 20);
|
||||||
// rect 2
|
// rect 2
|
||||||
ren.push_quad(0,0,20,20,0xff0000ff);
|
ren.push_quad(0,0,20,20,0xff0000ff);
|
||||||
// rect 3
|
// rect 3
|
||||||
|
Loading…
Reference in New Issue
Block a user