I have a basic (working) bitmap font renderer using C++/OpenGL in my program. I have a “Write” function which takes a const char*, and x/y pixel locations, and I ultimately end up with three things:
A vertex array of vec4f’s, where the XY of the vec4f are vertex coords in screen space, and the ZW are the UV coords. So one quad for one character is four vec4f’s.
An indices array of GLushorts.
A count (a short) of how many text characters there are to draw this frame.
All three things are refilled/recalculated every frame, because the text being displayed can potentially change every frame, since some changing numbers are displayed, such as frame rate. I should also mention that the arrays are fixed. They’re normal arrays with fixed sizes on the stack, which may be relevant to my question.
So my question is, am I doing the following OpenGL code in the best way? I realize this is considered premature optimization, but this is more about me wanting to ensure I’m doing things correctly in general. So, after the vertex/index arrays are filled (on CPU), this is my OpenGL code, which is running every frame:
// Bind VAO glBindVertexArray(_text_vao_id_hud); // Bind and set up VBO glBindBuffer(GL_ARRAY_BUFFER, _text_vbo_id_hud); glBufferData(GL_ARRAY_BUFFER, sizeof(VEC4F) * 4 * _text_character_count_hud, _text_character_vertices_hud, // This is a pointer (vertex array) GL_STATIC_DRAW); // Bind and set up EBO glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _text_ebo_id_hud); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * 6 * _text_character_count_hud, _text_character_indices_hud, // This is a pointer (indices array) GL_STATIC_DRAW); // Set up attrib array glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(VEC4F), (const GLvoid*)(0)); glEnableVertexAttribArray(0); // Bind shader program glUseProgram(myFontShader); // Sets the uniform (texture ID) glUniform1i(_GetShaderUniform(UniformType::UNIFORM_TEXTURE_0), 0); glActiveTexture(GL_TEXTURE0); // Disable depth, so it paints on top of everything else glDisable(GL_DEPTH_TEST); // Bind and draw VAO with DrawElements glBindVertexArray(_text_vao_id_hud); glBindTexture(GL_TEXTURE_2D, _font_texture_id); glDrawElements(GL_TRIANGLES, 6 * _text_character_count_hud, GL_UNSIGNED_SHORT, (const GLvoid*)(0)); glBindVertexArray(0); // Re-enable depth glEnable(GL_DEPTH_TEST); // Unbind shader program glUseProgram(0);
Something tells me I don’t have to do all of this every frame. For example, I was wondering, since the arrays are static, that perhaps there’s some way to allocate fixed chunks on the GPU for those vertex/index arrays, and therefore simply update them every frame, but not keep re-allocating them? (I’m just guessing here if this would be even possible, let alone wise.)
Thank you for any advice!