# 统一渲染架构快速入门 ## 概述 本项目采用统一的渲染架构设计,通过抽象基类 `RenderWidgetBase` 实现对 Vulkan 和 QPainter 两种渲染方式的统一管理。 ## 核心设计 ### 三层架构 ``` ┌─────────────────────────────────────┐ │ MainWindow │ ← 使用统一接口 │ (RenderWidgetBase* m_renderWidget) │ └──────────────┬──────────────────────┘ │ ↓ ┌─────────────────────────────────────┐ │ RenderWidgetBase (基类) │ ← 定义统一接口 │ - initializeRenderer() │ │ - setRenderingEnabled() │ │ - getRenderFrameCount() │ │ - getRendererType() │ └──────────────┬──────────────────────┘ │ ┌───────┴────────┐ ↓ ↓ ┌─────────────┐ ┌─────────────┐ │VulkanWidget │ │CustomWidget │ ← 具体实现 │ (Vulkan) │ │ (QPainter) │ └─────────────┘ └─────────────┘ ``` ## 编译选项 ### 使用 Vulkan(默认,如果可用) ```bash cd ScreenLockDetector mkdir -p build && cd build cmake .. -DENABLE_VULKAN=ON make -j4 ``` **结果**:应用将使用 VulkanWidget 进行硬件加速渲染 ### 使用 QPainter(后备方案) ```bash cd ScreenLockDetector mkdir -p build && cd build cmake .. -DENABLE_VULKAN=OFF make -j4 ``` **结果**:应用将使用 CustomWidget 进行 CPU 绘制 ### 自动回退 如果 Vulkan 头文件不可用,CMake 会自动回退到 QPainter: ```bash cmake .. # 输出:Vulkan headers not found, disabling Vulkan support ``` ## 主要改进 ### 之前的设计问题 ```cpp // ❌ 旧设计:需要维护两个独立的组件 private: CustomWidget *m_customWidget; #ifdef ENABLE_VULKAN_WIDGET VulkanWidget *m_vulkanWidget; #endif QTabWidget *m_tabWidget; // 使用 Tab 切换 ``` ### 新的统一设计 ```cpp // ✅ 新设计:单一组件指针 private: RenderWidgetBase *m_renderWidget; // 统一接口 // 构造函数中根据编译选项创建 #ifdef ENABLE_VULKAN_WIDGET m_renderWidget = new VulkanWidget(this); #else m_renderWidget = new CustomWidget(this); #endif ``` ## 统一接口使用示例 ### 1. 初始化渲染器 ```cpp // 对于 VulkanWidget:内部调用 initializeVulkan() // 对于 CustomWidget:直接返回 true(无需初始化) bool success = m_renderWidget->initializeRenderer(); if (!success) { qDebug() << "Error:" << m_renderWidget->getLastError(); } ``` ### 2. 控制渲染 ```cpp // 启用渲染(适用于任何渲染器) m_renderWidget->setRenderingEnabled(true); // 禁用渲染(适用于任何渲染器) m_renderWidget->setRenderingEnabled(false); // 查询状态 bool isRendering = m_renderWidget->isRenderingEnabled(); ``` ### 3. 获取状态信息 ```cpp // 获取渲染器类型 QString type = m_renderWidget->getRendererType(); // 返回 "Vulkan" 或 "QPainter" // 获取帧数统计 int frames = m_renderWidget->getRenderFrameCount(); // 检查初始化状态 bool initialized = m_renderWidget->isInitialized(); ``` ### 4. 错误处理 ```cpp if (!m_renderWidget->isInitialized()) { if (!m_renderWidget->initializeRenderer()) { QMessageBox::warning( this, "初始化失败", m_renderWidget->getLastError() ); } } ``` ## 锁屏检测集成 无论使用哪种渲染器,锁屏检测的处理逻辑完全一致: ```cpp void MainWindow::onLockStateChanged(bool locked) { // 统一的处理逻辑 if (m_renderWidget) { m_renderWidget->setRenderingEnabled(!locked); } updateStatusDisplay(); updateButtonStates(); } ``` ## 添加新渲染器 假设要添加 OpenGL 支持: ### 1. 创建新类 ```cpp // src/openglwidget.h class OpenGLWidget : public RenderWidgetBase { Q_OBJECT public: explicit OpenGLWidget(QWidget *parent = nullptr); // 实现所有虚函数 bool initializeRenderer() override; void setRenderingEnabled(bool enabled) override; bool isRenderingEnabled() const override; int getRenderFrameCount() const override; void resetFrameCount() override; bool isInitialized() const override; QString getLastError() const override; QString getRendererType() const override { return "OpenGL"; } }; ``` ### 2. 修改 CMakeLists.txt ```cmake option(ENABLE_OPENGL "Enable OpenGL support" OFF) if(ENABLE_OPENGL) list(APPEND SOURCES src/openglwidget.cpp) list(APPEND HEADERS src/openglwidget.h) add_definitions(-DENABLE_OPENGL_WIDGET) endif() ``` ### 3. 修改 MainWindow 构造函数 ```cpp #ifdef ENABLE_VULKAN_WIDGET m_renderWidget = new VulkanWidget(this); #elif defined(ENABLE_OPENGL_WIDGET) m_renderWidget = new OpenGLWidget(this); #else m_renderWidget = new CustomWidget(this); #endif ``` ## 运行效果 ### Vulkan 模式 ``` ┌──────────────────────────────────────┐ │ Qt Screen Lock Detection Demo │ ├──────────────────────────────────────┤ │ │ │ [Vulkan 硬件加速渲染窗口] │ │ (旋转的彩色圆圈动画) │ │ │ ├──────────────────────────────────────┤ │ [ Enable Rendering ] │ │ [ Disable Rendering ] │ │ [ Reset Frame Count ] │ ├──────────────────────────────────────┤ │ Renderer Type: Vulkan │ │ Detector Status: Active │ │ Renderer Status: ✓ Initialized │ │ Screen Lock Status: 🔓 UNLOCKED │ │ Rendering Status: ✓ ENABLED │ │ Frame Count: 1234 frames │ └──────────────────────────────────────┘ ``` ### QPainter 模式 ``` ┌──────────────────────────────────────┐ │ Qt Screen Lock Detection Demo │ ├──────────────────────────────────────┤ │ │ │ [QPainter 2D 渲染窗口] │ │ (旋转的彩色圆圈动画) │ │ │ ├──────────────────────────────────────┤ │ [ Enable Rendering ] │ │ [ Disable Rendering ] │ │ [ Reset Frame Count ] │ ├──────────────────────────────────────┤ │ Renderer Type: QPainter │ │ Detector Status: Active │ │ Renderer Status: ✓ Initialized │ │ Screen Lock Status: 🔓 UNLOCKED │ │ Rendering Status: ✓ ENABLED │ │ Frame Count: 1234 frames │ └──────────────────────────────────────┘ ``` ## 优势总结 ### ✅ 代码简化 - MainWindow 代码减少约 40% - 消除了大量重复的控制逻辑 - 减少了条件编译代码 ### ✅ 统一界面 - 不再使用 Tab 切换 - 单一、简洁的用户界面 - 自动选择最佳渲染方式 ### ✅ 易于维护 - 添加新功能只需修改基类接口 - 所有实现类自动继承新接口 - 更容易追踪和修复 bug ### ✅ 高可扩展性 - 可以轻松添加新的渲染后端 - 可以在运行时切换渲染器(未来功能) - 支持插件化架构(未来功能) ## 常见问题 ### Q: 如何知道当前使用的是哪种渲染器? A: 查看应用程序窗口的 "Renderer Type" 标签,或在日志中查看: ``` MainWindow initialized with Vulkan renderer ``` ### Q: Vulkan 初始化失败怎么办? A: 应用会自动显示错误信息。可以重新编译使用 QPainter: ```bash cmake .. -DENABLE_VULKAN=OFF make -j4 ``` ### Q: 两种渲染器性能差异大吗? A: - **Vulkan**: 硬件加速,GPU 渲染,CPU 占用低,适合复杂场景 - **QPainter**: CPU 渲染,CPU 占用较高,但兼容性最好 ### Q: 可以在运行时切换渲染器吗? A: 当前版本不支持,但架构设计已经为此功能预留了空间。 ## 相关文档 - [详细设计文档](./unified_rendering_design.md) - 完整的架构设计说明 - [API 参考](../src/renderwidgetbase.h) - RenderWidgetBase 接口定义 - [主 README](../README.md) - 项目总体说明 ## 贡献指南 如果您想添加新的渲染后端: 1. 创建新类继承 `RenderWidgetBase` 2. 实现所有虚函数 3. 在 CMakeLists.txt 中添加编译选项 4. 在 MainWindow 中添加创建逻辑 5. 编写测试用例 6. 更新文档 欢迎提交 Pull Request!