do font stuff

This commit is contained in:
Bailey Harrison 2022-11-23 16:20:08 +00:00
parent b5c7750649
commit 04a7114e0e
9 changed files with 67 additions and 68 deletions

View File

@ -1,11 +1,11 @@
#pragma once #pragma once
#if 0
#include "engine_api.h" #include "engine_api.h"
#include "resource.hpp" #include "resource.hpp"
#include "gfx.hpp"
#include <glm/vec2.hpp> #include <glm/vec2.hpp>
#include <map> #include <map>
@ -17,7 +17,7 @@ class ENGINE_API Font : public Resource {
public: public:
struct Character { struct Character {
unsigned int textureID; // openGL texture handle gfx::Texture* texture;
glm::ivec2 size; glm::ivec2 size;
glm::ivec2 bearing; // offset from baseline to top-left of glyph glm::ivec2 bearing; // offset from baseline to top-left of glyph
long advance; // offset to the next glyph long advance; // offset to the next glyph
@ -33,4 +33,3 @@ public:
}; };
} }
#endif

View File

@ -7,5 +7,6 @@
namespace engine::util { namespace engine::util {
std::unique_ptr<std::vector<char>> readTextFile(const std::string& path); std::unique_ptr<std::vector<char>> readTextFile(const std::string& path);
std::unique_ptr<std::vector<uint8_t>> readBinaryFile(const std::string& path);
} }

View File

@ -22,7 +22,7 @@ namespace engine {
class ENGINE_API Window { class ENGINE_API Window {
public: public:
Window(const std::string& title, bool resizable = true); Window(const std::string& title, bool resizable = true, bool fullscreen = true);
Window(const Window&) = delete; Window(const Window&) = delete;
Window& operator=(const Window&) = delete; Window& operator=(const Window&) = delete;
~Window(); ~Window();

3
release.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/sh
cd "Release/test"
./enginetest

3
run.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/sh
cd "Debug/test"
./enginetest

View File

@ -16,7 +16,7 @@ namespace engine {
Application::Application(const char* appName, const char* appVersion) Application::Application(const char* appName, const char* appVersion)
{ {
m_win = new Window(appName, true); m_win = new Window(appName, true, true);
gfxdev = new GFXDevice(appName, appVersion, m_win->getHandle()); gfxdev = new GFXDevice(appName, appVersion, m_win->getHandle());

View File

@ -1,87 +1,58 @@
#if 0
#include "resources/font.hpp" #include "resources/font.hpp"
#include <ft2build.h> #define STB_TRUETYPE_IMPLEMENTATION
#include FT_FREETYPE_H #include <stb_truetype.h>
#include "util/files.hpp"
#include "gfx_device.hpp"
namespace engine::resources { namespace engine::resources {
Font::Font(const std::filesystem::path& resPath) : Resource(resPath, "font") Font::Font(const std::filesystem::path& resPath) : Resource(resPath, "font")
{ {
FT_Library library; // TODO: load font
FT_Face face; auto fontBuffer = util::readBinaryFile(resPath);
int err;
err = FT_Init_FreeType(&library); stbtt_fontinfo info{};
if (err) { int res = stbtt_InitFont(&info, fontBuffer->data(), 0);
throw std::runtime_error("Failed to initialise freetype library"); if (res != 0) {
throw std::runtime_error("Failed to read font file: " + resPath.string());
} }
err = FT_New_Face(library, resPath.string().c_str(), 0, &face); float scale = stbtt_ScaleForPixelHeight(&info, 64);
if (err == FT_Err_Unknown_File_Format) {
FT_Done_FreeType(library);
throw std::runtime_error("Unknown file format for font '" + resPath.string() + "'");
}
else if (err != 0) {
FT_Done_FreeType(library);
throw std::runtime_error("Unable to open font '" + resPath.string() + "'");
}
err = FT_Set_Pixel_Sizes(face, 0, 64);
if (err) {
FT_Done_Face(face);
FT_Done_FreeType(library);
throw std::runtime_error("Attempt to set pixel size to one unavailable in the font");
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
for (unsigned char c = 0; c < 128; c++) { for (unsigned char c = 0; c < 128; c++) {
err = FT_Load_Char(face, c, FT_LOAD_RENDER); // TODO: get character bitmap buffer, size, offsets, advance
if (err) { int32_t advance = 0, xoff = 0;
FT_Done_Face(face); stbtt_GetCodepointHMetrics(&info, c, &advance, &xoff);
FT_Done_FreeType(library);
throw std::runtime_error("Unable to load char glyph"); int32_t w, h, yoff;
const uint8_t* bitmap = stbtt_GetCodepointBitmap(&info, scale, scale, c, &w, &h, &xoff, &yoff);
auto colorBuffer = std::make_unique<std::vector<uint32_t>>(w * h);
int i = 0;
for (uint32_t& col : *colorBuffer) {
col = bitmap[i];
i++;
} }
// generate texture // generate texture
unsigned int texture; gfx::Texture* texture = gfxdev->createTexture(colorBuffer->data(), w, h, gfx::TextureFilter::LINEAR, gfx::TextureFilter::LINEAR);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RED,
face->glyph->bitmap.width,
face->glyph->bitmap.rows,
0,
GL_RED,
GL_UNSIGNED_BYTE,
face->glyph->bitmap.buffer
);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
Character character = { Character character = {
texture, texture,
glm::ivec2{face->glyph->bitmap.width, face->glyph->bitmap.rows}, // Size of Glyph glm::ivec2{w, h}, // Size of Glyph
glm::ivec2{face->glyph->bitmap_left, face->glyph->bitmap_top}, // Offset from baseline (bottom-left) to top-left of glyph glm::ivec2{xoff, yoff}, // Offset from baseline (bottom-left) to top-left of glyph
face->glyph->advance.x advance
}; };
m_characters.insert(std::make_pair(c, character)); m_characters.insert(std::make_pair(c, character));
} }
glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // reset alignment settings // TODO clean up resources
FT_Done_Face(face);
FT_Done_FreeType(library);
} }
@ -95,4 +66,3 @@ Font::Character Font::getChar(char c)
} }
} }
#endif

View File

@ -30,4 +30,23 @@ namespace engine::util {
return buffer; return buffer;
} }
std::unique_ptr<std::vector<uint8_t>> readBinaryFile(const std::string& path)
{
std::ifstream file(path, std::ios::ate | std::ios::binary);
if (file.is_open() == false) {
throw std::runtime_error("Unable to open file " + path);
}
auto buffer = std::make_unique<std::vector<uint8_t>>(file.tellg());
file.seekg(0);
file.read((char*)buffer->data(), buffer->size());
file.close();
return buffer;
}
} }

View File

@ -9,7 +9,7 @@ const uint64_t BILLION = 1000000000;
namespace engine { namespace engine {
Window::Window(const std::string& title, bool resizable) : m_title(title), m_resizable(resizable) Window::Window(const std::string& title, bool resizable, bool fullscreen) : m_title(title), m_resizable(resizable), m_fullscreen(fullscreen)
{ {
// init SDL // init SDL
@ -39,6 +39,10 @@ namespace engine {
windowFlags |= SDL_WINDOW_RESIZABLE; windowFlags |= SDL_WINDOW_RESIZABLE;
} }
if (m_fullscreen) {
windowFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
}
// create the window // create the window
m_handle = SDL_CreateWindow( m_handle = SDL_CreateWindow(
m_title.c_str(), m_title.c_str(),