diff --git a/main.cpp b/main.cpp index a049880..36b71de 100644 --- a/main.cpp +++ b/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);