225 lines
4.0 KiB
GLSL
225 lines
4.0 KiB
GLSL
|
#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;
|
||
|
}
|
||
|
}
|