Sample vulkan text render. By using the stb_truetype.h.
Simple hello world center of the screen.
- cores folder should be place with liblibretro_vulkan.dll.
- system folder place font there.
- stb_truetype typically returns quads with Y coordinates increasing upward while Vulkan’s viewport has Y increasing downward. This can cause the text to appear upside-down.
- In init_text_vertex_buffer, modify the vertex position calculations to normalize the coordinates or map them to screen space. Since the orthographic projection already maps (0,0) to the top-left and (width,height) to the bottom-right, we can keep the positions in pixel space but adjust the centering logic.
- The vertex positions from stbtt_GetBakedQuad are in pixel coordinates relative to the font atlas. To work with Vulkan’s orthographic projection, normalize these coordinates to the range [0, 1] or map them directly to screen space.
The scale factor in init_text_vertex_buffer should account for the font size relative to the screen resolution. Instead of a fixed scale = 1.0f, calculate it based on the font size and atlas dimensions, and adjust it to fit the screen.
float scale = FONT_SIZE / ATLAS_HEIGHT; // Base scale relative to atlas
// Adjust scale to fit within screen dimensions
scale *= (float)height / FONT_SIZE; // Scale to match screen height
This ensures the text size is proportional to the screen height. You can further adjust the scale to make the text larger or smaller as needed.
float text_width = max_x - min_x;
float text_height = max_y - min_y;
float start_x = (width - text_width * scale) * 0.5f; // Center horizontally
float start_y = (height - text_height * scale) * 0.5f; // Center vertically
vertices[vtx_count + 0].pos[1] = (q.y0 * scale - start_y); // Flip Y
vertices[vtx_count + 1].pos[1] = (q.y0 * scale - start_y);
vertices[vtx_count + 2].pos[1] = (q.y1 * scale - start_y);
vertices[vtx_count + 3].pos[1] = (q.y1 * scale - start_y);
Alternatively, flip the texture coordinates in the vertex shader or adjust the atlas during initialization. To flip the texture vertically, modify the t0 and t1 coordinates:
vertices[vtx_count + 0].tex[1] = 1.0f - q.t0; // Flip t0
vertices[vtx_count + 1].tex[1] = 1.0f - q.t0;
vertices[vtx_count + 2].tex[1] = 1.0f - q.t1;
vertices[vtx_count + 3].tex[1] = 1.0f - q.t1;
The update_ubo function creates an orthographic projection matrix using glm_ortho. Ensure it correctly maps the vertex positions to the screen. The current setup (0.0f, (float)width, (float)height, 0.0f, -1.0f, 1.0f) is correct for Vulkan’s coordinate system, but verify that the vertex positions are in the expected range.
#version 310 es
precision mediump float;
layout(location = 0) in vec4 vColor;
layout(location = 1) in vec2 vTexCoord;
layout(location = 0) out vec4 FragColor;
layout(set = 0, binding = 1) uniform sampler2D FontTexture;
void main() {
//float alpha = texture(FontTexture, vTexCoord).r;
//FragColor = vec4(vColor.rgb, vColor.a * alpha);
FragColor = vec4(1.0, 0.0, 0.0, 1.0); // Red for debugging
}If red quads appear centered on the screen, the vertex positions are correct, and the issue lies in the texture sampling or atlas.
The provided reference (https://dev.to/shreyaspranav/how-to-render-truetype-fonts-in-opengl-using-stbtruetypeh-1p5k) suggests the following for OpenGL, which we can adapt for Vulkan:
- Orthographic Projection: Use an orthographic projection to map pixel coordinates to screen space, which is already implemented.
- Text Centering: Calculate the text bounding box and offset the quads to center them, which is partially implemented but needs the scaling and Y-flip fixes.
- Texture Atlas: Ensure the atlas is correctly uploaded and sampled, which appears correct but needs verification.
- Blending: The Vulkan pipeline already enables blending with VK_BLEND_FACTOR_SRC_ALPHA, which is consistent with the reference.