diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5ccb838..b590688 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.25)
include(FetchContent)
-set(BLT_GRAPHICS_VERSION 1.0.3)
+set(BLT_GRAPHICS_VERSION 1.0.4)
set(BLT_GRAPHICS_TEST_VERSION 0.0.1)
project(BLT_WITH_GRAPHICS VERSION ${BLT_GRAPHICS_VERSION})
diff --git a/include/blt/gfx/font/font.h b/include/blt/gfx/font/font.h
index a480742..6924d39 100644
--- a/include/blt/gfx/font/font.h
+++ b/include/blt/gfx/font/font.h
@@ -16,8 +16,6 @@
* along with this program. If not, see .
*/
-#include "blt/std/types.h"
-
#ifndef BLT_WITH_GRAPHICS_FONT_H
#define BLT_WITH_GRAPHICS_FONT_H
@@ -27,6 +25,8 @@
#include
#include
#include
+#include "blt/std/types.h"
+#include
namespace blt::gfx::font
{
@@ -49,7 +49,7 @@ namespace blt::gfx::font
font_face_t& set_pixel_sizes(blt::u32 width, blt::u32 height);
- std::optional load_char(char c);
+ [[nodiscard]] std::optional load_char(FT_ULong c) const;
[[nodiscard]] FT_Face* get() const
{
@@ -64,9 +64,20 @@ namespace blt::gfx::font
struct font_file_t
{
- std::string_view path;
- blt::u32 character_min_index;
- blt::u32 character_max_index;
+ font_face_t font;
+ blt::u64 character_min_index;
+ blt::u64 character_max_index;
+
+ font_file_t(font_face_t font, u64 characterMinIndex, u64 characterMaxIndex);
+ };
+
+ struct glyph_t
+ {
+ blt::vec2ui size;
+ blt::vec2ui bearing;
+ blt::i64 advance;
+
+ glyph_t(const vec2ui& size, const vec2ui& bearing, blt::i64 advance);
};
}
diff --git a/include/blt/gfx/renderer/font_renderer.h b/include/blt/gfx/renderer/font_renderer.h
index 2d47725..7925615 100644
--- a/include/blt/gfx/renderer/font_renderer.h
+++ b/include/blt/gfx/renderer/font_renderer.h
@@ -20,16 +20,46 @@
#define BLT_WITH_GRAPHICS_FONT_RENDERER_H
#include
+#include
+#include
+#include
namespace blt::gfx
{
-
+ class font_texture_atlas : public texture_gl2D
+ {
+ public:
+ struct bounded_t
+ {
+ font::glyph_t glyph;
+ blt::vec2ui min;
+ blt::vec2ui max;
+ };
+
+ explicit font_texture_atlas(blt::i32 dimensions);
+
+ blt::u64 add_font(const font::font_file_t& file);
+
+ blt::u64 add_font(const font::font_file_t& file, blt::u64 start);
+
+ bounded_t& get_glyph(blt::u64 c)
+ { return glyphs.at(c); }
+
+ [[nodiscard]] const bounded_t& get_glyph(blt::u64 c) const
+ { return glyphs.at(c); }
+
+ private:
+ blt::hashmap_t glyphs;
+ blt::u32 used_width = 0;
+ blt::u32 used_height = 0;
+ };
class font_renderer_t
{
public:
- explicit font_renderer_t();
+ explicit font_renderer_t(const std::vector& files, blt::i32 dimensions = 4096);
+
private:
};
diff --git a/libraries/BLT b/libraries/BLT
index 7bf24a1..05e5fcf 160000
--- a/libraries/BLT
+++ b/libraries/BLT
@@ -1 +1 @@
-Subproject commit 7bf24a11a53d345b58a7437a1b9768f2da78eeb2
+Subproject commit 05e5fcf7f1091d6c85711ff7ce53d840c17e547b
diff --git a/src/blt/gfx/font/font.cpp b/src/blt/gfx/font/font.cpp
index 73c83aa..721d72f 100644
--- a/src/blt/gfx/font/font.cpp
+++ b/src/blt/gfx/font/font.cpp
@@ -18,6 +18,7 @@
#include
#include
#include
+#include
#include "blt/std/assert.h"
namespace blt::gfx::font
@@ -252,13 +253,19 @@ namespace blt::gfx::font
return *this;
}
- std::optional font_face_t::load_char(char c)
+ std::optional font_face_t::load_char(FT_ULong c) const
{
if (int err = FT_Load_Char(*face, c, FT_LOAD_RENDER))
return {err};
return {};
}
+ font_file_t::font_file_t(font_face_t font, u64 characterMinIndex, u64 characterMaxIndex):
+ font(std::move(font)), character_min_index(characterMinIndex), character_max_index(characterMaxIndex)
+ {}
+
+ glyph_t::glyph_t(const vec2ui& size, const vec2ui& bearing, blt::i64 advance): size(size), bearing(bearing), advance(advance)
+ {}
const unsigned int default_font_compressed_size = 91605;
const unsigned int default_font_compressed_data[91608 / 4] =
diff --git a/src/blt/gfx/renderer/font_renderer.cpp b/src/blt/gfx/renderer/font_renderer.cpp
index 5164f15..8c32ec2 100644
--- a/src/blt/gfx/renderer/font_renderer.cpp
+++ b/src/blt/gfx/renderer/font_renderer.cpp
@@ -19,5 +19,62 @@
namespace blt::gfx
{
-
+ font_texture_atlas::font_texture_atlas(blt::i32 dimensions): texture_gl2D(dimensions, dimensions, GL_RED)
+ {}
+
+ blt::u64 font_texture_atlas::add_font(const font::font_file_t& file)
+ {
+ return add_font(file, file.character_min_index);
+ }
+
+ blt::u64 font_texture_atlas::add_font(const font::font_file_t& file, blt::u64 start)
+ {
+ blt::u32 max_height = 0;
+ for (auto i = start; i < file.character_max_index; i++)
+ {
+ // returns an empty optional if there is no error code
+ if (file.font.load_char(i))
+ continue;
+ auto face = *file.font.get();
+
+ auto width = face->glyph->bitmap.width;
+ auto height = face->glyph->bitmap.rows;
+ max_height = std::max(max_height, height);
+
+ // if adding this width overflows, we need to move to the next row.
+ if (used_width + width > static_cast(getWidth()))
+ {
+ used_height += max_height;
+ max_height = 0;
+ used_width = 0;
+ }
+
+ // if we can't fit the height of this character we should move to the next texture atlas.
+ if (used_height + height > static_cast(getHeight()))
+ return i;
+
+ auto begin_width = used_width;
+ auto begin_height = used_height;
+ auto end_width = used_width + width;
+ auto end_height = used_height + height;
+
+ // upload the texture
+ upload(face->glyph->bitmap.buffer, GL_RED, 0, static_cast(begin_width), static_cast(begin_height),
+ static_cast(width), static_cast(height));
+
+ glyphs.insert(std::pair{i, bounded_t{
+ font::glyph_t{
+ {width, height},
+ {face->glyph->bitmap_left, face->glyph->bitmap_top},
+ face->glyph->advance.x},
+ {begin_width, begin_height}, {end_width, end_height}}
+ });
+ }
+ return -1;
+ }
+
+ font_renderer_t::font_renderer_t(const std::vector& files, blt::i32 dimensions)
+ {
+
+ }
}
\ No newline at end of file
diff --git a/src/blt/gfx/texture.cpp b/src/blt/gfx/texture.cpp
index 3a932d2..745696e 100644
--- a/src/blt/gfx/texture.cpp
+++ b/src/blt/gfx/texture.cpp
@@ -180,33 +180,6 @@ void blt::gfx::texture_gl::setDefaults(GLint type, GLint wrap_type) const
#endif
}
-void blt::gfx::texture_gl2D::upload(void* data, GLint dataColorMode, int level, int x_offset, int y_offset, int sub_width, int sub_height,
- GLint dataMode) const
-{
- if (sub_width < 0)
- sub_width = m_width;
- if (sub_height < 0)
- sub_height = m_height;
- bind();
- glTexSubImage2D(textureBindType, level, x_offset, y_offset, sub_width, sub_height, dataColorMode, dataMode, data);
- generateMipmaps();
- unbind();
-}
-
-void blt::gfx::texture_gl2D::upload(const blt::gfx::texture_data& file_data) const
-{
- upload((void*) file_data.data(), file_data.channels() == 4 ? GL_RGBA : GL_RGB, 0, 0, 0, file_data.width(), file_data.height());
-}
-
-void blt::gfx::texture_gl2D::upload(void* data, int width, int height, GLint dataColorMode, GLint dataMode)
-{
- bind();
- glTexImage2D(textureBindType, 0, textureColorMode, width, height, 0, dataColorMode, dataMode, data);
- generateMipmaps();
- unbind();
-}
-
-
void blt::gfx::texture_gl2D::resize(int width, int height)
{
m_width = width;
@@ -238,6 +211,34 @@ blt::gfx::texture_gl2D::texture_gl2D(const blt::gfx::texture_data& data):
unbind();
}
+void blt::gfx::texture_gl2D::upload(void* data, GLint dataColorMode, int level, int x_offset, int y_offset, int sub_width, int sub_height,
+ GLint dataMode) const
+{
+ if (sub_width < 0)
+ sub_width = m_width;
+ if (sub_height < 0)
+ sub_height = m_height;
+ bind();
+ glTexSubImage2D(textureBindType, level, x_offset, y_offset, sub_width, sub_height, dataColorMode, dataMode, data);
+ generateMipmaps();
+ unbind();
+}
+
+void blt::gfx::texture_gl2D::upload(const blt::gfx::texture_data& file_data) const
+{
+ upload((void*) file_data.data(), file_data.channels() == 4 ? GL_RGBA : GL_RGB, 0, 0, 0, file_data.width(), file_data.height());
+}
+
+void blt::gfx::texture_gl2D::upload(void* data, int width, int height, GLint dataColorMode, GLint dataMode)
+{
+ bind();
+ glTexImage2D(textureBindType, 0, textureColorMode, width, height, 0, dataColorMode, dataMode, data);
+ generateMipmaps();
+ unbind();
+}
+
+
+
void blt::gfx::gl_texture2D_array::upload(void* data, int index, GLint dataColorMode, int level, int x_offset, int y_offset, int sub_width,
int sub_height) const
{