Files
UnrealEngine/Engine/Source/ThirdParty/MaterialX/Deploy/MaterialX-1.38.10/include/MaterialXRenderMsl/MetalFramebuffer.h
2025-05-18 13:04:45 +08:00

135 lines
3.9 KiB
Objective-C

//
// Copyright Contributors to the MaterialX Project
// SPDX-License-Identifier: Apache-2.0
//
#ifndef MATERIALX_METALFRAMEBUFFER_H
#define MATERIALX_METALFRAMEBUFFER_H
/// @file
/// Metal framebuffer handling
#include <MaterialXRenderMsl/Export.h>
#include <MaterialXRender/ImageHandler.h>
#import <Metal/Metal.h>
MATERIALX_NAMESPACE_BEGIN
class MetalFramebuffer;
/// Shared pointer to a MetalFramebuffer
using MetalFramebufferPtr = std::shared_ptr<MetalFramebuffer>;
/// @class MetalFramebuffer
/// Wrapper for an Metal framebuffer
class MX_RENDERMSL_API MetalFramebuffer
{
public:
/// Create a new framebuffer
static MetalFramebufferPtr create(id<MTLDevice> device,
unsigned int width, unsigned int height,
unsigned int channelCount,
Image::BaseType baseType,
id<MTLTexture> colorTexture = nil,
bool encodeSrgb = false,
MTLPixelFormat pixelFormat = MTLPixelFormatInvalid);
/// Destructor
virtual ~MetalFramebuffer();
/// Resize the framebuffer
void resize(unsigned int width, unsigned int height, bool forceRecreate = false,
MTLPixelFormat pixelFormat = MTLPixelFormatInvalid,
id<MTLTexture> extColorTexture = nil);
/// Set the encode sRGB flag, which controls whether values written
/// to the framebuffer are encoded to the sRGB color space.
void setEncodeSrgb(bool encode)
{
if(encode != _encodeSrgb)
{
_encodeSrgb = encode;
resize(_width, _height, true);
}
}
/// Return the encode sRGB flag.
bool getEncodeSrgb()
{
return _encodeSrgb;
}
/// Return the framebuffer width
unsigned int getWidth() const { return _width; }
/// Return the framebuffer height
unsigned int getHeight() const { return _height; }
/// Bind the framebuffer for rendering.
void bind(MTLRenderPassDescriptor* renderpassDesc);
/// Unbind the frame buffer after rendering.
void unbind();
/// Return our color texture handle.
id<MTLTexture> getColorTexture() const
{
return _colorTexture;
}
void setColorTexture(id<MTLTexture> newColorTexture)
{
auto sameDim = [](id<MTLTexture> tex0, id<MTLTexture> tex1) -> bool
{
return [tex0 width] == [tex1 width] &&
[tex0 height] == [tex1 height];
};
if((!_colorTextureOwned || sameDim(_colorTexture, newColorTexture)) &&
sameDim(newColorTexture, _depthTexture))
{
if(_colorTextureOwned)
[_colorTexture release];
_colorTexture = newColorTexture;
}
}
/// Return our depth texture handle.
id<MTLTexture> getDepthTexture() const
{
return _depthTexture;
}
/// Return the color data of this framebuffer as an image.
/// If an input image is provided, it will be used to store the color data;
/// otherwise a new image of the required format will be created.
ImagePtr getColorImage(id<MTLCommandQueue> cmdQueue = nil, ImagePtr image = nullptr);
protected:
MetalFramebuffer(id<MTLDevice> device,
unsigned int width, unsigned int height,
unsigned int channelCount,
Image::BaseType baseType,
id<MTLTexture> colorTexture = nil,
bool encodeSrgb = false,
MTLPixelFormat pixelFormat = MTLPixelFormatInvalid);
protected:
unsigned int _width;
unsigned int _height;
unsigned int _channelCount;
Image::BaseType _baseType;
bool _encodeSrgb;
id<MTLDevice> _device = nil;
id<MTLTexture> _colorTexture = nil;
id<MTLTexture> _depthTexture = nil;
bool _colorTextureOwned = false;
};
MATERIALX_NAMESPACE_END
#endif