Copying Metal Texture Of Previous Drawable to Current Drawable With Alpha Information

Hi everyone I am trying to take the texture from a previous draw call that renders some objects and copy them to the next draw call that renders different objects. So far I have tried the blit commander way and I tried to manually copy the textures, but both ways seem to completely overwrite the current texture while not taking into account alpha information. I am doing this after my initial command encoder that binds the buffers. I noticed that the previous texture's alpha information is not processed so it overwrites the current layer with the _view.clearColor value. I confirmed that both layers get presented as one layer is shown the majority of the time while the other layer flashes every now and then.

Layer 1 completely overwrites layer 0 so all I see if layer 1 instead of the two layers being combined, the green is the view's clearColor and seems to be part of the texture which I think is the problem:

Layer 1:

Layer 0:

The blit commander way, my data is split into layers and if the first layer is getting rendered in the batch then that one does not get copied over since it starts from the top to render the layers in the correct order on top of each other:


    if(previousDrawable && currentDrawable && previousTexture != currentDrawable.texture){

        [blitCommandEncoder copyFromTexture:previousTexture toTexture:currentDrawable.texture];
    }

    [blitCommandEncoder endEncoding];
    if(currentDrawable && layerId > 0){

        self.previousDrawable = currentDrawable;

        self.previousTexture = currentDrawable.texture;

    }else{

        self.previousDrawable = nil;

    }

The manual texture copying way:

       if(previousDrawable && currentDrawable && previousTexture != currentDrawable.texture){

       int textureSize = currentDrawable.texture.width * currentDrawable.texture.height * 4;

        unsigned char* previousTextureData = new unsigned char[textureSize];

        unsigned char* currentTextureData = new unsigned char[textureSize];



        [previousDrawable.texture getBytes:previousTextureData bytesPerRow:previousDrawable.texture.width * 4 fromRegion:MTLRegionMake2D(0, 0, previousDrawable.texture.width, previousDrawable.texture.height) mipmapLevel:0];

        [currentDrawable.texture getBytes:currentTextureData bytesPerRow:currentDrawable.texture.width * 4 fromRegion:MTLRegionMake2D(0, 0, currentDrawable.texture.width, currentDrawable.texture.height) mipmapLevel:0];



        for(int i = 0; i < textureSize; i+=4){

            if((int)previousTextureData[i + 3] > 0)
            {

                currentTextureData[i] = previousTextureData[i];

                currentTextureData[i + 1] = previousTextureData[i + 1];

                currentTextureData[i + 2] = previousTextureData[i + 2];

                currentTextureData[i + 3] = previousTextureData[i + 3];

            }
        }


        [currentDrawable.texture replaceRegion:MTLRegionMake2D(0, 0, currentDrawable.texture.width, currentDrawable.texture.height) mipmapLevel:0 withBytes:currentTextureData bytesPerRow:currentDrawable.texture.width * 4];

        delete[] previousTextureData;

        delete[] currentTextureData;
     }

    if(currentDrawable && layerId > 0){

        self.previousDrawable = currentDrawable;

        self.previousTexture = currentDrawable.texture;

    }else{

        self.previousDrawable = nil;

    }
Answered by jamarp in 725226022

After some realization about how the MTKView clears the buffer, I changed my system around to only contain one vertex buffer and one index buffer with quads to be sent to the GPU.

Accepted Answer

After some realization about how the MTKView clears the buffer, I changed my system around to only contain one vertex buffer and one index buffer with quads to be sent to the GPU.

Copying Metal Texture Of Previous Drawable to Current Drawable With Alpha Information
 
 
Q