by argv » Tue Oct 03, 2017 5:57 pm
I want to use ZScript to draw its HUD bars with a horizontal skew proportional to the
height of the bar, regardless of how much of the bar is filled. I've put together
this web-based demonstration (warning: doesn't show correctly in Microsoft IE/Edge) to show you what I have and what I want. The middle bar shows what I want; the bottom bar shows what I have.
Aetherius draws bars like I want on its HUD, by drawing each 1-pixel-wide sliver of the bar with a separate draw call. This is very slow. I'd like to help with that by skewing them with a shader instead, which should be much faster.
But I've got a problem. Currently, an ordinary texture can be drawn on the status bar, a shader can be attached to it via GLDEFS, and it can skew the texture just fine—but the horizontal skew is proportional to the scaled width of the texture, not the height! The result is like the bottom bar in the above demonstration.
This is my shader:
Code: Select all
const mat2 shearMatrix = mat2(1, 20./220., 0, 1);
const vec4 trans = vec4(0., 0., 0., 0.);
vec4 Process(vec4 color) {
vec2 xy = gl_TexCoord[0].st;
xy -= .5;
xy.x *= 1. + (20. / 220.);
xy *= shearMatrix;
xy += .5;
if (xy.x < 0. || xy.x > 1.)
return trans * color;
else
return getTexel(xy) * color;
}
I have it attached to a 1×20 texture named “HPBFILNV” in GLDEFS. I'm drawing it from a ZScript BaseStatusBar implementation like so:
Code: Select all
SetSize(0, 1440, 1080);
int value = CPlayer.Health;
int MaxValue = CPlayer.mo.GetMaxHealth(true);
int MaxFillWidth = 200;
TextureID Fill = TexMan.CheckForTexture("HPBFILNV", TexMan.Type_Any);
Vector2 Pos = (250, -175);
int DrawFlags = DI_ITEM_LEFT_TOP | DI_SCREEN_LEFT_BOTTOM;
double scale = double(value) / double(MaxValue);
double underScale = min(scale, 1.0) * MaxFillWidth;
DrawTexture(Fill, Pos, DrawFlags, scale: (underScale, 1));
As you can see, the 1×20 texture is scaled horizontally to fill desired rectangular area. Then the shader is run over it to produce the (incorrectly) skewed bar.
Does anyone have any idea how to make it skew like I want? Is it possible, under the current constraints of GZDoom custom texture shaders?
I want to use ZScript to draw its HUD bars with a horizontal skew proportional to the [i]height[/i] of the bar, regardless of how much of the bar is filled. I've put together [b][url=http://svgur.com/s/3Ep]this web-based demonstration[/url][/b] (warning: doesn't show correctly in Microsoft IE/Edge) to show you what I have and what I want. The middle bar shows what I want; the bottom bar shows what I have.
[url=https://forum.zdoom.org/viewtopic.php?f=43&t=54914]Aetherius[/url] draws bars like I want on its HUD, by drawing each 1-pixel-wide sliver of the bar with a separate draw call. This is very slow. I'd like to help with that by skewing them with a shader instead, which should be much faster.
But I've got a problem. Currently, an ordinary texture can be drawn on the status bar, a shader can be attached to it via GLDEFS, and it can skew the texture just fine—but the horizontal skew is proportional to the scaled width of the texture, not the height! The result is like the bottom bar in the above demonstration.
This is my shader:
[code]
const mat2 shearMatrix = mat2(1, 20./220., 0, 1);
const vec4 trans = vec4(0., 0., 0., 0.);
vec4 Process(vec4 color) {
vec2 xy = gl_TexCoord[0].st;
xy -= .5;
xy.x *= 1. + (20. / 220.);
xy *= shearMatrix;
xy += .5;
if (xy.x < 0. || xy.x > 1.)
return trans * color;
else
return getTexel(xy) * color;
}
[/code]
I have it attached to a 1×20 texture named “HPBFILNV” in GLDEFS. I'm drawing it from a ZScript BaseStatusBar implementation like so:
[code]
SetSize(0, 1440, 1080);
int value = CPlayer.Health;
int MaxValue = CPlayer.mo.GetMaxHealth(true);
int MaxFillWidth = 200;
TextureID Fill = TexMan.CheckForTexture("HPBFILNV", TexMan.Type_Any);
Vector2 Pos = (250, -175);
int DrawFlags = DI_ITEM_LEFT_TOP | DI_SCREEN_LEFT_BOTTOM;
double scale = double(value) / double(MaxValue);
double underScale = min(scale, 1.0) * MaxFillWidth;
DrawTexture(Fill, Pos, DrawFlags, scale: (underScale, 1));
[/code]
As you can see, the 1×20 texture is scaled horizontally to fill desired rectangular area. Then the shader is run over it to produce the (incorrectly) skewed bar.
Does anyone have any idea how to make it skew like I want? Is it possible, under the current constraints of GZDoom custom texture shaders?