iOS-Metal:如何清除Depth Buffer?与OpenGL中的glClear(GL_DEPTH_BUFFER_BIT)类似

时间:2022-04-26 04:02:28

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.

我需要清除深度缓冲区,我在OpenGL中使用glClear(GL_DEPTH_BUFFER_BIT),如何做金属?我已经浏览了苹果的文档,没有任何暗示。

2 个解决方案

#1


2  

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.

简短的回答是清除深度缓冲区,在开始渲染过程之前添加这两行:mRenderPassDescriptor.depthAttachment.loadAction = MTLLoadActionClear; mRenderPassDescriptor.depthAttachment.clearDepth = 1.0f;如果没有结束并重新启动渲染过程,你就无法做到清晰。

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.

在Metal中,您必须定义在开始渲染到MTLTexture时要清除颜色和深度缓冲区。在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.

为此,在MTLRenderPassDescriptor中,将depthAttachment.loadAction设置为MTLLoadActionClear,将depthAttachment.clearDepth设置为1.0f。您可能还想将colorAttachments [0] .loadAction设置为MTLLoadActionClear以清除颜色缓冲区。

This render pass descriptor is then passed in to your call to MTLCommandBuffer::renderCommandEncoderWithDescriptor.

然后将此渲染传递描述符传递给对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.

如果您确实希望在渲染过程中途清除深度或颜色缓冲区,则必须在MTLRenderCommandEncoder上调用endEncoding,然后再将depthAttachment.loadAction设置为MTLLoadActionClear再次开始编码。

#2


0  

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];

类似于ogles2方法[_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"];
        }

#1


2  

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.

简短的回答是清除深度缓冲区,在开始渲染过程之前添加这两行:mRenderPassDescriptor.depthAttachment.loadAction = MTLLoadActionClear; mRenderPassDescriptor.depthAttachment.clearDepth = 1.0f;如果没有结束并重新启动渲染过程,你就无法做到清晰。

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.

在Metal中,您必须定义在开始渲染到MTLTexture时要清除颜色和深度缓冲区。在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.

为此,在MTLRenderPassDescriptor中,将depthAttachment.loadAction设置为MTLLoadActionClear,将depthAttachment.clearDepth设置为1.0f。您可能还想将colorAttachments [0] .loadAction设置为MTLLoadActionClear以清除颜色缓冲区。

This render pass descriptor is then passed in to your call to MTLCommandBuffer::renderCommandEncoderWithDescriptor.

然后将此渲染传递描述符传递给对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.

如果您确实希望在渲染过程中途清除深度或颜色缓冲区,则必须在MTLRenderCommandEncoder上调用endEncoding,然后再将depthAttachment.loadAction设置为MTLLoadActionClear再次开始编码。

#2


0  

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];

类似于ogles2方法[_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"];
        }