diff --git a/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.mm b/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.mm index 76f774a6f..9ba322226 100644 --- a/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.mm +++ b/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.mm @@ -16,6 +16,7 @@ namespace { struct Uniforms { int32_t scale[2]; float lineWidth; + float aspectRatioMultiplier; }; constexpr size_t NumBufferedScans = 2048; @@ -33,6 +34,9 @@ constexpr size_t NumBufferedScans = 2048; id _quadBuffer; // i.e. four vertices defining a quad. id _uniformsBuffer; id _scansBuffer; + + // Current uniforms. + Uniforms _uniforms; } - (nonnull instancetype)initWithView:(nonnull MTKView *)view { @@ -51,11 +55,11 @@ constexpr size_t NumBufferedScans = 2048; // Allocate space for uniforms. _uniformsBuffer = [view.device newBufferWithLength:16 options:MTLResourceCPUCacheModeWriteCombined]; - const Uniforms testUniforms = { - .scale = {1024, 1024}, - .lineWidth = 1.0f / 312.0f - }; - [self setUniforms:testUniforms]; + _uniforms.scale[0] = 1024; + _uniforms.scale[1] = 1024; + _uniforms.lineWidth = 1.0f / 312.0f; + _uniforms.aspectRatioMultiplier = 1.0f; + [self setUniforms]; // Allocate a large buffer for scans. _scansBuffer = [view.device @@ -70,7 +74,7 @@ constexpr size_t NumBufferedScans = 2048; vertexDescriptor.attributes[0].format = MTLVertexFormatFloat2; vertexDescriptor.layouts[0].stride = sizeof(float)*2; - // Create a scans buffer, and for now just put two in there. + // TODO: shouldn't I need to explain the Scan layout, too? Or do these things not need to be specified when compatible? // Generate TEST pipeline. id library = [view.device newDefaultLibrary]; @@ -85,8 +89,8 @@ constexpr size_t NumBufferedScans = 2048; return self; } -- (void)setUniforms:(const Uniforms &)uniforms { - memcpy(_uniformsBuffer.contents, &uniforms, sizeof(Uniforms)); +- (void)setUniforms { + memcpy(_uniformsBuffer.contents, &_uniforms, sizeof(Uniforms)); } - (void)setTestScans { @@ -112,8 +116,8 @@ constexpr size_t NumBufferedScans = 2048; @param size New drawable size in pixels */ - (void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size { - // I think (?) I don't care about this; the MKLView has already handled resizing the backing, - // which will naturally change the viewport. + _uniforms.aspectRatioMultiplier = float((4.0 / 3.0) / (size.width / size.height)); + [self setUniforms]; } /*! diff --git a/OSBindings/Mac/Clock Signal/ScanTarget/ScanTarget.metal b/OSBindings/Mac/Clock Signal/ScanTarget/ScanTarget.metal index e4610583e..f64876228 100644 --- a/OSBindings/Mac/Clock Signal/ScanTarget/ScanTarget.metal +++ b/OSBindings/Mac/Clock Signal/ScanTarget/ScanTarget.metal @@ -17,8 +17,11 @@ struct Uniforms { // for mapping from scan-style integer positions into eye space. int2 scale [[attribute(0)]]; - // This provides the intended width of a scan, in eye-coordinate terms. + // This provides the intended height of a scan, in eye-coordinate terms. float lineWidth [[attribute(1)]]; + + // Provides a scaling factor in order to preserve 4:3 central content. + float aspectRatioMultiplier [[attribute(2)]]; }; // This is intended to match `Scan` as defined by the BufferingScanTarget. @@ -53,7 +56,7 @@ vertex ColouredVertex scanVertexMain( QuadInputVertex vert [[stage_in]], constant Uniforms &uniforms [[buffer(1)]], constant Scan *scans [[buffer(2)]], ushort instance [[instance_id]]) { - // Unpack start and end vertices. + // Unpack start and end vertices; little-endian numbers are assumed here. const float2 start = float2( float(scans[instance].startPosition & 0xffff) / float(uniforms.scale.x), float(scans[instance].startPosition >> 16) / float(uniforms.scale.y) @@ -70,7 +73,7 @@ vertex ColouredVertex scanVertexMain( QuadInputVertex vert [[stage_in]], // Hence determine this quad's real shape. ColouredVertex output; output.position = float4( - (start + vert.position.x * tangent + vert.position.y * normal * uniforms.lineWidth) * float2(2.0, -2.0) + float2(-1.0, 1.0), + ((start + vert.position.x * tangent + vert.position.y * normal * uniforms.lineWidth) * float2(2.0, -2.0) + float2(-1.0, 1.0)) * float2(uniforms.aspectRatioMultiplier, 1.0), 0.0, 1.0 );