2020-08-05 01:49:01 +00:00
|
|
|
//
|
|
|
|
// ScanTarget.metal
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 04/08/2020.
|
|
|
|
// Copyright © 2020 Thomas Harte. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#include <metal_stdlib>
|
|
|
|
using namespace metal;
|
|
|
|
|
2020-08-08 01:19:17 +00:00
|
|
|
struct Uniforms {
|
|
|
|
// This is used to scale scan positions, i.e. it provides the range
|
|
|
|
// for mapping from scan-style integer positions into eye space.
|
|
|
|
int2 scale [[attribute(0)]];
|
|
|
|
|
2020-08-08 02:29:24 +00:00
|
|
|
// This provides the intended height of a scan, in eye-coordinate terms.
|
2020-08-08 01:19:17 +00:00
|
|
|
float lineWidth [[attribute(1)]];
|
2020-08-08 02:29:24 +00:00
|
|
|
|
|
|
|
// Provides a scaling factor in order to preserve 4:3 central content.
|
|
|
|
float aspectRatioMultiplier [[attribute(2)]];
|
2020-08-08 01:19:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// This is intended to match `Scan` as defined by the BufferingScanTarget.
|
|
|
|
// Fields have been combined as necessary to make them all at least four
|
|
|
|
// bytes in size, since that is the required attribute alignment in Swift.
|
|
|
|
struct Scan {
|
|
|
|
uint32_t startPosition [[attribute(0)]];
|
|
|
|
uint32_t startOffsetAndAngle [[attribute(1)]];
|
|
|
|
uint32_t startCycles [[attribute(2)]];
|
|
|
|
|
|
|
|
uint32_t endPosition [[attribute(3)]];
|
|
|
|
uint32_t endOffsetAndAngle [[attribute(4)]];
|
|
|
|
uint32_t endCycles [[attribute(5)]];
|
|
|
|
|
|
|
|
uint32_t compositeAmplitude [[attribute(6)]];
|
|
|
|
uint32_t dataYAndLine [[attribute(7)]];
|
|
|
|
};
|
|
|
|
|
2020-08-05 21:27:43 +00:00
|
|
|
struct ColouredVertex {
|
2020-08-05 01:49:01 +00:00
|
|
|
float4 position [[position]];
|
|
|
|
};
|
|
|
|
|
2020-08-08 01:19:17 +00:00
|
|
|
|
|
|
|
// MARK: - Scan shaders; these do final output to the display.
|
|
|
|
|
2020-08-08 21:12:49 +00:00
|
|
|
vertex ColouredVertex scanVertexMain( constant Uniforms &uniforms [[buffer(1)]],
|
|
|
|
constant Scan *scans [[buffer(0)]],
|
|
|
|
uint instanceID [[instance_id]],
|
|
|
|
uint vertexID [[vertex_id]]) {
|
2020-08-08 02:29:24 +00:00
|
|
|
// Unpack start and end vertices; little-endian numbers are assumed here.
|
2020-08-08 02:20:01 +00:00
|
|
|
const float2 start = float2(
|
2020-08-08 21:12:49 +00:00
|
|
|
float(scans[instanceID].startPosition & 0xffff) / float(uniforms.scale.x),
|
|
|
|
float(scans[instanceID].startPosition >> 16) / float(uniforms.scale.y)
|
2020-08-08 02:20:01 +00:00
|
|
|
);
|
|
|
|
const float2 end = float2(
|
2020-08-08 21:12:49 +00:00
|
|
|
float(scans[instanceID].endPosition & 0xffff) / float(uniforms.scale.x),
|
|
|
|
float(scans[instanceID].endPosition >> 16) / float(uniforms.scale.y)
|
2020-08-08 02:20:01 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
// Calculate the tangent and normal.
|
2020-08-08 21:12:49 +00:00
|
|
|
const float2 tangent = (end - start);
|
2020-08-08 02:20:01 +00:00
|
|
|
const float2 normal = float2(-tangent.y, tangent.x) / length(tangent);
|
|
|
|
|
|
|
|
// Hence determine this quad's real shape.
|
2020-08-05 21:27:43 +00:00
|
|
|
ColouredVertex output;
|
2020-08-08 02:20:01 +00:00
|
|
|
output.position = float4(
|
2020-08-08 21:12:49 +00:00
|
|
|
((start + (float(vertexID&2) * 0.5) * tangent + (float(vertexID&1) - 0.5) * normal * uniforms.lineWidth) * float2(2.0, -2.0) + float2(-1.0, 1.0)) * float2(uniforms.aspectRatioMultiplier, 1.0),
|
2020-08-08 02:20:01 +00:00
|
|
|
0.0,
|
|
|
|
1.0
|
|
|
|
);
|
2020-08-05 21:27:43 +00:00
|
|
|
return output;
|
2020-08-05 01:49:01 +00:00
|
|
|
}
|
|
|
|
|
2020-08-08 01:19:17 +00:00
|
|
|
fragment float4 scanFragmentMain(ColouredVertex vert [[stage_in]]) {
|
|
|
|
return float4(1.0);
|
2020-08-05 01:49:01 +00:00
|
|
|
}
|