Skip to main content

OpenGLGlyphTextRenderer.ixx File

OpenGL-based text renderer using FreeType glyph rendering. More...

Included Headers

#include <cassert> #include <ft2build.h> #include <glad/gl.h> #include <iostream> #include <memory> #include <ostream> #include <ranges> #include <string> #include <unordered_map> #include <vector> #include <helios.rendering.text.TextRenderCommand> #include <helios.rendering.shader.UniformValueMap> #include <helios.rendering.shader.UniformSemantics> #include <helios.ext.opengl.rendering.shader.OpenGLShader> #include <helios.rendering.text.Glyph> #include <helios.rendering.RenderPass> #include <helios.engine.core.data.FontId> #include <helios.ext.opengl.rendering.FreeTypeFontResourceManager> #include <helios.rendering.text.TextMesh> #include <helios.math> #include <helios.rendering.text.TextRenderer> #include <helios.rendering.text.FontResourceProvider>

Namespaces Index

namespacehelios
namespaceext

Platform-specific extensions and backend implementations. More...

namespaceopengl

OpenGL-specific implementations. More...

namespacerendering

OpenGL rendering implementations. More...

Classes Index

classOpenGLGlyphTextRenderer

Renders and manages text using OpenGL and FreeType. More...

Description

OpenGL-based text renderer using FreeType glyph rendering.

File Listing

The file content with the documentation metadata removed is:

