// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
#pragma once
#if COMPILE_WITH_TEXTURE_TOOL
#include "Engine/Render2D/SpriteAtlas.h"
#include "Engine/Graphics/Textures/Types.h"
#include "Engine/Graphics/Textures/GPUTexture.h"
#include "Engine/Core/ISerializable.h"
class JsonWriter;
///
/// Textures importing, processing and exporting utilities.
///
class FLAXENGINE_API TextureTool
{
public:
///
/// Importing texture options
///
struct Options : public ISerializable
{
///
/// Texture format type
///
TextureFormatType Type;
///
/// True if texture should be imported as a texture atlas resource
///
bool IsAtlas;
///
/// True if disable dynamic texture streaming
///
bool NeverStream;
///
/// Enables/disables texture data compression.
///
bool Compress;
///
/// True if texture channels have independent data
///
bool IndependentChannels;
///
/// True if use sRGB format for texture data. Recommended for color maps and diffuse color textures.
///
bool sRGB;
///
/// True if generate mip maps chain for the texture.
///
bool GenerateMipMaps;
///
/// True if flip Y coordinate of the texture.
///
bool FlipY;
///
/// True if resize the texture.
///
bool Resize;
///
/// True if preserve alpha coverage in generated mips for alpha test reference. Scales mipmap alpha values to preserve alpha coverage based on an alpha test reference value.
///
bool PreserveAlphaCoverage;
///
/// The reference value for the alpha coverage preserving.
///
float PreserveAlphaCoverageReference;
///
/// Texture group for streaming (negative if unused). See Streaming Settings.
///
int32 TextureGroup;
///
/// The import texture scale.
///
float Scale;
///
/// Custom texture size X, use only if Resize texture flag is set.
///
int32 SizeX;
///
/// Custom texture size Y, use only if Resize texture flag is set.
///
int32 SizeY;
///
/// Maximum size of the texture (for both width and height).
/// Higher resolution textures will be resized during importing process.
///
int32 MaxSize;
///
/// Function used for fast importing textures used by internal parts of the engine
///
Function InternalLoad;
///
/// The sprites for the sprite sheet import mode.
///
Array Sprites;
public:
///
/// Init
///
Options();
///
/// Gets string that contains information about options
///
/// String
String ToString() const;
public:
// [ISerializable]
void Serialize(SerializeStream& stream, const void* otherObj) override;
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
};
public:
#if USE_EDITOR
///
/// Checks whenever the given texture file contains alpha channel data with values different than solid fill of 1 (non fully opaque).
///
/// The file path.
/// True if has alpha channel, otherwise false.
static bool HasAlpha(const StringView& path);
#endif
///
/// Imports the texture.
///
/// The file path.
/// The output data.
/// True if fails, otherwise false.
static bool ImportTexture(const StringView& path, TextureData& textureData);
///
/// Imports the texture.
///
/// The file path.
/// The output data.
/// The import options.
/// The error message container.
/// True if fails, otherwise false.
static bool ImportTexture(const StringView& path, TextureData& textureData, Options options, String& errorMsg);
///
/// Exports the texture.
///
/// The output file path.
/// The output data.
/// True if fails, otherwise false.
static bool ExportTexture(const StringView& path, const TextureData& textureData);
///
/// Converts the specified source texture data into an another format.
///
/// The destination data.
/// The source data.
/// The destination data format. Must be other than source data type.
/// True if fails, otherwise false.
static bool Convert(TextureData& dst, const TextureData& src, const PixelFormat dstFormat);
///
/// Resizes the specified source texture data into an another dimensions.
///
/// The destination data.
/// The source data.
/// The destination data width.
/// The destination data height.
/// True if fails, otherwise false.
static bool Resize(TextureData& dst, const TextureData& src, int32 dstWidth, int32 dstHeight);
public:
typedef Color (*ReadPixel)(const void*);
typedef void (*WritePixel)(const void*, const Color&);
struct PixelFormatSampler
{
PixelFormat Format;
int32 PixelSize;
ReadPixel Sample;
WritePixel Store;
};
///
/// Determines whether this tool can sample the specified format to read texture samples and returns the sampler object.
///
/// The format.
/// The pointer to the sampler object or null if cannot sample the given format.
static const PixelFormatSampler* GetSampler(PixelFormat format);
///
/// Stores the color into the specified texture data (uses no interpolation).
///
///
/// Use GetSampler for the texture sampler.
///
/// The texture data sampler.
/// The X texture coordinates (normalized to range 0-width).
/// The Y texture coordinates (normalized to range 0-height).
/// The data pointer for the texture slice (1D or 2D image).
/// The row pitch (in bytes). The offset between each image rows.
/// The color to store (linear).
static void Store(const PixelFormatSampler* sampler, int32 x, int32 y, const void* data, int32 rowPitch, const Color& color);
///
/// Samples the specified texture data (uses no interpolation).
///
///
/// Use GetSampler for the texture sampler.
///
/// The texture data sampler.
/// The texture coordinates (normalized to range 0-1).
/// The data pointer for the texture slice (1D or 2D image).
/// The size of the input texture (in pixels).
/// The row pitch (in bytes). The offset between each image rows.
/// The sampled color (linear).
static Color SamplePoint(const PixelFormatSampler* sampler, const Float2& uv, const void* data, const Int2& size, int32 rowPitch);
///
/// Samples the specified texture data (uses no interpolation).
///
///
/// Use GetSampler for the texture sampler.
///
/// The texture data sampler.
/// The X texture coordinates (normalized to range 0-width).
/// The Y texture coordinates (normalized to range 0-height).
/// The data pointer for the texture slice (1D or 2D image).
/// The row pitch (in bytes). The offset between each image rows.
/// The sampled color (linear).
static Color SamplePoint(const PixelFormatSampler* sampler, int32 x, int32 y, const void* data, int32 rowPitch);
///
/// Samples the specified texture data (uses linear interpolation).
///
///
/// Use GetSampler for the texture sampler.
///
/// The texture data sampler.
/// The texture coordinates (normalized to range 0-1).
/// The data pointer for the texture slice (1D or 2D image).
/// The size of the input texture (in pixels).
/// The row pitch (in bytes). The offset between each image rows.
/// The sampled color (linear).
static Color SampleLinear(const PixelFormatSampler* sampler, const Float2& uv, const void* data, const Int2& size, int32 rowPitch);
private:
enum class ImageType
{
DDS,
TGA,
PNG,
BMP,
GIF,
TIFF,
JPEG,
HDR,
RAW,
Internal,
};
static bool GetImageType(const StringView& path, ImageType& type);
#if COMPILE_WITH_DIRECTXTEX
static bool ExportTextureDirectXTex(ImageType type, const StringView& path, const TextureData& textureData);
static bool ImportTextureDirectXTex(ImageType type, const StringView& path, TextureData& textureData, bool& hasAlpha);
static bool ImportTextureDirectXTex(ImageType type, const StringView& path, TextureData& textureData, const Options& options, String& errorMsg, bool& hasAlpha);
static bool ConvertDirectXTex(TextureData& dst, const TextureData& src, const PixelFormat dstFormat);
static bool ResizeDirectXTex(TextureData& dst, const TextureData& src, int32 dstWidth, int32 dstHeight);
#endif
#if COMPILE_WITH_STB
static bool ExportTextureStb(ImageType type, const StringView& path, const TextureData& textureData);
static bool ImportTextureStb(ImageType type, const StringView& path, TextureData& textureData, bool& hasAlpha);
static bool ImportTextureStb(ImageType type, const StringView& path, TextureData& textureData, const Options& options, String& errorMsg, bool& hasAlpha);
static bool ConvertStb(TextureData& dst, const TextureData& src, const PixelFormat dstFormat);
static bool ResizeStb(PixelFormat format, TextureMipData& dstMip, const TextureMipData& srcMip, int32 dstMipWidth, int32 dstMipHeight);
static bool ResizeStb(TextureData& dst, const TextureData& src, int32 dstWidth, int32 dstHeight);
#endif
};
#endif