1

I am new to Metal Framework, and I just downloaded the "HelloTriangle" listed here: https://developer.apple.com/documentation/metal/using_a_render_pipeline_to_render_primitives?language=objc

I am trying to mask/clip the area filled in by the color specified via MTLRenderPassDescriptor.colorAttachment[0].clearColor to a specific area. Can this be done in anyway?

From this: enter image description here

To this, (assuming the black is transparent):

enter image description here

I tried using [renderEncoder setScissorRect:(MTLScissorRect){x, y, w, h}]; but it only mask the triangle and not the yellow background

Reason for my question: This example is a simplified version of the issue I am trying to fix in my project. Most of the widget's background color in my project is set via colorAttachment[0].clearColor and I just need to mask it to certain smaller region in some case so that the area outside the clipping will just show other existing widgets at those area.

Here is the code snippet of the function

- (void)drawInMTKView:(nonnull MTKView *)view
{
    static const AAPLVertex triangleVertices[] =
    {
        // 2D positions,    RGBA colors
        { {  250,  -250 }, { 1, 0, 0, 1 } },
        { { -250,  -250 }, { 0, 1, 0, 1 } },
        { {    0,   250 }, { 0, 0, 1, 1 } },
    };

    // Create a new command buffer for each render pass to the current drawable.
    id<MTLCommandBuffer> commandBuffer = [_commandQueue commandBuffer];
    commandBuffer.label = @"MyCommand";

    // Obtain a renderPassDescriptor generated from the view's drawable textures.
    MTLRenderPassDescriptor *renderPassDescriptor = view.currentRenderPassDescriptor;

    if(renderPassDescriptor != nil)
    {
        renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(1.0, 1.0, 0.0, 1.0); // Yellow background
        
        // Create a render command encoder.
        id<MTLRenderCommandEncoder> renderEncoder =
        [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
        renderEncoder.label = @"MyRenderEncoder";

        // Set the region of the drawable to draw into.
        [renderEncoder setViewport:(MTLViewport){0.0, 0.0, _viewportSize.x, _viewportSize.y, 0.0, 1.0 }];
        
//        [renderEncoder setScissorRect:(MTLScissorRect){700, 350, 200, 500}];
        
        [renderEncoder setRenderPipelineState:_pipelineState];

        // Pass in the parameter data.
        [renderEncoder setVertexBytes:triangleVertices
                               length:sizeof(triangleVertices)
                              atIndex:AAPLVertexInputIndexVertices];
        
        [renderEncoder setVertexBytes:&_viewportSize
                               length:sizeof(_viewportSize)
                              atIndex:AAPLVertexInputIndexViewportSize];

        // Draw the triangle.
        [renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle
                          vertexStart:0
                          vertexCount:3];

        [renderEncoder endEncoding];

        // Schedule a present once the framebuffer is complete using the current drawable.
        [commandBuffer presentDrawable:view.currentDrawable];
    }

    // Finalize rendering here & push the command buffer to the GPU.
    [commandBuffer commit];
}

Thanks in advance.

sivan
  • 120
  • 1
  • 9
  • Does this answer your question? [Alpha / Transparency & MTKView?](https://stackoverflow.com/questions/47643974/alpha-transparency-mtkview) – Jeshua Lacock Jan 18 '22 at 20:14
  • @JeshuaLacock, no. I am aware of this. The problem with this is, I will have to manually draw a yellow rect at the area that is unclipped – sivan Jan 19 '22 at 01:55
  • I see - I retracted my duplicate flag. Hmm, based on the images, it seems like you just want to change the primitive shape rect so that it is a fraction of the view's width and offset its' position half the difference. – Jeshua Lacock Jan 19 '22 at 21:25
  • Yes, clipping. I just want the clipping to be applied to my background color too, which in this case is set via colorAttachment[0].clearColor. Not sure if it's possible, so checking here. My workaround would be the same way that you have stated – sivan Jan 20 '22 at 01:56
  • I'm pretty sure that the answer is if you need to "clear" just part of your attachment, you need to draw a quad. I don't think there's any way to make the clear load action clear just part of the texture. – JustSomeGuy Jan 21 '22 at 19:44
  • @JustSomeGuy, yeah, looks like it. Thanks! – sivan Jan 26 '22 at 02:39

0 Answers0