1
0
Fork 0
Univerxel/src/client/render/api/Images.hpp

122 lines
3.5 KiB
C++

#pragma once
#include "common.hpp"
#include <optional>
#include <vector>
namespace render {
/// Abstract raw image
class Image {
public:
virtual ~Image() { }
struct frame {
uint32_t height;
uint32_t width;
};
// NOTE: matches VkFormat
enum class Format {
/// DXT3 RGBA SRGB
BC2 = 136,
/// DXT5 RGBA SRGB
BC3 = 138,
// MAYBE: R8G8B8A8
// MAYBE: For HDR BC6H_SFLOAT = 144,
};
// NOTE: matches VkImageLayout
enum class Layout {
UNDEFINED = 0,
GENERAL = 1,
COLOR_ATTACHMENT = 2,
DEPTH_STENCIL_ATTACHMENT = 3,
DEPTH_STENCIL_READ_ONLY = 4,
SHADER_READ_ONLY = 5,
TRANSFER_SRC = 6,
TRANSFER_DST = 7,
PREINITIALIZED = 8,
DEPTH_READ_ONLY_STENCIL_ATTACHMENT = 1000117000,
DEPTH_ATTACHMENT_STENCIL_READ_ONLY = 1000117001,
DEPTH_ATTACHMENT = 1000241000,
DEPTH_READ_ONLY = 1000241001,
STENCIL_ATTACHMENT = 1000241002,
STENCIL_READ_ONLY = 1000241003
};
// NOTE: matches VkImageUsageFlags
enum class Usage {
TRANSFER_SRC = 0x00000001,
TRANSFER_DST = 0x00000002,
SAMPLED = 0x00000004,
STORAGE = 0x00000008,
COLOR_ATTACHMENT = 0x00000010,
DEPTH_STENCIL_ATTACHMENT = 0x00000020,
TRANSIENT_ATTACHMENT = 0x00000040,
INPUT_ATTACHMENT = 0x00000080,
};
friend inline Usage operator|(Usage a, Usage b) {
return static_cast<Usage>(static_cast<int>(a) | static_cast<int>(b));
}
//NOTE: matches VkImageAspectFlags
enum class Aspect {
COLOR = 0x00000001,
DEPTH = 0x00000002,
STENCIL = 0x00000004,
METADATA = 0x00000008
};
struct properties {
frame size;
uint32_t mipmapLevels;
Format format;
};
struct requirement: properties {
requirement(const properties& props, Layout layout, Usage usage, Aspect aspect,
int samples = 1, bool optimal = true): properties(props), layout(layout),
usage(usage), aspect(aspect), samples(samples), optimal(optimal)
{
assert(samples > 0 && (ceil(log2(n)) == floor(log2(n))) && "Samples must be pow2");
}
Layout layout;
Usage usage;
Aspect aspect;
//NOTE: matches VkSampleCountFlagBits
int samples;
bool optimal;
static requirement Texture(const properties &props) {
return requirement(props, Layout::SHADER_READ_ONLY, Usage::SAMPLED, Aspect::COLOR); }
};
static std::optional<properties> Read(const std::string&, std::vector<unsigned char>& data);
};
/// Const image (single texture2D) with sampler
class Texture: public Image {
public:
// NOTE: matches VkSamplerAddressMode
enum class Wrap {
REPEAT = 0,
MIRRORED_REPEAT = 1,
CLAMP_TO_EDGE = 2,
CLAMP_TO_BORDER = 3,
};
struct sampling {
bool magLinear = true;
bool minLinear = true;
Wrap wrap = Wrap::MIRRORED_REPEAT;
int anisotropy = 0;
bool mipmap = true;
};
/// Only supports dds files
/// DXT1(BC1) DXT3(BC2) DXT5(BC3)
static _FORCE_INLINE_ std::unique_ptr<Texture> LoadFromFile(const std::string &path, const sampling &props) {
assert(loadFunc != nullptr && "Uninitialized renderer");
return loadFunc(path, props);
}
protected:
static std::unique_ptr<Texture> (*loadFunc)(const std::string&, const sampling&);
};
}