Fix text rendering

This commit is contained in:
Corentin 2021-07-13 00:35:45 +09:00
commit 1a200205a5
12 changed files with 214 additions and 68 deletions

View file

@ -0,0 +1,28 @@
#include <iostream>
#include "uui/opengl/application.hpp"
#include "uui/opengl/component.hpp"
#include "uui/opengl/label.hpp"
using namespace std;
int main()
{
try
{
uui::GlApplication app;
// uui::GlApplication app2; // exception : application already created
auto window = app.create_window(800, 600, "OpenGl!");
for(int i = 0; i < 100; i += 1)
window->create_label(4*i, 4*i, "Hello World!", {1.0f, 1.0f, 1.0f, 0.5f});
app.run();
}
catch(const std::exception& error)
{
std::cerr << error.what() << std::endl;
return EXIT_FAILURE;
}
cout << "Example done" << endl;
return 0;
}

View file

@ -15,10 +15,13 @@ int main()
uui::GlApplication app;
// uui::GlApplication app2; // exception : application already created
auto window = app.create_window(800, 600, "OpenGl!");
auto comp = window->create_component(0, 100, 0.5f, 50);
comp->set_background_color(0.8f, 0.1f, 0.5f);
auto label = window->create_label(0.5f, 0.5f, "Hello World!", {1.0f, 1.0f, 1.0f, 0.5f});
label->set_background_color(0.1f, 0.5f, 0.1f);
// auto comp = window->create_component(0, 100, 0.5f, 50);
// comp->set_background_color(0.8f, 0.1f, 0.5f);
auto label = window->create_label(50, 50, "Hello World!", {0.5f, 1.0f, 0.5f, 1.0f});
label->set_background_color(0.1f, 0.2f, 0.5f);
label = window->create_label(0.5f, 0.5f, "Hello World!", {1.0f, 1.0f, 1.0f, 0.5f});
label->set_background_color(0.5f, 0.5f, 0.1f);
label = window->create_label(0.75f, 0.75f, "Hello World!", {1.0f, 1.0f, 1.0f, 0.1f});
app.run();
}
// cout << "\nStarting example 2" << endl;

View file

@ -59,8 +59,10 @@ void uui::GlApplication::run()
frame_count = 0.0f;
start_time = end_time;
}
glfwPollEvents();
}
glfwPollEvents();
else
glfwWaitEvents();
// Destroying windows
for(auto it = windows.begin(); it != windows.end(); it += 1)
@ -78,7 +80,15 @@ void uui::GlApplication::run()
it -= 1;
}
else
window->draw();
{
if constexpr(debug_mode)
window->render();
else
{
if(window->render_needed && !window->iconified)
window->render();
}
}
}
if constexpr(debug_mode)
frame_count += 1;

View file

@ -104,11 +104,7 @@ void uui::GlComponent::set_vbo_data()
};
// clang-format on
glBindBuffer(GL_ARRAY_BUFFER, gl_vbo);
if constexpr(uui::GlApplication::debug_mode)
_glCheckError();
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
if constexpr(uui::GlApplication::debug_mode)
_glCheckError();
glVertexAttribPointer(
0, // index
@ -145,8 +141,6 @@ void uui::GlComponent::render()
{
glBindVertexArray(gl_vao);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*)0);
if constexpr(uui::GlApplication::debug_mode)
_glCheckError();
}
void uui::GlComponent::on_resize()

View file

