ScreenLockDetector/TEXT_RENDERING.md

186 lines
5.9 KiB
Markdown
Raw Normal View History

2025-11-10 20:00:34 +08:00
# 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
```cmake
# 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
- FreeType Documentation: https://freetype.org/freetype2/docs/
- Vulkan Text Rendering: https://learnopengl.com/In-Practice/Text-Rendering
- Font Atlas Generation: https://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_Text_Rendering_02