Prepare OpenGL text rendering state only once
Date: Sun Jan 7 17:55:38 2024 +0100
This commit is contained in:
parent
3b78739efd
commit
85195590aa
1 changed files with 57 additions and 23 deletions
80
main.cpp
80
main.cpp
|
|
@ -118,6 +118,7 @@ uint32_t hex_program;
|
|||
uint32_t texture_array;
|
||||
glm::mat4 transforms[ARRAY_LIMIT];
|
||||
int32_t letter_map[ARRAY_LIMIT];
|
||||
int32_t text_frame_idx;
|
||||
|
||||
|
||||
// error processing
|
||||
|
|
@ -240,27 +241,47 @@ uint32_t make_gl_program(const char *pathname_vertex, const char *pathname_fragm
|
|||
return program;
|
||||
}
|
||||
|
||||
void render_text(const char *text, float x, float y, float scale, glm::vec3 color)
|
||||
void render_queued_text(glm::vec3 color)
|
||||
{
|
||||
//glActiveTexture(GL_TEXTURE0);
|
||||
//glBindTexture(GL_TEXTURE_2D_ARRAY, texture_array);
|
||||
//glBindVertexArray(textvao);
|
||||
//glBindBuffer(GL_ARRAY_BUFFER, textvbo);
|
||||
|
||||
glUniform3f(glGetUniformLocation(text_program, "text_color"), color.x, color.y, color.z);
|
||||
glUniformMatrix4fv(glGetUniformLocation(text_program, "transforms"), text_frame_idx, GL_FALSE, &transforms[0][0][0]);
|
||||
glUniform1iv(glGetUniformLocation(text_program, "letter_map"), text_frame_idx, &letter_map[0]);
|
||||
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, text_frame_idx);
|
||||
|
||||
//glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
//glBindVertexArray(0);
|
||||
//glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
text_frame_idx = 0;
|
||||
}
|
||||
|
||||
void render_text(const char *text, float x, float y, float scale, glm::vec3 color, bool render_immediately)
|
||||
{
|
||||
// TODO: Group draw calls together instead of doing 1 draw call/character. Use an atlas with GL_TEXTURE_ARRAY
|
||||
// Take tips from https://www.youtube.com/watch?v=S0PyZKX4lyI
|
||||
scale *= 48.0f/256;
|
||||
|
||||
// activate corresponding render state
|
||||
glUseProgram(text_program);
|
||||
glUniform3f(glGetUniformLocation(text_program, "text_color"), color.x, color.y, color.z);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, texture_array);
|
||||
glBindVertexArray(textvao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, textvbo);
|
||||
|
||||
int idx = 0;
|
||||
//glUseProgram(text_program);
|
||||
//glActiveTexture(GL_TEXTURE0);
|
||||
//glBindTexture(GL_TEXTURE_2D_ARRAY, texture_array);
|
||||
//glBindVertexArray(textvao);
|
||||
//glBindBuffer(GL_ARRAY_BUFFER, textvbo);
|
||||
|
||||
// iterate through 128 ASCI characters
|
||||
for (const char *p = text; *p != '\0'; ++p)
|
||||
{
|
||||
// Avoid drawing more than 400 chars at a time
|
||||
if (idx == ARRAY_LIMIT - 1)
|
||||
break;
|
||||
// Avoid drawing more than ARRAY_LIMIT chars at a time
|
||||
if (text_frame_idx == ARRAY_LIMIT)
|
||||
{
|
||||
render_queued_text(color);
|
||||
}
|
||||
|
||||
char c = *p;
|
||||
charglyph_t charglyph = glyphmap[(size_t)c];
|
||||
|
|
@ -274,20 +295,21 @@ void render_text(const char *text, float x, float y, float scale, glm::vec3 colo
|
|||
float xpos = x + charglyph.bearing.x * scale;
|
||||
float ypos = y - (256 - charglyph.bearing.y) * scale;
|
||||
|
||||
transforms[idx] = glm::translate(glm::mat4(1.0f), glm::vec3(xpos, ypos, 0)) * glm::scale(glm::mat4(1.0f), glm::vec3(256 * scale, 256 * scale, 0));
|
||||
letter_map[idx] = charglyph.tex;
|
||||
transforms[text_frame_idx] = glm::translate(glm::mat4(1.0f), glm::vec3(xpos, ypos, 0)) * glm::scale(glm::mat4(1.0f), glm::vec3(256 * scale, 256 * scale, 0));
|
||||
letter_map[text_frame_idx] = charglyph.tex;
|
||||
|
||||
// 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)
|
||||
++idx;
|
||||
++text_frame_idx;
|
||||
}
|
||||
if (render_immediately)
|
||||
{
|
||||
render_queued_text(color);
|
||||
}
|
||||
glUniformMatrix4fv(glGetUniformLocation(text_program, "transforms"), idx, GL_FALSE, &transforms[0][0][0]);
|
||||
glUniform1iv(glGetUniformLocation(text_program, "letter_map"), idx, &letter_map[0]);
|
||||
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, idx);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
// glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
// glBindVertexArray(0);
|
||||
// glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
bool inside_hex(hex_t *hex, glm::vec2 point)
|
||||
|
|
@ -654,8 +676,15 @@ int main([[maybe_unused]]int argc, [[maybe_unused]]char **argv)
|
|||
static char debug_text_buf[256];
|
||||
{
|
||||
TIME_BLOCK(text_render);
|
||||
// Prepare GL state for text rendering
|
||||
glUseProgram(text_program);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, texture_array);
|
||||
glBindVertexArray(textvao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, textvbo);
|
||||
|
||||
stbsp_snprintf(debug_text_buf, 256, "Cursor position %.0f %.0f screen %.2f %.2f world", cursor_x, cursor_y, cursor_world.x, cursor_world.y);
|
||||
render_text(debug_text_buf, 25, 25, .5f, glm::vec3(1.0f, 1.0f, 1.0f));
|
||||
render_text(debug_text_buf, 25, 25, .5f, glm::vec3(1.0f, 1.0f, 1.0f), true);
|
||||
|
||||
for (int i = 0; show_hex_numbers && i < grid.rows * grid.columns; ++i)
|
||||
{
|
||||
|
|
@ -671,14 +700,19 @@ int main([[maybe_unused]]int argc, [[maybe_unused]]char **argv)
|
|||
continue;
|
||||
char number_string[11];
|
||||
stbsp_snprintf(number_string, 11, "%d", i);
|
||||
render_text(number_string, v.x, v.y, .2f + (0.3f / the_camera.size.x), glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
render_text(number_string, v.x, v.y, .2f + (0.3f / the_camera.size.x), glm::vec3(0.0f, 0.0f, 0.0f), false);
|
||||
}
|
||||
render_queued_text(glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
if (hovered_hex != -1)
|
||||
{
|
||||
char buf[30];
|
||||
stbsp_snprintf(buf, 30, "Cursor INSIDE hex %d", hovered_hex);
|
||||
render_text(buf, 25.0f, window_height - 25.0f, .5f, glm::vec3(1.0f, 1.0f, 1.0f));
|
||||
render_text(buf, 25.0f, window_height - 25.0f, .5f, glm::vec3(1.0f, 1.0f, 1.0f), true);
|
||||
}
|
||||
// Restore GL state
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue