302 lines
8.1 KiB
HLSL
302 lines
8.1 KiB
HLSL
#include "shared/point.hlsl"
|
|
#include "shared/quat-functions.hlsl"
|
|
|
|
static const float3 Corners[] =
|
|
{
|
|
float3(-1, -1, 0),
|
|
float3(1, -1, 0),
|
|
float3(1, 1, 0),
|
|
float3(1, 1, 0),
|
|
float3(-1, 1, 0),
|
|
float3(-1, -1, 0),
|
|
};
|
|
|
|
static const uint digits[5] = {
|
|
989790207, // 0b111 010 111 111 101 111 111 111 111 111 ,
|
|
707184749, // 0b101 010 001 001 101 100 100 001 101 101 ,
|
|
721420031, // 0b101 010 111 111 111 111 111 011 111 111 ,
|
|
713333353, // 0b101 010 100 001 001 001 101 001 101 001 ,
|
|
989658751, // 0b111 010 111 111 001 111 111 001 111 111
|
|
};
|
|
|
|
static const uint characters[5] = {
|
|
// -
|
|
14680064, // 0b000 000 111 000 000 000 000 000 000 000,
|
|
48234496, // 0b000 010 111 000 000 000 000 000 000 000,
|
|
1038090240, // 0b111 101 111 000 000 000 000 000 000 000,
|
|
48234496, // 0b000 010 111 010 000 000 000 000 000 000,
|
|
15204352, // 0b000 000 111 010 000 000 000 000 000 000
|
|
};
|
|
|
|
static const uint MinusCharIndex = 0;
|
|
static const uint NanCharIndex = 1;
|
|
|
|
static const int DigitCount = 8;
|
|
static const int LabelPadding = 1;
|
|
static const int2 DigitSize = int2(3, 5);
|
|
static const int DigitPadding = 1;
|
|
static const int2 PaddedDigitSize = DigitSize + DigitPadding;
|
|
static const int2 LabelSize = int2(DigitCount, 1) * PaddedDigitSize + 2 * LabelPadding - 1;
|
|
|
|
cbuffer Params : register(b0)
|
|
{
|
|
float4 Color;
|
|
float2 LabelOffset;
|
|
float Scale;
|
|
};
|
|
|
|
cbuffer IntParams : register(b1)
|
|
{
|
|
int StartIndex;
|
|
int ShowMode;
|
|
};
|
|
|
|
cbuffer Transforms : register(b2)
|
|
{
|
|
float4x4 CameraToClipSpace;
|
|
float4x4 ClipSpaceToCamera;
|
|
float4x4 WorldToCamera;
|
|
float4x4 CameraToWorld;
|
|
float4x4 WorldToClipSpace;
|
|
float4x4 ClipSpaceToWorld;
|
|
float4x4 ObjectToWorld;
|
|
float4x4 WorldToObject;
|
|
float4x4 ObjectToCamera;
|
|
float4x4 ObjectToClipSpace;
|
|
};
|
|
|
|
cbuffer FogParams : register(b3)
|
|
{
|
|
float4 FogColor;
|
|
float FogDistance;
|
|
float FogBias;
|
|
}
|
|
|
|
cbuffer RequestedResolution : register(b4)
|
|
{
|
|
float TargetWidth;
|
|
float TargetHeight;
|
|
}
|
|
|
|
struct psInput
|
|
{
|
|
float4 position : SV_POSITION;
|
|
float4 color : COLOR;
|
|
float2 uv : uv;
|
|
float fog : FOG;
|
|
int id : ID;
|
|
float attributeValue : VALUE;
|
|
};
|
|
|
|
sampler ClampedSampler : register(s0);
|
|
|
|
StructuredBuffer<Point> DataPoints : t0;
|
|
StructuredBuffer<Point> OverridePositionPoints : t1;
|
|
|
|
static const float NanPlaceholder = 999666.666;
|
|
static const int NotAnInt = -2147483647; // almost max neg
|
|
|
|
static const float Pow10[] = {
|
|
1, 10, 100, 1000, 10000, 100000, 1000000};
|
|
|
|
psInput vsMain(uint id : SV_VertexID)
|
|
{
|
|
uint overridePositionCount, stride;
|
|
OverridePositionPoints.GetDimensions(overridePositionCount, stride);
|
|
|
|
psInput output;
|
|
|
|
int quadIndex = id % 6;
|
|
int drawIndex = id / 6;
|
|
|
|
float3 quadPos = Corners[quadIndex];
|
|
|
|
int2 targetSize = int2(TargetWidth, TargetHeight);
|
|
int2 evenTargetSize = targetSize & 0xfffffffe;
|
|
int2 oddBit = targetSize & 1;
|
|
|
|
float3 pos = overridePositionCount > 0 ? OverridePositionPoints[drawIndex].Position
|
|
: DataPoints[drawIndex + StartIndex].Position;
|
|
|
|
float4 posInObject = float4(pos, 1);
|
|
float4 posInClipSpace = mul(posInObject, ObjectToClipSpace);
|
|
|
|
float width = 4.0 * DigitCount;
|
|
float height = 7;
|
|
|
|
float2 s = float2(width / targetSize.x, 7.0 / targetSize.y) * Scale;
|
|
int2 intLabelOffset = (int2)(LabelOffset.x + 30.0, LabelOffset.y - 10);
|
|
|
|
posInClipSpace.xyz /= posInClipSpace.w;
|
|
posInClipSpace.w = 1;
|
|
|
|
// posInClipSpace.xy = floor((posInClipSpace.xy + 1) * 0.5 * (float2)targetSize - oddBit) / (float2)evenTargetSize * 2 - 1;
|
|
|
|
float2 screenPos = ((posInClipSpace.xy + 1) * 0.5) * (float2)targetSize;
|
|
screenPos = floor(screenPos) + 0.5; // pixel center
|
|
posInClipSpace.xy = (screenPos / (float2)targetSize) * 2 - 1;
|
|
|
|
posInClipSpace.xy += quadPos.xy * s + float2(LabelOffset.x / (float)TargetWidth, LabelOffset.y / (float)TargetHeight);
|
|
output.position = posInClipSpace;
|
|
|
|
output.uv = (float2(0, 1) + (quadPos.xy * 0.5 + 0.5) * float2(1, -1)); //* float2(DigitCount,1);
|
|
|
|
if (ShowMode == 0)
|
|
{
|
|
output.id = drawIndex;
|
|
output.attributeValue = NanPlaceholder;
|
|
}
|
|
else
|
|
{
|
|
output.id = NotAnInt;
|
|
Point p = DataPoints[drawIndex + StartIndex];
|
|
float f = 0;
|
|
switch (ShowMode)
|
|
{
|
|
case 1:
|
|
f = p.FX1;
|
|
break;
|
|
case 2:
|
|
f = p.FX2;
|
|
break;
|
|
case 3:
|
|
f = p.Position.x;
|
|
break;
|
|
case 4:
|
|
f = p.Position.y;
|
|
break;
|
|
case 5:
|
|
f = p.Position.z;
|
|
break;
|
|
case 6:
|
|
f = p.Scale.x;
|
|
break;
|
|
case 7:
|
|
f = p.Scale.y;
|
|
break;
|
|
case 8:
|
|
f = p.Scale.z;
|
|
break;
|
|
case 9:
|
|
f = p.Color.r;
|
|
break;
|
|
case 10:
|
|
f = p.Color.g;
|
|
break;
|
|
case 11:
|
|
f = p.Color.b;
|
|
break;
|
|
case 12:
|
|
f = p.Color.a;
|
|
break;
|
|
}
|
|
|
|
output.attributeValue = isnan(f) ? NanPlaceholder : f;
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
float4 psMain(psInput input) : SV_TARGET
|
|
{
|
|
float2 uv = input.uv;
|
|
|
|
int2 pixelPos = (uv * LabelSize) - 0.5 / LabelSize;
|
|
// return float4(pixelPos * 1.0 / LabelSize, 0, 1);
|
|
|
|
int2 p1 = pixelPos - LabelPadding;
|
|
int2 digitIndex = p1 / PaddedDigitSize;
|
|
int2 pInDigit = p1 - digitIndex * PaddedDigitSize;
|
|
|
|
if (pInDigit.x > 2)
|
|
discard;
|
|
|
|
if (pInDigit.y > 4 || pInDigit.y < 0)
|
|
discard;
|
|
|
|
int2 decimalIndex = DigitCount - digitIndex - 1;
|
|
|
|
// Draw int index
|
|
int intValue = input.id + StartIndex;
|
|
if (intValue != NotAnInt)
|
|
{
|
|
// Integer...
|
|
int requiredDigitCount = intValue == 0 ? 0 : log10(intValue);
|
|
if (requiredDigitCount < decimalIndex.x)
|
|
discard;
|
|
|
|
int digit = int((intValue / pow(10, decimalIndex.x))) % 10;
|
|
bool bit = digits[pInDigit.y] >> ((10 - digit) * 3 - pInDigit.x - 1) & 1;
|
|
if (!bit)
|
|
discard;
|
|
|
|
return Color;
|
|
}
|
|
// Attempt to draw float value
|
|
else
|
|
{
|
|
float floatValue = input.attributeValue;
|
|
if (floatValue == NanPlaceholder)
|
|
{
|
|
if (decimalIndex.x == 0)
|
|
{
|
|
bool bit = characters[pInDigit.y] >> ((10 - NanCharIndex) * 3 - pInDigit.x - 1) & 1;
|
|
if (bit)
|
|
return Color;
|
|
}
|
|
discard;
|
|
}
|
|
|
|
bool isNegative = floatValue < -0.0001;
|
|
|
|
if (isNegative)
|
|
{
|
|
floatValue *= -1;
|
|
}
|
|
|
|
const int decimalPosition = 3;
|
|
|
|
// Add gap for decimal point
|
|
if (decimalIndex.x == decimalPosition)
|
|
{
|
|
bool bit = characters[pInDigit.y] >> ((10 - 3) * 3 - pInDigit.x - 1) & 1;
|
|
if (bit)
|
|
return Color;
|
|
|
|
discard;
|
|
}
|
|
|
|
decimalIndex += (decimalIndex <= decimalPosition - 1) ? 1 : 0;
|
|
|
|
int requiredDigitCount = floatValue == 0 ? 1 : (log10(floatValue) + decimalPosition);
|
|
bool needsLeadingZero = floatValue < 1;
|
|
|
|
if (requiredDigitCount < decimalIndex.x - 1 - (needsLeadingZero ? 1 : 0))
|
|
{
|
|
if (isNegative && requiredDigitCount == decimalIndex.x - 2 - ((needsLeadingZero ? 1 : 0)))
|
|
{
|
|
bool bit = characters[pInDigit.y] >> ((10 - MinusCharIndex) * 3 - pInDigit.x - 1) & 1;
|
|
if (bit)
|
|
return Color;
|
|
}
|
|
discard;
|
|
}
|
|
|
|
// double scaled = round(floatValue * pow(10, decimalPosition));
|
|
// int digit = int(scaled / pow(10, decimalPosition - decimalIndex.x)) % 10;
|
|
|
|
int digit = int(((floatValue + 0.0001) / pow(10, decimalIndex.x - decimalPosition - 1))) % 10;
|
|
|
|
// float scale = Pow10[clamp(decimalIndex.x - decimalPosition - 1, 0, 7)];
|
|
// int digit = int((round(floatValue * Pow10[decimalPosition]) / scale)) % 10;
|
|
|
|
bool bit = digits[pInDigit.y] >> ((10 - digit) * 3 - pInDigit.x - 1) & 1;
|
|
if (!bit)
|
|
discard;
|
|
|
|
return Color;
|
|
|
|
return 1;
|
|
}
|
|
}
|