1/**
2 * @file OpenGLGlyphTextRenderer.ixx
3 * @brief OpenGL-based text renderer using FreeType glyph rendering.
4 */
5module;
6
7#include <cassert>
8#include <ft2build.h>
9#include <glad/gl.h>
10#include <iostream>
11#include <memory>
12#include <ostream>
13#include <ranges>
14#include <string>
15#include <unordered_map>
16#include <vector>
17
18#include FT_FREETYPE_H
19
20export module helios.ext.opengl.rendering.OpenGLGlyphTextRenderer;
21
22import helios.rendering.text.FontResourceProvider;
23import helios.rendering.text.TextRenderer;
24import helios.rendering.text.TextMesh;
25import helios.rendering.text.Glyph;
26
27import helios.math;
28import helios.ext.opengl.rendering.shader.OpenGLShader;
29import helios.ext.opengl.rendering.FreeTypeFontResourceManager;
30
31
32import helios.rendering.shader.UniformSemantics;
33import helios.engine.core.data.FontId;
34import helios.rendering.text.TextRenderCommand;
35
36import helios.rendering.RenderPass;
37
38import helios.rendering.shader.UniformValueMap;
39
40export namespace helios::ext::opengl::rendering {
41
42 /**
43 * @brief Renders and manages text using OpenGL and FreeType.
44 *
45 * This class is responsible for rendering text using cached glyph textures and managing
46 * OpenGL resources for efficient rendering. It leverages FreeType to rasterize font glyphs
47 * and OpenGL to render them onto the screen. Text rendering is performed by positioning
48 * quads (one per character) with texture-mapped glyphs.
49 *
50 * The class provides methods for initializing OpenGL resources, loading fonts into a cache,
51 * and rendering text at specified positions and scales.
52 *
53 * Inherits from the TextRenderer class in the helios rendering system.
54 */
56
57
58
59 friend class OpenGLDevice;
60
61 /**
62 * @brief Initializes OpenGL resources (VAO and VBO) for text rendering.
63 *
64 * Creates a vertex array object and vertex buffer for rendering glyph quads.
65 * The VBO is configured for dynamic updates (one quad per character).
66 *
67 * Must be called before any rendering operations.
68 */
69 void init() {
70 glGenVertexArrays(1, &vao_);
71 glGenBuffers(1, &vbo_);
72 glBindVertexArray(vao_);
73 glBindBuffer(GL_ARRAY_BUFFER, vbo_);
74 // 2D quad for a texture requires 6 vertices with 4 floats each => 6*4
75 glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6*4, nullptr, GL_DYNAMIC_DRAW);
76 glEnableVertexAttribArray(0);
77 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
78 glBindBuffer(GL_ARRAY_BUFFER, 0);
79 glBindVertexArray(0);
80 }
81
82
83
84
85 /**
86 * @brief OpenGL Vertex Array Object for glyph rendering.
87 */
88 unsigned int vao_{};
89
90 /**
91 * @brief OpenGL Vertex Buffer Object for glyph quad vertices.
92 */
93 unsigned int vbo_{};
94
95 /**
96 * @brief Cached pointer to the last used shader for state optimization.
97 *
98 * Used to avoid redundant shader program activations. Reset at the beginning
99 * of each render pass.
100 */
101 mutable const helios::ext::opengl::rendering::shader::OpenGLShader* lastShader_ = nullptr;
102
103 /**
104 * @brief Cached texture ID for state optimization.
105 *
106 * Used to avoid redundant texture bindings.
107 */
108 mutable unsigned int lastTexture_ = 0;
109
110 /**
111 * @brief Cached VAO ID for state optimization.
112 *
113 * Used to avoid redundant VAO bindings. Reset at the beginning of each render pass.
114 */
115 mutable unsigned int lastVao_ = 0;
116
117 /**
118 * @brief Renders text at a specified position using a specified font and scale.
119 *
120 * This method uses OpenGL to render text, character by character, by updating vertex buffer
121 * objects (VBOs) and binding glyph textures. Each glyph is positioned relative to the given
122 * starting position, scaled according to the provided scale factor, and rendered using stored
123 * glyph information from a font cache.
124 *
125 * @param text The text string to render.
126 * @param position The starting (x, y) position for the text, in screen space coordinates.
127 * @param scale The scale factor to apply to the size of each glyph.
128 * @param fontId The font identifier used to select the font from the font cache.
129 */
130 void renderText(
131 const std::string_view text,
133 std::span<helios::math::vec4f> vertices,
135 ) noexcept {
136
137 glActiveTexture(GL_TEXTURE0);
138
139 if (vao_ != lastVao_) {
140 glBindVertexArray(vao_);
141 lastVao_ = vao_;
142 }
143
144 int offset = 0;
145 int stride = 6;
146 for (auto ch : text) {
147 auto vertex = vertices.subspan(offset, stride);
148 auto glyph = fontResourceProvider->glyph(ch, fontId);
149
150 // update the VBO for _each_ character (multiple drawcalls!)
151
152 // render glyph texture over quad
153 glBindTexture(GL_TEXTURE_2D, glyph.textureId);
154 // update content of vbo memory
155
156 glBindBuffer(GL_ARRAY_BUFFER, vbo_);
157
158 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(helios::math::vec4f) * stride, vertex.data());
159 glBindBuffer(GL_ARRAY_BUFFER, 0);
160 //render quad
161 glDrawArrays(GL_TRIANGLES, 0, 6);
162 // advance cursors for next glyph (1/64 pixels)
163
164 offset += stride;
165 }
166
167 }
168
169
170 /**
171 * @brief Resets cached rendering state at the beginning of a render pass.
172 *
173 * This ensures proper shader and VAO binding even when the render queue
174 * contents change between frames. Called internally by `OpenGLDevice` before
175 * processing the render queue.
176 *
177 * @param renderPass The render pass being started (currently unused, reserved for future use).
178 */
179 void beginRenderPass(helios::rendering::RenderPass& renderPass) const noexcept {
180 // Reset cached state at the beginning of each render pass
181 // to ensure proper shader and VAO binding even when render queue contents change
182 lastShader_ = nullptr;
183 lastVao_ = 0;
184 }
185
186 public:
187
188
189 /**
190 * @brief Destroys the OpenGLGlyphTextRenderer and releases all OpenGL resources.
191 *
192 * Cleans up the Vertex Array Object (VAO), Vertex Buffer Object (VBO),
193 * and all cached glyph textures for every loaded font.
194 *
195 * @note Must be called in a valid OpenGL context.
196 */
198
199 if (vao_ != 0) {
200 glDeleteVertexArrays(1, &vao_);
201 }
202 if (vbo_ != 0) {
203 glDeleteBuffers(1, &vbo_);
204 }
205
206 /**
207 *@todo glDeleteTextures()
208 */
209
210 glBindVertexArray(0);
211 glBindTexture(GL_TEXTURE_2D, 0);
212 }
213
214 /**
215 * @brief Returns the texture unit used for text rendering.
216 *
217 * @return The texture unit index (always 0).
218 */
219 static inline int textTextureUnit() {
220 return 0;
221 }
222
223 /**
224 * @brief Renders text using the specified render command.
225 *
226 * Processes the `TextRenderCommand`, activates the associated shader,
227 * applies uniform values, and renders the text string.
228 *
229 * @param command The render command containing text and rendering properties.
230 * @param frameUniformValues Frame-level uniforms (e.g., projection matrix).
231 *
232 * @note Requires a valid OpenGL context and initialized renderer.
233 */
234 void render(
236 const helios::rendering::shader::UniformValueMap& frameUniformValues) noexcept override {
237
238 if (auto* textPrototype = command.textRenderPrototype()) {
239 const auto& baseShader = textPrototype->shader();
240
241 const auto* shader = static_cast<const helios::ext::opengl::rendering::shader::OpenGLShader*>(&baseShader);
242 assert(shader && "Unexpected failure when casting to OpenGLShader.");
243
244 if (lastShader_ != shader) {
245 shader->use();
246 lastShader_ = shader;
247 }
248
249 shader->applyUniformValues(frameUniformValues);
250 shader->applyUniformValues(command.objectUniformValues());;
251 shader->applyUniformValues(command.materialUniformValues());;
252
253 const auto* textMesh = command.textMesh();
254
255 renderText(
256 textMesh->text(),
257 textMesh->fontId(),
258 textMesh->vertices(textPrototype->fontResourceProvider()),
259 &textPrototype->fontResourceProvider()
260 );
261 }
262
263 };
264
265
266
267
268 };
269}

Generated via doxygen2docusaurus 2.0.0 by Doxygen 1.15.0.