Skip to content

Commit

Permalink
Began remove T.init() and switching to T::create()
Browse files Browse the repository at this point in the history
  • Loading branch information
WillisMedwell committed Mar 8, 2024
1 parent 095c3f2 commit 69746a3
Show file tree
Hide file tree
Showing 10 changed files with 321 additions and 45 deletions.
3 changes: 2 additions & 1 deletion code/.clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ CheckOptions:
- { key: readability-identifier-naming.VariableCase, value: lower_case }
- { key: readability-identifier-naming.FunctionCase, value: lower_case }
- { key: readability-identifier-naming.StructCase, value: CamelCase }
- { key: readability-identifier-naming.MemberVariableCase, value: snake_case }
- { key: readability-identifier-naming.ConstantMemberCase, value: snake_case }
- { key: readability-identifier-naming.ClassCase, value: CamelCase }
- { key: readability-identifier-naming.MethodCase, value: lower_case }
- { key: readability-identifier-naming.PrivateMemberPrefix, value: _ }
- { key: readability-identifier-naming.StaticMemberPrefix, value: _ }
- { key: readability-identifier-naming.ConstantCase, value: UPPER_CASE }
- { key: readability-identifier-naming.LocalConstantCase, value: lower_case }
- { key: readability-identifier-naming.GlobalConstantCase, value: UPPER_CASE }
- { key: readability-identifier-naming.EnumConstantCase, value: lower_case }
Expand Down
23 changes: 20 additions & 3 deletions code/Demos/src/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,8 @@ struct IsoData {

Renderer::ResourceManager resource_manager;
Renderer::InstanceRenderer instance_renderer;

Cameras::StationaryPerspective camera { glm::vec3(0, 1, -1), glm::normalize(glm::vec3(0, -0.25f, 0.5f)) };
};
struct IsoLogic {
void init(AppRenderer& renderer, Core::AudioManager& audio, IsoData& data) {
Expand All @@ -428,9 +430,6 @@ struct IsoLogic {
data.spinning.angle = 0;
data.spinning.rotations_per_second = 1;

data.source_handle = audio.play_sound(data.sound_buffer).on_error(print_then_quit).value();
data.start_time = std::chrono::high_resolution_clock::now();

auto model_data = std::move(
Utily::FileReader::load_entire_file("assets/teapot.obj")
.on_error(print_then_quit)
Expand All @@ -449,6 +448,9 @@ struct IsoLogic {
.on_error(print_then_quit);

data.instance_renderer.init(data.resource_manager, model, image);

data.source_handle = audio.play_sound(data.sound_buffer, { 5, 0, 0 }).on_error(print_then_quit).value();
data.start_time = std::chrono::high_resolution_clock::now();
}

void update(float dt, const Core::InputManager& input, Core::AudioManager& audio, AppState& state, IsoData& data) {
Expand All @@ -470,12 +472,27 @@ struct IsoLogic {
lp.dir = { 0, 0, 1 };
lp.vel = { 0, 0, 0 };
audio.set_listener_properties(lp);

auto t = Components::Transform {};
t.position = glm::vec3(0, -1, 1);
t.scale = glm::vec3(0.5f);

auto model = t.calc_transform_mat();
data.instance_renderer.push_instance(model);

t.position = glm::vec3(0, -1, 2);
model = t.calc_transform_mat();
data.instance_renderer.push_instance(model);
}

void draw(AppRenderer& renderer, IsoData& data) {
renderer.screen_frame_buffer.bind();
renderer.screen_frame_buffer.clear(data.background_colour);
renderer.screen_frame_buffer.resize(renderer.window_width, renderer.window_height);

auto v = data.camera.view_matrix();
auto p = data.camera.projection_matrix(renderer.window_width, renderer.window_height);
data.instance_renderer.draw_instances(data.resource_manager, v, p);
}
void stop(IsoData& data) {
}
Expand Down
45 changes: 44 additions & 1 deletion code/Engine/include/Media/Font.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ namespace Media {
}
constexpr static auto IS_CHAR_DRAWABLE = gen_is_char_drawable_table();
}
}

#if 0

namespace Media {

class Font;

Expand Down Expand Up @@ -86,4 +91,42 @@ namespace Media {
namespace FontMeshGenerator {
auto generate_static_mesh(std::string_view str, const float char_height, const glm::vec2 bottom_left_pos, const FontAtlas& atlas) -> std::tuple<std::array<Model::Vertex2D, 400>, std::array<Model::Index, 600>>;
}
}
}

#else

namespace Media {

class FontAtlas
{
public:
/// @brief Load .ttf font from disk. Generate a font-atlas image. Can fail.
static auto create(std::filesystem::path path) noexcept -> Utily::Result<FontAtlas, Utily::Error>;

FontAtlas(FontAtlas&& other)
: _m(std::move(other.m)) { }

auto uv_for(char c) const noexcept -> glm::vec2;

private:
struct M {
const Media::Image atlas_image;
const glm::vec2 atlas_layout;
const glm::vec2 glyph_dimensions;
} _m;

explicit FontAtlas(M m)
: _m(std::move(m)) { }

constexpr static auto PRINTABLE_CHARS = []() {
constexpr char first_printable = char(32);
constexpr char last_printable = char(127);
constexpr size_t n = last_printable - first_printable;
std::array<char, n> chars {};
std::ranges::copy(std::views::iota(first_printable, last_printable), chars.begin());
return chars;
}();
};
}

#endif
38 changes: 38 additions & 0 deletions code/Engine/include/Media/Image.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <glm/vec2.hpp>

#if 0
namespace Media {

enum class ColourFormat : uint32_t {
Expand Down Expand Up @@ -60,4 +61,41 @@ namespace Media {
uint32_t _width { 0 }, _height { 0 };
std::optional<Core::Fence> _fence;
};
}
#endif

namespace Media {
class Image
{
public:
enum class InternalFormat {
undefined = 0,
greyscale,
rgba
};

/// @brief Load png image from disk and decode it. Can fail.
[[nodiscard]] static auto create(std::filesystem::path path)
-> Utily::Result<Image, Utily::Error>;
/// @brief Take decoded-raw image data and copy it. Can fail.
[[nodiscard]] static auto create(std::span<uint8_t> raw_bytes, glm::uvec2 dimensions, InternalFormat format)
-> Utily::Result<Image, Utily::Error>;

Image(Image&& other);

[[nodiscard]] inline auto raw_bytes() const noexcept { return std::span { _m.data.get(), _m.data_size_bytes }; }
[[nodsicard]] inline auto dimensions() const noexcept { return _m.dimensions; }
[[nodiscard]] auto opengl_format() const -> uint32_t;

private:
struct M {
std::unique_ptr<uint8_t[]> data = {};
size_t data_size_bytes = 0;
glm::uvec2 dimensions = { 0, 0 };
InternalFormat format = InternalFormat::undefined;
} _m;

explicit Image(M m)
: _m(std::move(m)) { }
};
}
2 changes: 1 addition & 1 deletion code/Engine/include/Renderer/InstanceRenderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Renderer {
void stop(ResourceManager& resource_manager);

void push_instance(const glm::mat4& instance_transformation);
void draw_instances(ResourceManager& resource_manager, glm::vec2 screen_dimensions);
void draw_instances(ResourceManager& resource_manager, const glm::mat4& projection, const glm::mat4& view);
private:
Renderer::ResourceHandle<Core::Shader> _s;
Renderer::ResourceHandle<Core::Texture> _t;
Expand Down
79 changes: 79 additions & 0 deletions code/Engine/src/Media/Font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ struct FreeType {

static FreeType free_type {};

#if 0
namespace Media {
auto FontAtlas::operator=(FontAtlas&& other) noexcept -> FontAtlas& {
this->image = std::move(other.image);
Expand Down Expand Up @@ -301,4 +302,82 @@ namespace Media {
}
return std::tuple { vertices, indices };
}
}

#endif

namespace Media {
auto FontAtlas::create(std::filesystem::path path, uint32_t chat_height_px) noexcept -> Utily::Result<FontAtlas, Utily::Error> {
// 1. Load ttf file from disk.
// 2. Initalise the freetype font face
// 3. Generate and cache the bitmap for each glyph.
// 4. Determine the most compact atlas dimensions.

// 1.
auto file_load_result = Utily::FileReader::load_entire_file(path);
if (file_load_result.has_error()) {
return file_load_result.error();
}
const auto& encoded_ttf = file_load_result.value();

// 2.
FT_Face ft_face = nullptr;
if (auto error = FT_New_Memory_Face(free_type.library, encoded_ttf.data(), encoded_ttf.size(), 0, &ft_face); error) {
return Utily::Error { FT_Error_String(error) };
}
if (auto error = FT_Set_Pixel_Sizes(ft_face, 0, char_height_px); error) {
return Utily::Error { FT_Error_String(error) };
}

// 3.
struct GlyphDimensions {
glm::uvec2 bitmap_dimensions = { 0, 0 };
uint32_t spanline = 0;
uint32_t left_padding = 0;
};
struct CachedGlyph {
char c;
std::vector<uint8_t> bitmap;
GlyphDimensions dimensions;
};
auto create_cached_glyph = [&](char c) {
auto glyph_index = FT_Get_Char_Index(ft_face, static_cast<std::uint32_t>(c));
FT_Load_Glyph(ft_face, glyph_index, FT_LOAD_DEFAULT);
FT_Render_Glyph(ft_face->glyph, FT_Render_Mode::FT_RENDER_MODE_NORMAL);
auto glyph_bitmap = std::span {
ft_face->glyph->bitmap.buffer,
ft_face->glyph->bitmap.width * ft_face->glyph->bitmap.rows
};
return CachedGlyph {
.c = c,
.bitmap = { glyph_bitmap.begin(), glyph_bitmap.end() },
.dimensions = GlyphDimensions {
.bitmap_dimensions = { ft_face->glyph->bitmap.width, ft_face->glyph->bitmap.rows },
.spanline = { ft_face->glyph->bitmap_top },
.left_padding = { ft_face->glyph->bitmap_left },
}
};
};
std::array<CachedGlyph, PRINTABLE_CHARS.size()> cached_glyphs;
std::transform(PRINTABLE_CHARS.begin(), PRINTABLE_CHARS.end(), cached_glyphs.begin(), create_cached_glyph);

// 4.
auto take_max_dimensions = [](AtlasGlyphDimensions&& agg, const CachedGlyph& cg) {
return AtlasGlyphDimensions {


// .bitmap_dimensions = {
// std::max(agg.bitmap_dimensions.x, cg.bitmap_dimensions),
// std::max(agg.)
// },
//.spanline = std::max(cg.spanline, agg.spanline), .left_padding = std::max(cg.left_padding, agg.left_padding),
};
};
const auto atlas_glyph_dimensions = std::reduce(cached_glyphs.begin(), cached_glyphs.end(), AtlasGlyphDimensions {}, take_max_dimensions);

return FontAtlas(M { .atlas_image = std::move(image), .atlas_layout = {}, .glyph_dimensions = {} });
}
auto FontAtlas::uv_for(char c) const noexcept -> glm::vec2 {
return {};
}
}
Loading

0 comments on commit 69746a3

Please sign in to comment.