mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 23:52:26 +00:00
Gets some uniforms in on the action.
With some effort towards scans, but incompletely so.
This commit is contained in:
parent
4c9418f59a
commit
4421acef34
@ -10,16 +10,26 @@
|
||||
|
||||
#import <Metal/Metal.h>
|
||||
|
||||
namespace {
|
||||
|
||||
struct Uniforms {
|
||||
int32_t scale[2];
|
||||
float lineWidth;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@implementation CSScanTarget {
|
||||
id<MTLCommandQueue> _commandQueue;
|
||||
|
||||
// TEST ONLY: to check that I'm drawing _something_, I'm heading towards ye standard
|
||||
// Gouraud shading triangle. https://metalbyexample.com/up-and-running-2/ is providing
|
||||
// much of the inspiration, albeit that I'm proceeding via MKLView.
|
||||
id<MTLFunction> _vertexShader;
|
||||
id<MTLFunction> _fragmentShader;
|
||||
id<MTLBuffer> _verticesBuffer;
|
||||
id<MTLRenderPipelineState> _gouraudPipeline;
|
||||
|
||||
// Buffers.
|
||||
id<MTLBuffer> _quadBuffer; // i.e. four vertices defining a quad.
|
||||
id<MTLBuffer> _uniformsBuffer;
|
||||
id<MTLBuffer> _scansBuffer;
|
||||
}
|
||||
|
||||
- (nonnull instancetype)initWithView:(nonnull MTKView *)view {
|
||||
@ -27,42 +37,35 @@
|
||||
if(self) {
|
||||
_commandQueue = [view.device newCommandQueue];
|
||||
|
||||
// Generate some static buffers. AS A TEST.
|
||||
// Install the standard quad.
|
||||
constexpr float vertices[] = {
|
||||
-0.9f, -0.9f, // Position.
|
||||
1.0f, 0.0f, 0.0f, // Colour.
|
||||
|
||||
-0.9f, -0.9f,
|
||||
-0.9f, 0.9f,
|
||||
0.0f, 1.0f, 0.0f,
|
||||
|
||||
0.9f, -0.9f,
|
||||
0.0f, 0.0f, 1.0f,
|
||||
|
||||
0.9f, 0.9f,
|
||||
0.0f, 1.0f, 1.0f,
|
||||
};
|
||||
_verticesBuffer = [view.device newBufferWithBytes:vertices length:sizeof(vertices) options:MTLResourceOptionCPUCacheModeDefault];
|
||||
_quadBuffer = [view.device newBufferWithBytes:vertices length:sizeof(vertices) options:MTLResourceCPUCacheModeDefaultCache];
|
||||
|
||||
// Allocate space for uniforms.
|
||||
_uniformsBuffer = [view.device newBufferWithLength:16 options:MTLResourceCPUCacheModeWriteCombined];
|
||||
Uniforms testUniforms = {
|
||||
.scale = {0, 0},
|
||||
.lineWidth = 0.1f
|
||||
};
|
||||
[self setUniforms:testUniforms];
|
||||
|
||||
// The quad buffer has only 2d positions.
|
||||
MTLVertexDescriptor *vertexDescriptor = [[MTLVertexDescriptor alloc] init];
|
||||
|
||||
// Position.
|
||||
vertexDescriptor.attributes[0].bufferIndex = 0;
|
||||
vertexDescriptor.attributes[0].offset = 0;
|
||||
vertexDescriptor.attributes[0].format = MTLVertexFormatFloat2;
|
||||
|
||||
// Colour.
|
||||
vertexDescriptor.attributes[1].bufferIndex = 0;
|
||||
vertexDescriptor.attributes[1].offset = sizeof(float)*2;
|
||||
vertexDescriptor.attributes[1].format = MTLVertexFormatFloat3;
|
||||
|
||||
// Total vertex size.
|
||||
vertexDescriptor.layouts[0].stride = sizeof(float)*5;
|
||||
vertexDescriptor.layouts[0].stride = sizeof(float)*2;
|
||||
|
||||
// Generate TEST pipeline.
|
||||
id<MTLLibrary> library = [view.device newDefaultLibrary];
|
||||
MTLRenderPipelineDescriptor *pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
|
||||
pipelineDescriptor.vertexFunction = [library newFunctionWithName:@"vertex_main"];
|
||||
pipelineDescriptor.fragmentFunction = [library newFunctionWithName:@"fragment_main"];
|
||||
pipelineDescriptor.vertexFunction = [library newFunctionWithName:@"scanVertexMain"];
|
||||
pipelineDescriptor.fragmentFunction = [library newFunctionWithName:@"scanFragmentMain"];
|
||||
pipelineDescriptor.colorAttachments[0].pixelFormat = view.colorPixelFormat;
|
||||
pipelineDescriptor.vertexDescriptor = vertexDescriptor;
|
||||
_gouraudPipeline = [view.device newRenderPipelineStateWithDescriptor:pipelineDescriptor error:nil];
|
||||
@ -70,6 +73,11 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setUniforms:(const Uniforms &)uniforms {
|
||||
memcpy(_uniformsBuffer.contents, &uniforms, sizeof(Uniforms));
|
||||
// [_uniformsBuffer didModifyRange:NSMakeRange(0, sizeof(Uniforms))];
|
||||
}
|
||||
|
||||
/*!
|
||||
@method mtkView:drawableSizeWillChange:
|
||||
@abstract Called whenever the drawableSize of the view will change
|
||||
@ -95,7 +103,10 @@
|
||||
|
||||
// Drawing. Just the test triangle, as described above.
|
||||
[encoder setRenderPipelineState:_gouraudPipeline];
|
||||
[encoder setVertexBuffer:_verticesBuffer offset:0 atIndex:0];
|
||||
|
||||
[encoder setVertexBuffer:_quadBuffer offset:0 atIndex:0];
|
||||
[encoder setVertexBuffer:_uniformsBuffer offset:0 atIndex:1];
|
||||
|
||||
[encoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4 instanceCount:1];
|
||||
|
||||
// Complete encoding.
|
||||
|
@ -12,23 +12,52 @@ using namespace metal;
|
||||
// These two structs are the same, but defined separately as an artefact
|
||||
// of my learning process, and the fact that they soon won't be.
|
||||
|
||||
struct InputVertex {
|
||||
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)]];
|
||||
|
||||
// This provides the intended width of a scan, in eye-coordinate terms.
|
||||
float lineWidth [[attribute(1)]];
|
||||
};
|
||||
|
||||
// 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)]];
|
||||
};
|
||||
|
||||
// This is a custom thing defining one corner of a quad.
|
||||
struct QuadInputVertex {
|
||||
float2 position [[attribute(0)]];
|
||||
float3 colour [[attribute(1)]];
|
||||
};
|
||||
|
||||
struct ColouredVertex {
|
||||
float4 position [[position]];
|
||||
float4 colour;
|
||||
};
|
||||
|
||||
vertex ColouredVertex vertex_main(InputVertex vert [[stage_in]]) {
|
||||
|
||||
// MARK: - Scan shaders; these do final output to the display.
|
||||
|
||||
vertex ColouredVertex scanVertexMain( QuadInputVertex vert [[stage_in]],
|
||||
constant Uniforms &uniforms [[buffer(1)]],
|
||||
constant Scan *scans [[buffer(2)]],
|
||||
ushort instance [[instance_id]]) {
|
||||
ColouredVertex output;
|
||||
output.position = float4(vert.position, 0.0, 1.0);
|
||||
output.colour = float4(vert.colour, 1.0);
|
||||
output.position = float4(vert.position * uniforms.lineWidth, 0.0, 1.0);
|
||||
return output;
|
||||
}
|
||||
|
||||
fragment float4 fragment_main(ColouredVertex vert [[stage_in]]) {
|
||||
return vert.colour;
|
||||
fragment float4 scanFragmentMain(ColouredVertex vert [[stage_in]]) {
|
||||
return float4(1.0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user