Skip to content

Commit

Permalink
feat(texture): add TextureBuilder class
Browse files Browse the repository at this point in the history
  • Loading branch information
lmichaelis committed Feb 24, 2024
1 parent b533e1b commit 202e9b8
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 0 deletions.
29 changes: 29 additions & 0 deletions include/zenkit/Texture.hh
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright © 2021-2023 GothicKit Contributors.
// SPDX-License-Identifier: MIT
#pragma once
#include "zenkit/Error.hh"
#include "zenkit/Library.hh"

#include <array>
Expand Down Expand Up @@ -37,6 +38,18 @@ namespace zenkit {
DXT5 = 0xE, ///< \brief DXT5 compression texture format
};

class InvalidMipmapSize final : public Error {
public:
explicit InvalidMipmapSize(uint32_t expect, size_t got)
: Error("Invalid texture mipmap size. Expected " + std::to_string(expect) + ", got " +
std::to_string(got)) {}
};

class UnsupportedFormatError final : public Error {
public:
explicit UnsupportedFormatError(std::string msg) : Error("Format not supported: " + msg) {}
};

/// \brief Simple ARGB quad.
struct ColorARGB {
std::uint8_t a, r, g, b;
Expand Down Expand Up @@ -134,5 +147,21 @@ namespace zenkit {

// Quirk: largest mipmap (level 0) stored at the end of the vector
std::vector<std::vector<std::uint8_t>> _m_textures;

friend class TextureBuilder;
};

class TextureBuilder {
public:
TextureBuilder(uint32_t width, uint32_t height);

TextureBuilder& add_mipmap(std::vector<uint8_t> bytes, TextureFormat format);

Texture build(TextureFormat format);

private:
std::uint32_t _m_width;
std::uint32_t _m_height;
std::vector<std::pair<std::vector<uint8_t>, TextureFormat>> _m_mipmaps;
};
} // namespace zenkit
34 changes: 34 additions & 0 deletions src/Texture.cc
Original file line number Diff line number Diff line change
Expand Up @@ -352,4 +352,38 @@ namespace zenkit {
w->write(m.data(), m.size());
}
}

TextureBuilder::TextureBuilder(uint32_t width, uint32_t height) : _m_width(width), _m_height(height) {}

TextureBuilder& TextureBuilder::add_mipmap(std::vector<uint8_t> bytes, TextureFormat format) {
auto expected_size = _ztex_mipmap_size(format, _m_width, _m_height, _m_mipmaps.size());
if (bytes.size() != expected_size) {
throw InvalidMipmapSize {expected_size, bytes.size()};
}

_m_mipmaps.emplace_back(std::move(bytes), format);
return *this;
}

Texture TextureBuilder::build(TextureFormat format) {
if (format == TextureFormat::P8) {
throw UnsupportedFormatError {"P8"};
}

Texture tex;
tex._m_format = format;
tex._m_width = _m_width;
tex._m_height = _m_height;
tex._m_reference_width = _m_width;
tex._m_reference_height = _m_height;
tex._m_mipmap_count = _m_mipmaps.size();
tex._m_average_color = {}; // FIXME(lmichaelis): Calculate the average color

for (auto i = 0u; i < _m_mipmaps.size(); ++i) {
auto& [data, fmt] = _m_mipmaps[i];
tex._m_textures.push_back(_ztex_convert_format(data.data(), _m_width >> i, _m_height >> i, fmt, format));
}

return tex;
}
} // namespace zenkit

0 comments on commit 202e9b8

Please sign in to comment.