mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-23 03:32:32 +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>
|
#import <Metal/Metal.h>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct Uniforms {
|
||||||
|
int32_t scale[2];
|
||||||
|
float lineWidth;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@implementation CSScanTarget {
|
@implementation CSScanTarget {
|
||||||
id<MTLCommandQueue> _commandQueue;
|
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> _vertexShader;
|
||||||
id<MTLFunction> _fragmentShader;
|
id<MTLFunction> _fragmentShader;
|
||||||
id<MTLBuffer> _verticesBuffer;
|
|
||||||
id<MTLRenderPipelineState> _gouraudPipeline;
|
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 {
|
- (nonnull instancetype)initWithView:(nonnull MTKView *)view {
|
||||||
@ -27,42 +37,35 @@
|
|||||||
if(self) {
|
if(self) {
|
||||||
_commandQueue = [view.device newCommandQueue];
|
_commandQueue = [view.device newCommandQueue];
|
||||||
|
|
||||||
// Generate some static buffers. AS A TEST.
|
// Install the standard quad.
|
||||||
constexpr float vertices[] = {
|
constexpr float vertices[] = {
|
||||||
-0.9f, -0.9f, // Position.
|
-0.9f, -0.9f,
|
||||||
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.9f, -0.9f,
|
||||||
0.0f, 0.0f, 1.0f,
|
|
||||||
|
|
||||||
0.9f, 0.9f,
|
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];
|
MTLVertexDescriptor *vertexDescriptor = [[MTLVertexDescriptor alloc] init];
|
||||||
|
|
||||||
// Position.
|
|
||||||
vertexDescriptor.attributes[0].bufferIndex = 0;
|
vertexDescriptor.attributes[0].bufferIndex = 0;
|
||||||
vertexDescriptor.attributes[0].offset = 0;
|
vertexDescriptor.attributes[0].offset = 0;
|
||||||
vertexDescriptor.attributes[0].format = MTLVertexFormatFloat2;
|
vertexDescriptor.attributes[0].format = MTLVertexFormatFloat2;
|
||||||
|
vertexDescriptor.layouts[0].stride = sizeof(float)*2;
|
||||||
// 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;
|
|
||||||
|
|
||||||
// Generate TEST pipeline.
|
// Generate TEST pipeline.
|
||||||
id<MTLLibrary> library = [view.device newDefaultLibrary];
|
id<MTLLibrary> library = [view.device newDefaultLibrary];
|
||||||
MTLRenderPipelineDescriptor *pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
|
MTLRenderPipelineDescriptor *pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
|
||||||
pipelineDescriptor.vertexFunction = [library newFunctionWithName:@"vertex_main"];
|
pipelineDescriptor.vertexFunction = [library newFunctionWithName:@"scanVertexMain"];
|
||||||
pipelineDescriptor.fragmentFunction = [library newFunctionWithName:@"fragment_main"];
|
pipelineDescriptor.fragmentFunction = [library newFunctionWithName:@"scanFragmentMain"];
|
||||||
pipelineDescriptor.colorAttachments[0].pixelFormat = view.colorPixelFormat;
|
pipelineDescriptor.colorAttachments[0].pixelFormat = view.colorPixelFormat;
|
||||||
pipelineDescriptor.vertexDescriptor = vertexDescriptor;
|
pipelineDescriptor.vertexDescriptor = vertexDescriptor;
|
||||||
_gouraudPipeline = [view.device newRenderPipelineStateWithDescriptor:pipelineDescriptor error:nil];
|
_gouraudPipeline = [view.device newRenderPipelineStateWithDescriptor:pipelineDescriptor error:nil];
|
||||||
@ -70,6 +73,11 @@
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setUniforms:(const Uniforms &)uniforms {
|
||||||
|
memcpy(_uniformsBuffer.contents, &uniforms, sizeof(Uniforms));
|
||||||
|
// [_uniformsBuffer didModifyRange:NSMakeRange(0, sizeof(Uniforms))];
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@method mtkView:drawableSizeWillChange:
|
@method mtkView:drawableSizeWillChange:
|
||||||
@abstract Called whenever the drawableSize of the view will change
|
@abstract Called whenever the drawableSize of the view will change
|
||||||
@ -95,7 +103,10 @@
|
|||||||
|
|
||||||
// Drawing. Just the test triangle, as described above.
|
// Drawing. Just the test triangle, as described above.
|
||||||
[encoder setRenderPipelineState:_gouraudPipeline];
|
[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];
|
[encoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4 instanceCount:1];
|
||||||
|
|
||||||
// Complete encoding.
|
// Complete encoding.
|
||||||
|
@ -12,23 +12,52 @@ using namespace metal;
|
|||||||
// These two structs are the same, but defined separately as an artefact
|
// 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.
|
// 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)]];
|
float2 position [[attribute(0)]];
|
||||||
float3 colour [[attribute(1)]];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ColouredVertex {
|
struct ColouredVertex {
|
||||||
float4 position [[position]];
|
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;
|
ColouredVertex output;
|
||||||
output.position = float4(vert.position, 0.0, 1.0);
|
output.position = float4(vert.position * uniforms.lineWidth, 0.0, 1.0);
|
||||||
output.colour = float4(vert.colour, 1.0);
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
fragment float4 fragment_main(ColouredVertex vert [[stage_in]]) {
|
fragment float4 scanFragmentMain(ColouredVertex vert [[stage_in]]) {
|
||||||
return vert.colour;
|
return float4(1.0);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user