Skip to content

Commit

Permalink
Bug fixes from pull request review
Browse files Browse the repository at this point in the history
  • Loading branch information
LucasDworschak committed Jan 17, 2024
1 parent 25877a3 commit 4bd02ab
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 47 deletions.
5 changes: 4 additions & 1 deletion gl_engine/shaders/labels.vert
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,13 @@ void main() {
// apply "soft" distance scaling depending on near/far label values (if option is set as uniform)
if(label_dist_scaling)
{
float dist_scale = 1.0 - ((dist - nearLabel) / (interpolatedFarLabelDistance - nearLabel)) * 0.4f;
float dist_scale = 1.0 - ((dist - nearLabel) / (farLabel1 - nearLabel)) * 0.4f;
scale *= (dist_scale * dist_scale);
}

// importance based scaling
scale *= (importance + 1.5) / 2.5;

// remove rotation from position -> since we want to always face the camera; and apply the scaling
vec4 rotationless_pos = (inv_view_rot * vec4((pos.xy + pos.zw*offset_mask[gl_VertexID]) * scale,0.0,1.0));
rotationless_pos /= rotationless_pos.w;
Expand Down
18 changes: 10 additions & 8 deletions nucleus/map_label/MapLabel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,16 @@
#include "CharUtils.h"
#include "srs.h"

#include <qDebug>

#include "stb_slim/stb_truetype.h"

namespace nucleus {

void MapLabel::init(const std::unordered_map<int, const MapLabel::CharData>& character_data, const stbtt_fontinfo* fontinfo)
void MapLabel::init(const std::unordered_map<int, const MapLabel::CharData>& character_data, const stbtt_fontinfo* fontinfo, const float uv_width_norm)
{
float offset_x = 0;
float offset_y = -font_size / 2.0f + 75.0;

float uv_width_norm = 1.0f / 512.0f;
float offset_x = 0.0f;
constexpr float offset_y = -font_size / 2.0f + 75.0f;

std::string altitude_text = std::to_string(m_altitude);
altitude_text = altitude_text.substr(0, altitude_text.find("."));
Expand Down Expand Up @@ -72,10 +74,10 @@ std::vector<float> inline MapLabel::create_text_meta(const std::unordered_map<in
float xOffset = 0;
for (unsigned long long i = 0; i < safe_chars.size(); i++) {
if (!character_data.contains(safe_chars[i])) {
std::cout << "character with unicode index(Dec: " << safe_chars[i] << ") cannot be shown -> please add it to nucleus/map_label/MapLabelManager.h.all_char_list" << std::endl;
qDebug() << "character with unicode index(Dec: " << safe_chars[i] << ") cannot be shown -> please add it to nucleus/map_label/MapLabelManager.h.all_char_list";
safe_chars[i] = 32; // replace with space character
}
// std::cout << "checking: " << safe_chars[i] << std::endl;

assert(character_data.contains(safe_chars[i]));

int advance, lsb;
Expand All @@ -91,7 +93,7 @@ std::vector<float> inline MapLabel::create_text_meta(const std::unordered_map<in

{ // get width of last char
if (!character_data.contains(safe_chars[safe_chars.size() - 1])) {
std::cout << "character with unicode index(Dec: " << safe_chars[safe_chars.size() - 1] << ") cannot be shown -> please add it to nucleus/map_label/MapLabelManager.h.all_char_list" << std::endl;
qDebug() << "character with unicode index(Dec: " << safe_chars[safe_chars.size() - 1] << ") cannot be shown -> please add it to nucleus/map_label/MapLabelManager.h.all_char_list";
safe_chars[safe_chars.size() - 1] = 32; // replace with space character
}
const MapLabel::CharData b = character_data.at(safe_chars[safe_chars.size() - 1]);
Expand Down
10 changes: 6 additions & 4 deletions nucleus/map_label/MapLabel.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@
#include <string>
#include <vector>

#include "stb_slim/stb_truetype.h"

#include <unordered_map>

struct stbtt_fontinfo;

namespace nucleus {

class MapLabel {
Expand All @@ -47,9 +47,11 @@ class MapLabel {
, m_latitude(latitude)
, m_longitude(longitude)
, m_altitude(altitude)
, m_importance(importance) {};
, m_importance(importance)
{
}

void init(const std::unordered_map<int, const MapLabel::CharData>& character_data, const stbtt_fontinfo* fontinfo);
void init(const std::unordered_map<int, const MapLabel::CharData>& character_data, const stbtt_fontinfo* fontinfo, const float uv_width_norm);

constexpr static float font_size = 30.0f;
constexpr static glm::vec2 icon_size = glm::vec2(30.0f);
Expand Down
46 changes: 18 additions & 28 deletions nucleus/map_label/MapLabelManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "MapLabelManager.h"

#include <QDebug>
#include <QFile>
#include <QIcon>
#include <QSize>
Expand All @@ -34,7 +35,8 @@
namespace nucleus {

MapLabelManager::MapLabelManager()
: m_font_atlas(m_font_atlas_size, QImage::Format_RGB32)
: m_font_bitmap(m_font_atlas_size.width() * m_font_atlas_size.height() * m_channel_count)
, m_font_atlas(m_font_atlas_size, QImage::Format_RGB32)
{
// const char8_t text;
// double latitude;
Expand Down Expand Up @@ -73,11 +75,6 @@ MapLabelManager::MapLabelManager()
m_labels.push_back({ "Östliche Hochgrubachspitze", 47.5587933, 12.3450985, 2284, 0 });
}

MapLabelManager::~MapLabelManager()
{
delete[] m_font_bitmap;
}

void MapLabelManager::init()
{
m_indices.push_back(0);
Expand All @@ -91,27 +88,23 @@ void MapLabelManager::init()
create_font();

for (auto& label : m_labels) {
label.init(m_char_data, &m_fontinfo);
label.init(m_char_data, &m_fontinfo, uv_width_norm);
}

// paint svg icon into the an image of appropriate size
m_icon = QIcon(QString(":/qt/qml/app/icons/peak.svg")).pixmap(QSize(MapLabel::icon_size.x, MapLabel::icon_size.y)).toImage();
}

void inline MapLabelManager::make_outline(uint8_t* temp_bitmap, int lasty)
void inline MapLabelManager::make_outline(std::vector<uint8_t>& temp_bitmap, const int lasty)
{
// create the final font bitmap (3 channels -> 1 for font; 1 for outline; the last channel is empty)
const int channels = 3;
m_font_bitmap = new uint8_t[m_font_atlas_size.width() * m_font_atlas_size.height() * channels];
// set everything to 0
memset(m_font_bitmap, 0, m_font_atlas_size.width() * m_font_atlas_size.height() * channels);

const int outline_bit_count = 4 * (m_font_outline.x - 1) * (m_font_outline.y - 1) + 2 * (m_font_outline.x - 1) + 2 * (m_font_outline.y - 1) + 1;
int* outline_mask = new int[outline_bit_count];
std::fill(m_font_bitmap.begin(), m_font_bitmap.end(), 0);

constexpr int outline_bit_count = 4 * (m_font_outline.x - 1) * (m_font_outline.y - 1) + 2 * (m_font_outline.x - 1) + 2 * (m_font_outline.y - 1) + 1;
int outline_mask[outline_bit_count];
int index = 0;
for (int i = -m_font_outline.y + 1; i < m_font_outline.y; i++) {
for (int j = -m_font_outline.x + 1; j < m_font_outline.x; j++) {
outline_mask[index++] = (i * m_font_atlas_size.width() + j) * channels + 1;
outline_mask[index++] = (i * m_font_atlas_size.width() + j) * m_channel_count + 1;
}
}

Expand All @@ -120,8 +113,9 @@ void inline MapLabelManager::make_outline(uint8_t* temp_bitmap, int lasty)

for (int i = 0; i < lasty; ++i) {
for (int j = 0; j < m_font_atlas_size.width(); ++j) {

const uint8_t value = temp_bitmap[(i * m_font_atlas_size.width() + j)];
const int current_index = (i * m_font_atlas_size.width() + j) * channels;
const int current_index = (i * m_font_atlas_size.width() + j) * m_channel_count;
m_font_bitmap[current_index] = value;

// add the outline to the outline channel
Expand All @@ -140,8 +134,6 @@ void inline MapLabelManager::make_outline(uint8_t* temp_bitmap, int lasty)
}
}
}

delete[] outline_mask;
}

void MapLabelManager::create_font()
Expand All @@ -156,12 +148,12 @@ void MapLabelManager::create_font()
const auto font_init = stbtt_InitFont(&m_fontinfo, reinterpret_cast<const uint8_t*>(data.constData()), stbtt_GetFontOffsetForIndex(reinterpret_cast<const uint8_t*>(data.constData()), 0));
assert(font_init);

uint8_t* temp_bitmap = new uint8_t[m_font_atlas_size.width() * m_font_atlas_size.height()];
std::vector<uint8_t> temp_bitmap(m_font_atlas_size.width() * m_font_atlas_size.height());
std::fill(temp_bitmap.begin(), temp_bitmap.end(), 0);

const std::vector<int> safe_chars = CharUtils::string_to_unicode_int_list(all_char_list);

float scale = stbtt_ScaleForPixelHeight(&m_fontinfo, MapLabel::font_size);
STBTT_memset(temp_bitmap, 0, m_font_atlas_size.width() * m_font_atlas_size.height()); // background of 0 around pixel

int x = m_font_outline.x + m_font_padding.x;
int y = m_font_outline.y + m_font_padding.y;
Expand All @@ -179,12 +171,12 @@ void MapLabelManager::create_font()
y = bottom_y, x = 2 * m_font_outline.x + m_font_padding.x; // advance to next row
if (y + glyph_height + m_font_outline.y + m_font_padding.y >= m_font_atlas_size.height()) // check if it fits vertically AFTER potentially moving to next row
{
std::cout << "Font doesnt fit into bitmap" << std::endl;
qDebug() << "Font doesnt fit into bitmap";
assert(false);
break; // doesnt fit in image
}

stbtt_MakeGlyphBitmap(&m_fontinfo, temp_bitmap + x + y * m_font_atlas_size.width(), glyph_width, glyph_height, m_font_atlas_size.width(), scale, scale, glyph_index);
stbtt_MakeGlyphBitmap(&m_fontinfo, temp_bitmap.data() + x + y * m_font_atlas_size.width(), glyph_width, glyph_height, m_font_atlas_size.width(), scale, scale, glyph_index);
m_char_data.emplace(c, MapLabel::CharData { (unsigned short)(x - m_font_outline.x), (unsigned short)(y - m_font_outline.y), (unsigned short)(glyph_width + m_font_outline.x * 2), (unsigned short)(glyph_height + m_font_outline.y * 2), (float)x0 - m_font_outline.x, (float)y0 - m_font_outline.y });

x = x + glyph_width + 2 * m_font_outline.x + m_font_padding.x;
Expand All @@ -194,11 +186,9 @@ void MapLabelManager::create_font()

make_outline(temp_bitmap, bottom_y);

delete[] temp_bitmap;

// create a qimage with the data
m_font_atlas = QImage(m_font_bitmap, m_font_atlas_size.width(), m_font_atlas_size.height(), QImage::Format_RGB888);
// m_font_atlas.save("font_atlas.png");
m_font_atlas = QImage(m_font_bitmap.data(), m_font_atlas_size.width(), m_font_atlas_size.height(), QImage::Format_RGB888);
// m_font_atlas.save("font_atlas.png");
}

const std::vector<MapLabel>& MapLabelManager::labels() const
Expand Down
16 changes: 10 additions & 6 deletions nucleus/map_label/MapLabelManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#pragma once

#include "MapLabel.h"

#include <QImage>
#include <vector>

Expand All @@ -30,7 +31,6 @@ namespace nucleus {
class MapLabelManager {
public:
explicit MapLabelManager();
~MapLabelManager();

void init();

Expand All @@ -41,22 +41,26 @@ class MapLabelManager {

private:
// list of all characters that will be available (will be rendered to the font_atlas)
const std::string all_char_list = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789()[]{},;.:-_!\"§$%&/\\=+-*/#'~°^<>|@€´`öÖüÜäÄß";
static constexpr auto all_char_list = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789()[]{},;.:-_!\"§$%&/\\=+-*/#'~°^<>|@€´`öÖüÜäÄß";

static constexpr glm::vec2 m_font_outline = glm::vec2(2, 2);
static constexpr glm::vec2 m_font_padding = glm::vec2(2, 2);
static constexpr glm::ivec2 m_font_outline = glm::ivec2(2, 2);
static constexpr glm::ivec2 m_font_padding = glm::ivec2(2, 2);
static constexpr QSize m_font_atlas_size = QSize(512, 512);
static constexpr float uv_width_norm = 1.0f / m_font_atlas_size.width();

// 3 channels -> 1 for font; 1 for outline; the last channel is empty
static constexpr int m_channel_count = 3;

std::vector<MapLabel> m_labels;
std::vector<unsigned int> m_indices;

std::unordered_map<int, const MapLabel::CharData> m_char_data;

stbtt_fontinfo m_fontinfo;
uint8_t* m_font_bitmap;
std::vector<uint8_t> m_font_bitmap;

void create_font();
void inline make_outline(uint8_t* temp_bitmap, int lasty);
void inline make_outline(std::vector<uint8_t>& temp_bitmap, const int lasty);

QImage m_font_atlas;
QImage m_icon;
Expand Down

0 comments on commit 4bd02ab

Please sign in to comment.