Dashboard/Dashboard.Drawing.OpenGL/Executors/simple.frag

225 lines
4.0 KiB
GLSL
Raw Normal View History

2025-01-18 21:30:56 +01:00
#version 140
#define DB_GRADIENT_MAX 16
#define DB_COMMAND_MAX 64
#define CMD_POINT 1
#define CMD_LINE 2
#define CMD_RECT 3
#define STRIKE_CENTER 0
#define STRIKE_OUTSET 1
#define STRIKE_INSET 2
in vec3 v_v3Position;
in vec2 v_v2TexCoords;
flat in int v_iCmdIndex;
out vec4 f_Color;
uniform sampler2D txForeground;
uniform sampler2D txBackground;
struct Gradient_t {
float fPosition;
float pad0;
float pad1;
float pad2;
vec4 v4Color;
};
uniform GradientBlock
{
Gradient_t vstGradientStops[DB_GRADIENT_MAX];
};
vec4 getGradientColor(float position, int index, int count)
{
position = clamp(position, 0, 1);
int i0 = 0;
float p0 = vstGradientStops[index + i0].fPosition;
int i1 = count - 1;
float p1 = vstGradientStops[index + i1].fPosition;
for (int i = 0; i < count; i++)
{
float px = vstGradientStops[index + i].fPosition;
if (px > p0 && px <= position)
{
p0 = px;
i0 = i;
}
if (px < p1 && px >= position)
{
p1 = px;
i1 = i;
}
}
vec4 c0 = vstGradientStops[index + i0].v4Color;
vec4 c1 = vstGradientStops[index + i1].v4Color;
float l = p1 - p0;
float w = (l > 0) ? (position - p0) / (p1 - p0) : 0;
return mix(c0, c1, w);
}
struct CommandInfo_t {
int iCommand;
int iFlags;
float fArg0;
float fArg1;
int iFgGradientIndex;
int iFgGradientCount;
int iBgGradientIndex;
int iBgGradientCount;
vec4 v4FgColor;
vec4 v4BgColor;
};
uniform CommandBlock
{
CommandInfo_t vstCommandInfo[DB_COMMAND_MAX];
};
CommandInfo_t getCommandInfo()
{
return vstCommandInfo[v_iCmdIndex];
}
vec4 fgColor()
{
return getCommandInfo().v4FgColor;
}
vec4 bgColor()
{
return getCommandInfo().v4BgColor;
}
void Point(void)
{
vec4 fg = fgColor();
if (dot(v_v2TexCoords, v_v2TexCoords) <= 0.25)
f_Color = fg;
else
discard;
}
#define LINE_NORMALIZED_RADIUS(cmd) cmd.fArg0
void Line(void)
{
vec4 fg = fgColor();
CommandInfo_t cmd = getCommandInfo();
float t = clamp(v_v2TexCoords.x, 0, 1);
vec2 dv = v_v2TexCoords - vec2(t, 0);
float d = dot(dv, dv);
float lim = LINE_NORMALIZED_RADIUS(cmd);
lim *= lim;
if (d <= lim)
f_Color = fg;
else
discard;
}
#define RECT_ASPECT_RATIO(cmd) (cmd.fArg0)
#define RECT_BORDER_WIDTH(cmd) (cmd.fArg1)
#define RECT_FILL(cmd) ((cmd.iFlags & (1 << 0)) != 0)
#define RECT_BORDER(cmd) ((cmd.iFlags & (1 << 1)) != 0)
#define RECT_STRIKE_MASK 3
#define RECT_STRIKE_SHIFT 2
#define RECT_STRIKE_KIND(cmd) ((cmd.iFlags & RECT_STRIKE_MASK) >> RECT_STRIKE_SHIFT)
void Rect(void)
{
vec4 fg = fgColor();
vec4 bg = bgColor();
CommandInfo_t cmd = getCommandInfo();
float aspect = RECT_ASPECT_RATIO(cmd);
float border = RECT_BORDER_WIDTH(cmd);
int strikeKind = RECT_STRIKE_KIND(cmd);
vec2 p = abs(2*v_v2TexCoords - vec2(1));
p.x = p.x/aspect;
float m0;
float m1;
if (!RECT_BORDER(cmd))
{
m0 = 1;
m1 = 1;
}
else if (strikeKind == STRIKE_OUTSET)
{
m0 = 1;
m1 = border;
}
else if (strikeKind == STRIKE_INSET)
{
m0 = 1-border;
m1 = 1;
}
else // strikeKind == STRIKE_CENTER
{
float h = 0.5 * border;
m0 = 1-border;
m1 = 1+border;
}
if (p.x > m1*aspect || p.y > m1)
{
discard;
}
if (RECT_FILL(cmd))
{
if (p.x <= 1 && p.y <= 1)
{
f_Color = fg;
}
}
if (RECT_BORDER(cmd))
{
float x = clamp(p.x, aspect*m0, aspect*m1);
float y = clamp(p.y, m0, m1);
if (p.x == x || p.y == y)
{
f_Color = bg;
}
}
}
void main(void)
{
switch (getCommandInfo().iCommand)
{
case CMD_POINT:
Point();
break;
case CMD_LINE:
Line();
break;
case CMD_RECT:
Rect();
break;
default:
// Unimplemented value.
f_Color = vec4(1, 0, 1, 1);
break;
}
}