Refactor text rendering to use less input data
This commit is contained in:
parent
c1b6a2add3
commit
678414f014
2 changed files with 57 additions and 40 deletions
43
main.cpp
43
main.cpp
|
|
@ -237,7 +237,7 @@ uint32_t make_gl_program(const char *pathname_vertex, const char *pathname_fragm
|
|||
void render_text(const char *text, float x, float y, float scale, glm::vec3 color)
|
||||
{
|
||||
// TODO: Group draw calls together instead of doing 1 draw call/character. Use an atlas with GL_TEXTURE_ARRAY
|
||||
// TODO: Do not make draw calls for invisible characters!
|
||||
// Take tips from https://www.youtube.com/watch?v=S0PyZKX4lyI
|
||||
|
||||
// activate corresponding render state
|
||||
glUseProgram(text_program);
|
||||
|
|
@ -251,31 +251,39 @@ void render_text(const char *text, float x, float y, float scale, glm::vec3 colo
|
|||
char c = *p;
|
||||
charglyph_t charglyph = glyphmap[(size_t)c];
|
||||
|
||||
if (c == ' ') // Just advance by normal horizontal distance and prepare for next char
|
||||
{
|
||||
x += (charglyph.advance >> 6) * scale;
|
||||
continue;
|
||||
}
|
||||
|
||||
float xpos = x + charglyph.bearing.x * scale;
|
||||
float ypos = y - (charglyph.size.y - charglyph.bearing.y) * scale;
|
||||
|
||||
float w = charglyph.size.x * scale;
|
||||
float h = charglyph.size.y * scale;
|
||||
glm::mat4 transform = glm::translate(glm::mat4(1.0f), glm::vec3(xpos, ypos, 0)) * glm::scale(glm::mat4(1.0f), glm::vec3(charglyph.size.x * scale, charglyph.size.y * scale, 0));
|
||||
glUniformMatrix4fv(glGetUniformLocation(text_program, "transform"), 1, GL_FALSE, &transform[0][0]);
|
||||
|
||||
// update VBO for each character
|
||||
float vertices[4][4] = {
|
||||
{ xpos, ypos + h, 0.0f, 0.0f },
|
||||
{ xpos, ypos, 0.0f, 1.0f },
|
||||
{ xpos + w, ypos, 1.0f, 1.0f },
|
||||
{ xpos + w, ypos + h, 1.0f, 0.0f }
|
||||
};
|
||||
// float vertices[4][4] = {
|
||||
// { xpos, ypos + h, 0.0f, 0.0f },
|
||||
// { xpos, ypos, 0.0f, 1.0f },
|
||||
// { xpos + w, ypos, 1.0f, 1.0f },
|
||||
// { xpos + w, ypos + h, 1.0f, 0.0f }
|
||||
// };
|
||||
// render glyph texture over quad
|
||||
glBindTexture(GL_TEXTURE_2D, charglyph.tex);
|
||||
// update content of VBO memory
|
||||
glBindBuffer(GL_ARRAY_BUFFER, textvbo);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
//glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
|
||||
|
||||
// render quad
|
||||
glEnable(GL_CULL_FACE);
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, 1);
|
||||
glDisable(GL_CULL_FACE);
|
||||
// now advance cursors for next glyph (note that advance is number of 1/64 pixels)
|
||||
x += (charglyph.advance >> 6) * scale; // bitshift by 6 to get value in pixels (2^6 = 64)
|
||||
}
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
|
@ -452,14 +460,21 @@ int main([[maybe_unused]]int argc, [[maybe_unused]]char **argv)
|
|||
// text initialization
|
||||
text_program = make_gl_program("shaders/text.vert", "shaders/text.frag");
|
||||
|
||||
static GLfloat vertex_data[] = {
|
||||
0.0f, 1.0f,
|
||||
0.0f, 0.0f,
|
||||
1.0f, 0.0f,
|
||||
1.0f, 1.0f,
|
||||
};
|
||||
|
||||
|
||||
glGenVertexArrays(1, &textvao);
|
||||
glGenBuffers(1, &textvbo);
|
||||
glBindVertexArray(textvao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, textvbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
#version 330 core
|
||||
layout (location = 0) in vec4 vertex; // <vec2 pos, vec2 tex>
|
||||
layout (location = 0) in vec2 vertex; // <vec2 pos>
|
||||
out vec2 texuv;
|
||||
|
||||
uniform mat4 transform;
|
||||
uniform mat4 projection;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = projection * vec4(vertex.xy, 0.0, 1.0);
|
||||
texuv = vertex.zw;
|
||||
gl_Position = projection * transform * vec4(vertex.xy, 0.0, 1.0);
|
||||
texuv = vertex.xy;
|
||||
texuv.y=1.0f-texuv.y;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue