I need to clear the depth buffer, for which i use glClear(GL_DEPTH_BUFFER_BIT) in OpenGL, how to do in metal ? I have gone through apple's documentation, there is no hint about it.
The short answer is that to clear the depth buffer you add these two lines before beginning a render pass:
mRenderPassDescriptor.depthAttachment.loadAction = MTLLoadActionClear;
mRenderPassDescriptor.depthAttachment.clearDepth = 1.0f;
And you cannot do a clear without ending and restarting a render pass.
Long answer:
In Metal, you have to define that you want the colour and depth buffers cleared when you start rendering to a MTLTexture. There is no clear function like in OpenGL.
To do this, in your MTLRenderPassDescriptor, set depthAttachment.loadAction to MTLLoadActionClear and depthAttachment.clearDepth to 1.0f.
You may also want to set colorAttachments[0].loadAction to MTLLoadActionClear to clear the colour buffer.
This render pass descriptor is then passed in to your call to MTLCommandBuffer::renderCommandEncoderWithDescriptor.
If you do want to clear a depth or colour buffer midway through rendering you have to call endEncoding on MTLRenderCommandEncoder, and then start encoding again with depthAttachment.loadAction set to MTLLoadActionClear.
To explain the solution more clear with sample codes
Before start rendering:
void prepareRendering(){
CMDBuffer = [_commandQueue commandBuffer]; // get command Buffer
drawable = [_metalLayer nextDrawable]; // get drawable from metalLayer
renderingTexture = drawable.texture; // set that as rendering te
setupRenderPassDescriptorForTexture(drawable.texture); // set the depth and colour buffer properties
RenderCMDBuffer = [CMDBuffer renderCommandEncoderWithDescriptor:_renderPassDescriptor];
RenderCMDBuffer.label = @"MyRenderEncoder";
setUpDepthState(CompareFunctionLessEqual,true,false); //
[RenderCMDBuffer setDepthStencilState:_depthState];
[RenderCMDBuffer pushDebugGroup:@"DrawCube"];
}
void setupRenderPassDescriptorForTexture(id <MTLTexture> texture)
{
if (_renderPassDescriptor == nil)
_renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor];
// set color buffer properties
_renderPassDescriptor.colorAttachments[0].texture = texture;
_renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
_renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(1.0f, 1.0f,1.0f, 1.0f);
_renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
// set depth buffer properties
MTLTextureDescriptor* desc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat: MTLPixelFormatDepth32Float width: texture.width height: texture.height mipmapped: NO];
_depthTex = [device newTextureWithDescriptor: desc];
_depthTex.label = @"Depth";
_renderPassDescriptor.depthAttachment.texture = _depthTex;
_renderPassDescriptor.depthAttachment.loadAction = MTLLoadActionClear;
_renderPassDescriptor.depthAttachment.clearDepth = 1.0f;
_renderPassDescriptor.depthAttachment.storeAction = MTLStoreActionDontCare;
}
Render Your contents here
Render();
After rendering
similar to ogles2 method [_context presentRenderbuffer:_colorRenderBuffer];
void endDisplay()
{
[RenderCMDBuffer popDebugGroup];
[RenderCMDBuffer endEncoding];
[CMDBuffer presentDrawable:drawable];
[CMDBuffer commit];
_currentDrawable = nil;
}
The above methods clears the depth and colour buffers after rendering each frame
To clear the depth buffer in midway
void clearDepthBuffer(){
// end encoding the render command buffer
[RenderCMDBuffer popDebugGroup];
[RenderCMDBuffer endEncoding];
// here MTLLoadActionClear will clear your last drawn depth values
_renderPassDescriptor.depthAttachment.loadAction = MTLLoadActionClear; _renderPassDescriptor.depthAttachment.clearDepth = 1.0f;
_renderPassDescriptor.depthAttachment.storeAction = MTLStoreActionDontCare;
// here MTLLoadActionLoad will reuse your last drawn color buffer
_renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionLoad;
_renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
RenderCMDBuffer = [CMDBuffer renderCommandEncoderWithDescriptor:_renderPassDescriptor];
RenderCMDBuffer.label = @"MyRenderEncoder";
[RenderCMDBuffer pushDebugGroup:@"DrawCube"];
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With