ScreenLockDetector/docs/TEXT_RENDERING.md

5.9 KiB

Text Rendering Implementation in VulkanWidget

Overview

This document describes the text rendering implementation added to the VulkanWidget using FreeType library.

Features Implemented

1. FreeType Integration

  • Library: Uses system libfreetype.a (found at /usr/local/lib/libfreetype.a)
  • Font Loading: Automatically searches common font paths:
    • /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf
    • /usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf
    • /usr/share/fonts/TTF/DejaVuSans.ttf
    • /System/Library/Fonts/Helvetica.ttc (macOS)
    • /usr/local/share/fonts/DejaVuSans.ttf

2. Font Atlas Generation

  • Size: 512x512 texture atlas
  • Character Range: ASCII 32-126 (95 printable characters)
  • Format: Single-channel R8_UNORM texture
  • Packing: Automatic row-based packing with 1-pixel padding
  • Storage: CharInfo map stores texture coordinates, size, bearing, and advance for each character

3. Text Rendering Pipeline

  • Shaders:
    • text.vert - Converts pixel coordinates to NDC
    • text.frag - Samples font atlas with alpha blending
  • Blending: Alpha blending enabled for smooth text rendering
  • Descriptors:
    • Binding 0: Uniform Buffer (time, resolution, rotation, wavePhase)
    • Binding 1: Font texture sampler

4. Text Content (Matching CustomWidget)

The text rendering displays the same information as CustomWidget:

Active State:

  • Title: "Screen Lock Detector - Painting Active" (top center, white, scale 0.8)
  • Statistics Box (top left, green, scale 0.6):
    • Frame Count
    • FPS: ~60
    • Rotation angle
    • Running Time
  • Lock Info Box (below stats, magenta, scale 0.65/0.5):
    • Last Lock Info title
    • Lock time
    • Duration
    • Frame count at lock
    • Total locks
  • Hint: "Lock your screen..." (bottom center, yellow, scale 0.65)

Locked State:

  • Title: "PAINTING DISABLED" (center, white, scale 1.2)
  • Subtitle: "(Screen Locked)" (center, gray, scale 0.9)
  • Stats: Total frames painted (bottom left, gray, scale 0.7)

Implementation Details

Code Structure

  1. VulkanRenderer::initializeTextRendering()

    • Initializes FreeType library
    • Loads font face
    • Generates character glyphs
    • Creates font texture atlas
    • Sets up Vulkan image, image view, and sampler
  2. VulkanRenderer::createTextPipeline()

    • Loads text vertex and fragment shaders
    • Sets up vertex input (position, color, texCoord)
    • Configures alpha blending
    • Creates descriptor set layout with texture sampler
    • Builds graphics pipeline
  3. VulkanRenderer::generateTextQuads()

    • Converts text string to quad vertices
    • Handles newlines
    • Uses pixel coordinates (shader converts to NDC)
    • Sets texture coordinates from CharInfo map
    • Applies scale and color
  4. VulkanRenderer::drawText()

    • Binds text pipeline
    • Binds descriptor sets (UBO + font texture)
    • Generates text quads based on painting state
    • Creates temporary vertex/index buffers
    • Issues draw calls

Coordinate System

  • Input: Pixel coordinates (0,0 = top-left, width,height = bottom-right)
  • Shader: Converts to NDC (-1,-1 = bottom-left, 1,1 = top-right)
  • Y-axis: Flipped in shader (Vulkan Y-down → traditional Y-up)

Resource Management

  • Font texture and sampler are persistent (created once)
  • Text vertex/index buffers are recreated each frame (using static variables)
  • Old buffers are destroyed before creating new ones
  • Descriptor sets are updated after text rendering initialization

CMake Configuration

# FreeType support (for text rendering in Vulkan)
find_package(Freetype)
if(FREETYPE_FOUND)
    target_include_directories(${PROJECT_NAME} PRIVATE ${FREETYPE_INCLUDE_DIRS})
    target_link_libraries(${PROJECT_NAME} ${FREETYPE_LIBRARIES})
    target_compile_definitions(${PROJECT_NAME} PRIVATE ENABLE_FREETYPE)
endif()

Debugging

Debug output is enabled every ~5 seconds (300 frames):

Initializing text rendering with FreeType...
Text rendering initialized successfully with 95 characters
Font texture: OK
Font texture view: OK
Font sampler: OK
Creating text pipeline...
Text pipeline created successfully
Updating descriptor sets with font texture...
Descriptor sets updated with font texture

drawText called: charMap=95 pipeline=OK fontTexView=OK
Drawing text with 572 vertices, 858 indices
Window size: 756x425
First vertex pos: (30.4, 1.2)
First vertex color: (1, 1, 1, 1)

Known Issues and Future Improvements

Current Limitations:

  1. Text buffers are recreated every frame (performance impact)
  2. No text caching or batching
  3. Limited to ASCII characters only
  4. Fixed font size (48pt base)

Potential Improvements:

  1. Implement text buffer caching for static text
  2. Add support for Unicode/UTF-8
  3. Multiple font sizes/styles
  4. Text layout system (word wrapping, alignment)
  5. Better memory management for text resources
  6. Dynamic font atlas resizing
  7. SDF (Signed Distance Field) rendering for scalable text

Testing

To verify text rendering:

  1. Build project: ./build.sh
  2. Run application: ./run.sh
  3. Check console for text rendering initialization messages
  4. Verify text appears on screen matching CustomWidget layout
  5. Lock screen to test state changes

Dependencies

  • FreeType 2.x
  • Vulkan 1.x
  • Volk (for Vulkan function loading)
  • Qt 5.15.x (for window management)

Files Modified

  • CMakeLists.txt - Added FreeType support
  • src/vulkanrenderer.h - Added text rendering declarations
  • src/vulkanrenderer.cpp - Implemented text rendering functions
  • shaders/text.vert - Text vertex shader
  • shaders/text.frag - Text fragment shader

References