allow collection of vertices/indices
this way we need only one draw call for multiple layers
This commit is contained in:
parent
26ca2bdf43
commit
604240360e
1 changed files with 97 additions and 5 deletions
|
@ -4,6 +4,7 @@
|
|||
// but it is still compiled in the "main.cpp" translation unit,
|
||||
// because both files have mostly the same dependencies (OpenGL, GLM, FreeType).
|
||||
#include "ofMain.h"
|
||||
#include "ofUtils.h"
|
||||
|
||||
#include <GL/glext.h>
|
||||
#include <ft2build.h>
|
||||
|
@ -57,12 +58,12 @@ class Font {
|
|||
float x0, y0, x1, y1, x2, y2;
|
||||
};
|
||||
|
||||
struct BufferVertex {
|
||||
float x, y, u, v;
|
||||
int32_t bufferIndex;
|
||||
};
|
||||
|
||||
public:
|
||||
struct BufferVertex {
|
||||
float x, y, u, v;
|
||||
int32_t bufferIndex;
|
||||
};
|
||||
|
||||
/// A structure to model a given axis of a variable font.
|
||||
struct FontVariationAxisParameters {
|
||||
/// The name of the variation axis.
|
||||
|
@ -700,6 +701,97 @@ class Font {
|
|||
|
||||
}
|
||||
|
||||
void collectVerticesAndIndices(const glm::vec3 & position,
|
||||
const std::string & text,
|
||||
std::vector <BufferVertex> & vertices,
|
||||
std::vector <int32_t> & indices,
|
||||
const bool vFlip = false,
|
||||
const float fontSize_px = 42){
|
||||
float x = position.x;
|
||||
float y = position.y;
|
||||
float originalX = x;
|
||||
|
||||
FT_UInt previous = 0;
|
||||
for(const char * textIt = text.c_str(); *textIt != '\0';){
|
||||
float letterFontSize_px = fontSize_px; // can be individual
|
||||
uint32_t charcode = decodeCharcode(&textIt);
|
||||
|
||||
if(charcode == '\r'){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(charcode == '\n'){
|
||||
x = originalX;
|
||||
y -= (float)face->height / (float)face->units_per_EM * worldSize;
|
||||
if(hinting){
|
||||
y = std::round(y);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
auto glyphIt = glyphs.find(charcode);
|
||||
Glyph & glyph = (glyphIt == glyphs.end()) ? glyphs[0] : glyphIt->second;
|
||||
|
||||
if(previous != 0 && glyph.index != 0){
|
||||
FT_Vector kerning;
|
||||
FT_Error error = FT_Get_Kerning(face, previous, glyph.index, kerningMode, &kerning);
|
||||
if(!error){
|
||||
x += (float)kerning.x / emSize * worldSize;
|
||||
}
|
||||
}
|
||||
|
||||
// Do not emit quad for empty glyphs (whitespace).
|
||||
if(glyph.curveCount){
|
||||
FT_Pos d = (FT_Pos)(emSize * dilation);
|
||||
|
||||
float u0 = (float)(glyph.bearingX - d) / emSize;
|
||||
float v0 = (float)(glyph.bearingY - glyph.height - d) / emSize;
|
||||
float u1 = (float)(glyph.bearingX + glyph.width + d) / emSize;
|
||||
float v1 = (float)(glyph.bearingY + d) / emSize;
|
||||
|
||||
|
||||
float x0 = x + u0 * worldSize * letterFontSize_px;
|
||||
float y0 = y + v0 * worldSize * letterFontSize_px;
|
||||
float x1 = x + u1 * worldSize * letterFontSize_px;
|
||||
float y1 = y + v1 * worldSize * letterFontSize_px;
|
||||
|
||||
if(vFlip){
|
||||
float _v = v0;
|
||||
v0 = v1;
|
||||
v1 = _v;
|
||||
|
||||
y0 = y - v0 * worldSize * letterFontSize_px;
|
||||
y1 = y - v1 * worldSize * letterFontSize_px;
|
||||
}
|
||||
|
||||
int32_t base = static_cast <int32_t>(vertices.size());
|
||||
vertices.push_back(BufferVertex{x0, y0, u0, v0, glyph.bufferIndex});
|
||||
vertices.push_back(BufferVertex{x1, y0, u1, v0, glyph.bufferIndex});
|
||||
vertices.push_back(BufferVertex{x1, y1, u1, v1, glyph.bufferIndex});
|
||||
vertices.push_back(BufferVertex{x0, y1, u0, v1, glyph.bufferIndex});
|
||||
|
||||
indices.insert(indices.end(), {base, base + 1, base + 2, base + 2, base + 3, base});
|
||||
}
|
||||
|
||||
x += ((float)glyph.advance * letterFontSize_px) / emSize * worldSize;
|
||||
previous = glyph.index;
|
||||
}
|
||||
}
|
||||
|
||||
void draw(const std::vector <BufferVertex> & vertices,
|
||||
const std::vector <int32_t> & indices){
|
||||
glBindVertexArray(vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(BufferVertex) * vertices.size(), vertices.data(), GL_STREAM_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int32_t) * indices.size(), indices.data(), GL_STREAM_DRAW);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void draw(float x, float y, float z, const std::string & text, bool vFlip = false, float fontSize_px = 42){
|
||||
float originalX = x;
|
||||
|
||||
|
|
Loading…
Reference in a new issue