# RenderTexture Overhaul Design Document ## Overview This document outlines the design for implementing RenderTexture support across all UIDrawable classes in McRogueFace. This is Issue #6 and represents a major architectural change to the rendering system. ## Goals 1. **Automatic Clipping**: Children rendered outside parent bounds should be clipped 2. **Off-screen Rendering**: Enable post-processing effects and complex compositing 3. **Performance**: Cache static content, only re-render when changed 4. **Backward Compatibility**: Existing code should continue to work ## Current State ### Classes Already Using RenderTexture: - **UIGrid**: Uses a 1920x1080 RenderTexture for compositing grid view - **SceneTransition**: Uses two 1024x768 RenderTextures for transitions - **HeadlessRenderer**: Uses RenderTexture for headless mode ### Classes Using Direct Rendering: - **UIFrame**: Renders box and children directly - **UICaption**: Renders text directly - **UISprite**: Renders sprite directly ## Design Decisions ### 1. Opt-in Architecture Not all UIDrawables need RenderTextures. We'll use an opt-in approach: ```cpp class UIDrawable { protected: // RenderTexture support (opt-in) std::unique_ptr render_texture; sf::Sprite render_sprite; bool use_render_texture = false; bool render_dirty = true; // Enable RenderTexture for this drawable void enableRenderTexture(unsigned int width, unsigned int height); void updateRenderTexture(); }; ``` ### 2. When to Use RenderTexture RenderTextures will be enabled for: 1. **UIFrame with clipping enabled** (new property: `clip_children = true`) 2. **UIDrawables with effects** (future: shaders, blend modes) 3. **Complex composites** (many children that rarely change) ### 3. Render Flow ``` Standard Flow: render() → render directly to target RenderTexture Flow: render() → if dirty → clear RT → render to RT → dirty = false → draw RT sprite to target ``` ### 4. Dirty Flag Management Mark as dirty when: - Properties change (position, size, color, etc.) - Children added/removed - Child marked as dirty (propagate up) - Animation frame ### 5. Size Management RenderTexture size options: 1. **Fixed Size**: Set at creation (current UIGrid approach) 2. **Dynamic Size**: Match bounds, recreate on resize 3. **Pooled Sizes**: Use standard sizes from pool We'll use **Dynamic Size** with lazy creation. ## Implementation Plan ### Phase 1: Base Infrastructure (This PR) 1. Add RenderTexture members to UIDrawable 2. Add `enableRenderTexture()` method 3. Implement dirty flag system 4. Add `clip_children` property to UIFrame ### Phase 2: UIFrame Implementation 1. Update UIFrame::render() to use RenderTexture when clipping 2. Test with nested frames 3. Verify clipping works correctly ### Phase 3: Performance Optimization 1. Implement texture pooling 2. Add dirty flag propagation 3. Profile and optimize ### Phase 4: Extended Features 1. Blur/glow effects using RenderTexture 2. Viewport-based rendering (#8) 3. Screenshot improvements ## API Changes ### Python API: ```python # Enable clipping on frames frame.clip_children = True # New property # Future: effects frame.blur_amount = 5.0 sprite.glow_color = Color(255, 200, 100) ``` ### C++ API: ```cpp // Enable RenderTexture frame->enableRenderTexture(width, height); frame->setClipChildren(true); // Mark dirty frame->markDirty(); ``` ## Performance Considerations 1. **Memory**: Each RenderTexture uses GPU memory (width * height * 4 bytes) 2. **Creation Cost**: Creating RenderTextures is expensive, use pooling 3. **Clear Cost**: Clearing large RenderTextures each frame is costly 4. **Bandwidth**: Drawing to RenderTexture then to screen doubles bandwidth ## Migration Strategy 1. All existing code continues to work (direct rendering by default) 2. Gradually enable RenderTexture for specific use cases 3. Profile before/after to ensure performance gains 4. Document best practices ## Risks and Mitigation | Risk | Mitigation | |------|------------| | Performance regression | Opt-in design, profile extensively | | Memory usage increase | Texture pooling, size limits | | Complexity increase | Clear documentation, examples | | Integration issues | Extensive testing with SceneTransition | ## Success Criteria 1. ✓ Frames can clip children to bounds 2. ✓ No performance regression for direct rendering 3. ✓ Scene transitions continue to work 4. ✓ Memory usage is reasonable 5. ✓ API is intuitive and documented ## Future Extensions 1. **Shader Support** (#106): RenderTextures enable post-processing shaders 2. **Particle Systems** (#107): Render particles to texture for effects 3. **Caching**: Static UI elements cached in RenderTextures 4. **Resolution Independence**: RenderTextures for DPI scaling ## Conclusion This design provides a foundation for professional rendering capabilities while maintaining backward compatibility and performance. The opt-in approach allows gradual adoption and testing.