Files
UnrealEngine/Engine/Source/ThirdParty/MaterialX/MaterialX-1.38.10/source/MaterialXRender/ImageHandler.h
2025-05-18 13:04:45 +08:00

282 lines
9.3 KiB
C++

//
// Copyright Contributors to the MaterialX Project
// SPDX-License-Identifier: Apache-2.0
//
#ifndef MATERIALX_IMAGEHANDLER_H
#define MATERIALX_IMAGEHANDLER_H
/// @file
/// Image handler interfaces
#include <MaterialXRender/Export.h>
#include <MaterialXRender/Image.h>
#include <MaterialXFormat/File.h>
#include <MaterialXCore/Document.h>
MATERIALX_NAMESPACE_BEGIN
extern MX_RENDER_API const string IMAGE_PROPERTY_SEPARATOR;
extern MX_RENDER_API const string UADDRESS_MODE_SUFFIX;
extern MX_RENDER_API const string VADDRESS_MODE_SUFFIX;
extern MX_RENDER_API const string FILTER_TYPE_SUFFIX;
extern MX_RENDER_API const string DEFAULT_COLOR_SUFFIX;
class ImageHandler;
class ImageLoader;
class VariableBlock;
/// Shared pointer to an ImageHandler
using ImageHandlerPtr = std::shared_ptr<ImageHandler>;
/// Shared pointer to an ImageLoader
using ImageLoaderPtr = std::shared_ptr<ImageLoader>;
/// Map from strings to vectors of image loaders
using ImageLoaderMap = std::unordered_map<string, std::vector<ImageLoaderPtr>>;
/// @class ImageSamplingProperties
/// Interface to describe sampling properties for images.
class MX_RENDER_API ImageSamplingProperties
{
public:
/// Set the properties based on data in a uniform block.
/// @param fileNameUniform Name of the file name uniform. Used to find
/// corresponding sampler data in the uniform block
/// @param uniformBlock Block containing sampler uniforms
void setProperties(const string& fileNameUniform,
const VariableBlock& uniformBlock);
bool operator==(const ImageSamplingProperties& r) const;
/// Address mode options. Matches enumerations allowed for image address
/// modes, except UNSPECIFIED which indicates no explicit mode was defined.
enum class AddressMode : int
{
UNSPECIFIED = -1,
CONSTANT = 0,
CLAMP = 1,
PERIODIC = 2,
MIRROR = 3
};
/// Address mode in U
AddressMode uaddressMode = AddressMode::UNSPECIFIED;
/// Address mode in V
AddressMode vaddressMode = AddressMode::UNSPECIFIED;
/// Filter type options. Matches enumerations allowed for image filter
/// types, except UNSPECIFIED which indicates no explicit type was defined.
enum class FilterType : int
{
UNSPECIFIED = -1,
CLOSEST = 0,
LINEAR = 1,
CUBIC = 2
};
/// Filter type
FilterType filterType = FilterType::UNSPECIFIED;
/// Enable mipmaps
bool enableMipmaps = true;
/// Default color. Corresponds to the "default" value on the image
/// node definition.
Color4 defaultColor = { 0.0f, 0.0f, 0.0f, 1.0f };
};
/// @struct ImageSamplingKeyHasher
/// Class used for hashing ImageSamplingProperties in an unordered_map
struct MX_RENDER_API ImageSamplingKeyHasher
{
size_t operator()(const ImageSamplingProperties& k) const
{
return (size_t) k.enableMipmaps + // 1 bit
(((size_t) k.filterType & 3) << 1) + // 2 bit
((((size_t) k.uaddressMode + 1) & 7) << 3) + // 3 bit
((((size_t) k.vaddressMode + 1) & 7) << 6) + // 3 bit
((((size_t) k.defaultColor[0] + 1)) << 9) ;
}
};
/// @class ImageLoader
/// Abstract base class for file-system image loaders
class MX_RENDER_API ImageLoader
{
public:
ImageLoader()
{
}
virtual ~ImageLoader() { }
/// Standard image file extensions
static const string BMP_EXTENSION;
static const string EXR_EXTENSION;
static const string GIF_EXTENSION;
static const string HDR_EXTENSION;
static const string JPG_EXTENSION;
static const string JPEG_EXTENSION;
static const string PIC_EXTENSION;
static const string PNG_EXTENSION;
static const string PSD_EXTENSION;
static const string TGA_EXTENSION;
static const string TIF_EXTENSION;
static const string TIFF_EXTENSION;
static const string TXT_EXTENSION;
static const string TX_EXTENSION;
static const string TXR_EXTENSION;
/// Returns a list of supported extensions
/// @return List of support extensions
const StringSet& supportedExtensions() const
{
return _extensions;
}
/// Save an image to the file system. This method must be implemented by derived classes.
/// @param filePath File path to be written
/// @param image The image to be saved
/// @param verticalFlip Whether the image should be flipped in Y during save
/// @return if save succeeded
virtual bool saveImage(const FilePath& filePath,
ConstImagePtr image,
bool verticalFlip = false);
/// Load an image from the file system. This method must be implemented by derived classes.
/// @param filePath The requested image file path.
/// @return On success, a shared pointer to the loaded image; otherwise an empty shared pointer.
virtual ImagePtr loadImage(const FilePath& filePath);
protected:
// List of supported string extensions
StringSet _extensions;
};
/// @class ImageHandler
/// Base image handler class. Keeps track of images which are loaded from
/// disk via supplied ImageLoader. Derived classes are responsible for
/// determinining how to perform the logic for "binding" of these resources
/// for a given target (such as a given shading language).
class MX_RENDER_API ImageHandler
{
public:
static ImageHandlerPtr create(ImageLoaderPtr imageLoader)
{
return ImageHandlerPtr(new ImageHandler(imageLoader));
}
virtual ~ImageHandler() { }
/// Add another image loader to the handler, which will be invoked if
/// existing loaders cannot load a given image.
void addLoader(ImageLoaderPtr loader);
/// Get a list of extensions supported by the handler.
StringSet supportedExtensions();
/// Save image to disk. This method must be implemented by derived classes.
/// The first image loader which supports the file name extension will be used.
/// @param filePath File path to be written
/// @param image The image to be saved
/// @param verticalFlip Whether the image should be flipped in Y during save
/// @return if save succeeded
bool saveImage(const FilePath& filePath, ConstImagePtr image, bool verticalFlip = false);
/// Acquire an image from the cache or file system. If the image is not
/// found in the cache, then each image loader will be applied in turn.
/// If the image cannot be found by any loader, then a uniform image of the
/// given default color will be returned.
/// @param filePath File path of the image.
/// @param defaultColor Default color to use as a fallback for missing images.
/// @return On success, a shared pointer to the acquired image.
ImagePtr acquireImage(const FilePath& filePath, const Color4& defaultColor = Color4(0.0f));
/// Bind an image for rendering.
/// @param image The image to bind.
/// @param samplingProperties Sampling properties for the image.
virtual bool bindImage(ImagePtr image, const ImageSamplingProperties& samplingProperties);
/// Unbind an image, making it no longer active for rendering.
/// @param image The image to unbind.
virtual bool unbindImage(ImagePtr image);
/// Unbind all images that are currently stored in the cache.
void unbindImages();
/// Set the search path to be used for finding images on the file system.
void setSearchPath(const FileSearchPath& path)
{
_searchPath = path;
}
/// Return the image search path.
const FileSearchPath& getSearchPath() const
{
return _searchPath;
}
/// Set the filename resolver for images.
void setFilenameResolver(StringResolverPtr resolver)
{
_resolver = resolver;
}
/// Return the filename resolver for images.
StringResolverPtr getFilenameResolver() const
{
return _resolver;
}
/// Create rendering resources for the given image.
virtual bool createRenderResources(ImagePtr image, bool generateMipMaps, bool useAsRenderTarget = false);
/// Release rendering resources for the given image, or for all cached images
/// if no image pointer is specified.
virtual void releaseRenderResources(ImagePtr image = nullptr);
/// Clear the contents of the image cache, first releasing any render
/// resources associated with cached images.
void clearImageCache()
{
releaseRenderResources();
_imageCache.clear();
}
/// Return a fallback image with zeroes in all channels.
ImagePtr getZeroImage() const
{
return _zeroImage;
}
/// Acquire all images referenced by the given document, and return the
/// images in a vector.
ImageVec getReferencedImages(ConstDocumentPtr doc);
protected:
// Protected constructor.
ImageHandler(ImageLoaderPtr imageLoader);
// Load an image from the file system.
ImagePtr loadImage(const FilePath& filePath);
// Add an image to the cache.
void cacheImage(const string& filePath, ImagePtr image);
// Return the cached image, if found; otherwise return an empty
// shared pointer.
ImagePtr getCachedImage(const FilePath& filePath);
protected:
ImageLoaderMap _imageLoaders;
ImageMap _imageCache;
FileSearchPath _searchPath;
StringResolverPtr _resolver;
ImagePtr _zeroImage;
};
MATERIALX_NAMESPACE_END
#endif