Reputation: 673
I've followed the lecture given on WWDC2014 on how to use Metal API where they're creating "Hello world" app with a simple triangle. I'm expecting to see a red triangle on green background. Everything is great, but the triangle itself isn't there and I can't figure out why. Please help!
these lines are metal shaders:
struct Vertex
{
float3 position;
};
struct VertexOut
{
float4 position [[position]];
float4 color;
};
vertex VertexOut myVertexShader(
device Vertex* vertexArray [[ buffer(0) ]],
unsigned int vid [[ vertex_id ]])
{
VertexOut out;
float3 pos = vertexArray[vid].position;
out.position = float4(pos[0], pos[1], pos[2], 0.0);
out.color = float4(1.0, 0.0, 0.0, 1.0);
return out;
}
fragment float4 myFragmentShader(VertexOut interpolated [[ stage_in ]])
{
return interpolated.color;
}
these are view:
@implementation MyView
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if(self)
{
_device = MTLCreateSystemDefaultDevice();
}
NSLog(@"MyView::initWithCoder called");
return self;
}
+(id)layerClass
{
return [CAMetalLayer class];
}
@end
and these are view controller:
static const float zcoord = 0.f;
static const float vertexArrayData[] =
{
-0.3, -0.5, zcoord,
0.3, -0.5, zcoord,
0.f, 0.2, zcoord
};
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
MyView* view = (MyView*) self.view;
id<MTLCommandQueue> queue = [view.device newCommandQueue];
id<MTLBuffer> vertexArray = [view.device newBufferWithBytes:vertexArrayData
length:sizeof(vertexArrayData)
options:0];
MTLRenderPipelineDescriptor* desc = [MTLRenderPipelineDescriptor new];
id<MTLLibrary> lib = [view.device newDefaultLibrary];
desc.vertexFunction = [lib newFunctionWithName:@"myVertexShader"];
desc.fragmentFunction = [lib newFunctionWithName:@"myFragmentShader"];
desc.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm;
id<MTLRenderPipelineState> renderPipeline = [view.device newRenderPipelineStateWithDescriptor:desc error:nil];
id<MTLCommandBuffer> commandBuffer = [queue commandBuffer];
id<CAMetalDrawable> drawable = [(CAMetalLayer*)view.layer nextDrawable];
MTLRenderPassDescriptor* renderDesc = [MTLRenderPassDescriptor new];
renderDesc.colorAttachments[0].texture = drawable.texture;
renderDesc.colorAttachments[0].loadAction = MTLLoadActionClear;
renderDesc.colorAttachments[0].clearColor = MTLClearColorMake(0.0, 1.0, 0.0, 1.0);
id<MTLRenderCommandEncoder> render = [commandBuffer renderCommandEncoderWithDescriptor:renderDesc];
[render setRenderPipelineState:renderPipeline];
[render setVertexBuffer:vertexArray offset:0 atIndex:0];
[render drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:3];
[render endEncoding];
[commandBuffer presentDrawable:drawable];
[commandBuffer commit];
}
Upvotes: 1
Views: 231
Reputation: 673
I've got it, fellas.
The problem is in this line:
out.position = float4(pos[0], pos[1], pos[2], 0.0);
the last component of float4 shouldn't be zero. Putting 1.0 helped.
Regards
Upvotes: 2