@ -116,7 +116,7 @@ void uui::GlFontManager::deinit()
if(!initialized)
throw std::runtime_error("GlFontManager error : calling deinit while not initialized");
for(const auto& font: fonts) glDeleteTextures(1, &font.tex);
for(const auto& font: fonts) glDeleteTextures(1, &font.atlas_texture);
glDeleteBuffers(1, &gl_vbo);
glDeleteBuffers(1, &gl_vao);
glDeleteProgram(gl_program);
@ -128,6 +128,7 @@ const uui::GlFontManager::Font& uui::GlFontManager::init_font(const std::string&
{
fonts.emplace_back();
auto& font = fonts.back();
FT_Face face;
if(FT_New_Face(ft, font_path.c_str(), 0, &face))
throw std::runtime_error("ERROR::FREETYPE: Failed to load font");
@ -141,14 +142,14 @@ const uui::GlFontManager::Font& uui::GlFontManager::init_font(const std::string&
memset(font.char_infos, 0, sizeof(font.char_infos));
// Find minimum size for a texture holding all visible ASCII characters
for(int i = 32; i < 128; i++)
for(int i = 32; i < 256; i++)
{
if(FT_Load_Char(face, i, FT_LOAD_RENDER))
{
std::cout << "GlFontManager warning : loading character " << i << " failed!" << std::endl;
continue;
}
if(row_width + glyph->bitmap.width + 1 >= MAX_WIDTH)
if(row_width + glyph->bitmap.width + 1 >= ATLAS_MAX_WIDTH)
{
font.atlas_width = std::max(font.atlas_width, row_width);
font.atlas_height += row_height;
@ -166,8 +167,8 @@ const uui::GlFontManager::Font& uui::GlFontManager::init_font(const std::string&
// Create a texture that will be used to hold all ASCII glyphs
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &font.tex);
glBindTexture(GL_TEXTURE_2D, font.tex);
glGenTextures(1, &font.atlas_texture);
glBindTexture(GL_TEXTURE_2D, font.atlas_texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, font.atlas_width, font.atlas_height, 0, GL_RED, GL_UNSIGNED_BYTE, 0);
@ -188,7 +189,7 @@ const uui::GlFontManager::Font& uui::GlFontManager::init_font(const std::string&
row_height = 0;
for(int i = 32; i < 128; i++)
for(int i = 32; i < 256; i++)
{
if(FT_Load_Char(face, i, FT_LOAD_RENDER))
{
@ -196,7 +197,7 @@ const uui::GlFontManager::Font& uui::GlFontManager::init_font(const std::string&
continue;
}
if(offset_x + glyph->bitmap.width + 1 >= MAX_WIDTH)
if(offset_x + glyph->bitmap.width + 1 >= ATLAS_MAX_WIDTH)
{
offset_y += row_height;
row_height = 0;
@ -254,7 +255,7 @@ void uui::GlFontManager::render_text(
glBindVertexArray(gl_vao);
// Use the texture containing the atlas
glBindTexture(GL_TEXTURE_2D, font.tex);
glBindTexture(GL_TEXTURE_2D, font.atlas_texture);
std::vector<float> vertices;
vertices.resize(24 * text.size());
@ -269,7 +270,7 @@ void uui::GlFontManager::render_text(
const auto& char_info = font.char_infos[static_cast<size_t>(current_char)];
// Calculate the vertex and texture coordinates
float char_x = out_base_x + char_info.bitmap_left * scale_x;
float char_y = -out_base_y - char_info.bitmap_top * scale_y;
float char_y = out_base_y - char_info.bitmap_top * scale_y;
float w = char_info.bitmap_width * scale_x;
float h = char_info.bitmap_height * scale_y;
@ -283,12 +284,12 @@ void uui::GlFontManager::render_text(
// clang-format off
float current_vertex[24] = {
char_x, -char_y, char_info.texture_x, char_info.texture_y, // top_left
char_x + w, -char_y, char_info.texture_x + char_info.bitmap_width / font.atlas_width, char_info.texture_y, // top-right
char_x, -char_y - h, char_info.texture_x, char_info.texture_y + char_info.bitmap_height / font.atlas_height, // bottom-right
char_x + w, -char_y, char_info.texture_x + char_info.bitmap_width / font.atlas_width, char_info.texture_y, // top-right
char_x, -char_y - h, char_info.texture_x, char_info.texture_y + char_info.bitmap_height / font.atlas_height, // bottom-left
char_x + w, -char_y - h, char_info.texture_x + char_info.bitmap_width / font.atlas_width,
char_x, char_y, char_info.texture_x, char_info.texture_y, // top_left
char_x + w, char_y, char_info.texture_x + char_info.bitmap_width / font.atlas_width, char_info.texture_y, // top-right
char_x, char_y + h, char_info.texture_x, char_info.texture_y + char_info.bitmap_height / font.atlas_height, // bottom-right
char_x + w, char_y, char_info.texture_x + char_info.bitmap_width / font.atlas_width, char_info.texture_y, // top-right
char_x, char_y + h, char_info.texture_x, char_info.texture_y + char_info.bitmap_height / font.atlas_height, // bottom-left
char_x + w, char_y + h, char_info.texture_x + char_info.bitmap_width / font.atlas_width,
char_info.texture_y + char_info.bitmap_height / font.atlas_height // bottom-right
};
std::memcpy(vertices.data() + (char_count * 24), current_vertex, 24 * sizeof(float));

View file

@ -15,9 +15,9 @@ uui::GlLabel::GlLabel(
font_index = 0;
std::tie(text_width, text_height) = window->font_manager.get_text_size(text, window->font_manager.fonts[font_index], 1.0f, 1.0f);
std::cout << "Text size: " << this->text_width << "x" << text_height << std::endl;
size_width = text_width;
size_height = text_height;
coord_all_relative = false;
}
void uui::GlLabel::render()
@ -26,7 +26,7 @@ void uui::GlLabel::render()
position_x.index() == 1 ? std::get<1>(position_x) * static_cast<float>(window->width) : static_cast<float>(std::get<0>(position_x));
float text_y =
position_y.index() == 1 ? std::get<1>(position_y) * static_cast<float>(window->height) : static_cast<float>(std::get<0>(position_y));
text_y -= static_cast<float>(text_height) - 1;
text_y += static_cast<float>(text_height) - 1;
glBindVertexArray(gl_vao);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*)0);

View file

@ -59,9 +59,12 @@ void uui::GlWindow::glfw_resize_callback(GLFWwindow* window, int width, int heig
glViewport(0, 0, width, height);
gl_window->width = width;
gl_window->height = height;
gl_window->need_resize_refresh = true;
gl_window->render_needed = true;
gl_window->resize_needed = true;
glm::mat4 projection = glm::ortho(0.0f, static_cast<float>(width), 0.0f, static_cast<float>(height));
glm::mat4 projection = glm::ortho(0.0f, static_cast<float>(width), static_cast<float>(height), 0.0f);
glfwMakeContextCurrent(window);
glUseProgram(gl_window->font_manager.gl_program);
glUniformMatrix4fv(glGetUniformLocation(gl_window->font_manager.gl_program, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
}
@ -78,7 +81,7 @@ void uui::GlWindow::glfw_key_callback(GLFWwindow* window, int key, int scancode,
}
uui::GlWindow::GlWindow(uui::GlApplication* app, size_t index, int width, int height, const std::string& title):
app(app), width(width), height(height), need_resize_refresh(false), iconified(false), index(index), initialized(false)
app(app), width(width), height(height), render_needed(true), resize_needed(false), iconified(false), index(index), initialized(false)
{
if constexpr(uui::GlApplication::debug_mode)
std::cout << "Creating a GlWindow" << std::endl;
@ -117,7 +120,7 @@ void uui::GlWindow::init()
// glEnable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
if constexpr(uui::GlApplication::debug_mode)
{
@ -199,7 +202,7 @@ void uui::GlWindow::init()
font_manager.init();
glUseProgram(font_manager.gl_program);
glm::mat4 projection = glm::ortho(0.0f, static_cast<float>(width), 0.0f, static_cast<float>(height));
glm::mat4 projection = glm::ortho(0.0f, static_cast<float>(width), static_cast<float>(height), 0.0f);
glUniformMatrix4fv(glGetUniformLocation(font_manager.gl_program, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
glUseProgram(gl_program);
@ -224,24 +227,22 @@ void uui::GlWindow::deinit()
initialized = false;
}
void uui::GlWindow::draw()
void uui::GlWindow::render()
{
if(!iconified)
glfwMakeContextCurrent(glfw_window);
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(gl_program);
if(resize_needed)
{
glfwMakeContextCurrent(glfw_window);
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(gl_program);
if(need_resize_refresh)
{
for(auto& component: components) component->on_resize();
need_resize_refresh = false;
}
for(auto& component: components) component->render();
for(auto& component: components) component->on_resize();
resize_needed = false;
}
for(auto& component: components) component->render();
glfwSwapBuffers(glfw_window);
render_needed = false;
}
std::shared_ptr<uui::GlComponent> uui::GlWindow::create_component(