История изменений
Исправление KivApple, (текущая версия) :
Сделал всё же не «моноширинный» режим:
struct FontGlyphInfo {
glm::vec2 texCoord;
glm::vec2 texSize;
glm::vec2 offset;
glm::vec2 size;
float width;
};
...
void PF2FontLoader::parseCharBitmap(int index, const PF2CharHeader &header, FontGlyphInfo &glyph) {
int x0 = (index % m_colCount) * m_maxCharWidth;
int y0 = (index / m_colCount) * m_maxCharHeight;
glyph.texCoord.x = static_cast<float>(x0) / static_cast<float>(m_textureWidth);
glyph.texCoord.y = static_cast<float>(y0) / static_cast<float>(m_textureHeight);
glyph.texSize.x = static_cast<float>(header.width) / static_cast<float>(m_textureWidth);
glyph.texSize.y = static_cast<float>(header.height) / static_cast<float>(m_textureHeight);
glyph.offset.x = static_cast<float>(header.xOffset) / static_cast<float>(m_pointSize);
glyph.offset.y = static_cast<float>(header.yOffset) / static_cast<float>(m_pointSize);
glyph.size.x = static_cast<float>(header.width) / static_cast<float>(m_pointSize);
glyph.size.y = static_cast<float>(header.height) / static_cast<float>(m_pointSize);
glyph.width = static_cast<float>(header.deviceWidth) / static_cast<float>(m_pointSize);
auto base = m_deserializer.adapter().currentReadPos();
for (int y = 0; y < header.height; y++) {
int j = (y0 + y) * m_textureWidth + x0;
for (int x = 0; x < header.width; x++) {
int i = y * header.width + x;
uint8_t byte = m_data[base + i / 8];
if ((byte & (1 << (7 - i % 8))) != 0) {
m_textureData[j + x] = {255, 255, 255, 255};
}
}
}
}
...
glm::vec2 p(0.0f);
for (auto c : text) {
if (c != '\n') {
auto &glyph = m_font->glyphInfo(c);
auto o = glyph.offset;
auto s = glyph.size;
auto t1 = glyph.texCoord;
auto t2 = t1 + glyph.texSize;
m_vertexData.insert(m_data.end(), {
{{o.x + p.x, o.y + p.y + s.y}, {t1.x, t1.y}}, // 1
{{o.x + p.x + s.x, o.y + p.y + s.y}, {t2.x, t1.y}}, // 2
{{o.x + p.x, o.y + p.y}, {t1.x, t2.y}}, // 3
{{o.x + p.x + s.x, o.y + p.y + s.y}, {t2.x, t1.y}}, // 2
{{o.x + p.x + s.x, o.y + p.y}, {t2.x, t2.y}}, // 4
{{o.x + p.x, o.y + p.y}, {t1.x, t2.y}} // 3
});
p.x += glyph.width;
} else {
p.y -= 1.0f;
p.x = 0.0f;
}
}
Такой подход в сочетании с тем фактом, что в OpenGL координата Y инвентировона дал нормальный рендеринг:
https://freeimage.host/i/iIhtOG
Но получается, что я вообще не использую параметры ascent и descent, нормально ли это или я что-то упускаю?
Исправление KivApple, :
Сделал всё же не «моноширинный режим»:
struct FontGlyphInfo {
glm::vec2 texCoord;
glm::vec2 texSize;
glm::vec2 offset;
glm::vec2 size;
float width;
};
...
void PF2FontLoader::parseCharBitmap(int index, const PF2CharHeader &header, FontGlyphInfo &glyph) {
int x0 = (index % m_colCount) * m_maxCharWidth;
int y0 = (index / m_colCount) * m_maxCharHeight;
glyph.texCoord.x = static_cast<float>(x0) / static_cast<float>(m_textureWidth);
glyph.texCoord.y = static_cast<float>(y0) / static_cast<float>(m_textureHeight);
glyph.texSize.x = static_cast<float>(header.width) / static_cast<float>(m_textureWidth);
glyph.texSize.y = static_cast<float>(header.height) / static_cast<float>(m_textureHeight);
glyph.offset.x = static_cast<float>(header.xOffset) / static_cast<float>(m_pointSize);
glyph.offset.y = static_cast<float>(header.yOffset) / static_cast<float>(m_pointSize);
glyph.size.x = static_cast<float>(header.width) / static_cast<float>(m_pointSize);
glyph.size.y = static_cast<float>(header.height) / static_cast<float>(m_pointSize);
glyph.width = static_cast<float>(header.deviceWidth) / static_cast<float>(m_pointSize);
auto base = m_deserializer.adapter().currentReadPos();
for (int y = 0; y < header.height; y++) {
int j = (y0 + y) * m_textureWidth + x0;
for (int x = 0; x < header.width; x++) {
int i = y * header.width + x;
uint8_t byte = m_data[base + i / 8];
if ((byte & (1 << (7 - i % 8))) != 0) {
m_textureData[j + x] = {255, 255, 255, 255};
}
}
}
}
...
glm::vec2 p(0.0f);
for (auto c : text) {
if (c != '\n') {
auto &glyph = m_font->glyphInfo(c);
auto o = glyph.offset;
auto s = glyph.size;
auto t1 = glyph.texCoord;
auto t2 = t1 + glyph.texSize;
m_vertexData.insert(m_data.end(), {
{{o.x + p.x, o.y + p.y + s.y}, {t1.x, t1.y}}, // 1
{{o.x + p.x + s.x, o.y + p.y + s.y}, {t2.x, t1.y}}, // 2
{{o.x + p.x, o.y + p.y}, {t1.x, t2.y}}, // 3
{{o.x + p.x + s.x, o.y + p.y + s.y}, {t2.x, t1.y}}, // 2
{{o.x + p.x + s.x, o.y + p.y}, {t2.x, t2.y}}, // 4
{{o.x + p.x, o.y + p.y}, {t1.x, t2.y}} // 3
});
p.x += glyph.width;
} else {
p.y -= 1.0f;
p.x = 0.0f;
}
}
Такой подход в сочетании с тем фактом, что в OpenGL координата Y инвентировона дал нормальный рендеринг:
https://freeimage.host/i/iIhtOG
Но получается, что я вообще не использую параметры ascent и descent, нормально ли это или я что-то упускаю?
Исходная версия KivApple, :
Сделал всё не «моноширинный режим»:
struct FontGlyphInfo {
glm::vec2 texCoord;
glm::vec2 texSize;
glm::vec2 offset;
glm::vec2 size;
float width;
};
...
void PF2FontLoader::parseCharBitmap(int index, const PF2CharHeader &header, FontGlyphInfo &glyph) {
int x0 = (index % m_colCount) * m_maxCharWidth;
int y0 = (index / m_colCount) * m_maxCharHeight;
glyph.texCoord.x = static_cast<float>(x0) / static_cast<float>(m_textureWidth);
glyph.texCoord.y = static_cast<float>(y0) / static_cast<float>(m_textureHeight);
glyph.texSize.x = static_cast<float>(header.width) / static_cast<float>(m_textureWidth);
glyph.texSize.y = static_cast<float>(header.height) / static_cast<float>(m_textureHeight);
glyph.offset.x = static_cast<float>(header.xOffset) / static_cast<float>(m_pointSize);
glyph.offset.y = static_cast<float>(header.yOffset) / static_cast<float>(m_pointSize);
glyph.size.x = static_cast<float>(header.width) / static_cast<float>(m_pointSize);
glyph.size.y = static_cast<float>(header.height) / static_cast<float>(m_pointSize);
glyph.width = static_cast<float>(header.deviceWidth) / static_cast<float>(m_pointSize);
auto base = m_deserializer.adapter().currentReadPos();
for (int y = 0; y < header.height; y++) {
int j = (y0 + y) * m_textureWidth + x0;
for (int x = 0; x < header.width; x++) {
int i = y * header.width + x;
uint8_t byte = m_data[base + i / 8];
if ((byte & (1 << (7 - i % 8))) != 0) {
m_textureData[j + x] = {255, 255, 255, 255};
}
}
}
}
...
glm::vec2 p(0.0f);
for (auto c : text) {
if (c != '\n') {
auto &glyph = m_font->glyphInfo(c);
auto o = glyph.offset;
auto s = glyph.size;
auto t1 = glyph.texCoord;
auto t2 = t1 + glyph.texSize;
m_vertexData.insert(m_data.end(), {
{{o.x + p.x, o.y + p.y + s.y}, {t1.x, t1.y}}, // 1
{{o.x + p.x + s.x, o.y + p.y + s.y}, {t2.x, t1.y}}, // 2
{{o.x + p.x, o.y + p.y}, {t1.x, t2.y}}, // 3
{{o.x + p.x + s.x, o.y + p.y + s.y}, {t2.x, t1.y}}, // 2
{{o.x + p.x + s.x, o.y + p.y}, {t2.x, t2.y}}, // 4
{{o.x + p.x, o.y + p.y}, {t1.x, t2.y}} // 3
});
p.x += glyph.width;
} else {
p.y -= 1.0f;
p.x = 0.0f;
}
}
Такой подход в сочетании с тем фактом, что в OpenGL координата Y инвентировона дал нормальный рендеринг:
https://freeimage.host/i/iIhtOG
Но получается, что я вообще не использую параметры ascent и descent, нормально ли это или я что-то упускаю?