RGF(​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​Windows 渲染及应用开发框架)

介绍

RGF是一个Windows系统下基于Direct3D、Direct2D、DXGI、DirectWrite、WIC、GDI、GDIplus等技术开发的通用渲染框架。​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​RGF仓颉版(​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​后续简称”RGF”)基于RGF(​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​C/C++版)封装优化而来。​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​RGF为开发者提供轻量化、安全、高性能以及高度一致性的2D渲染能力,​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​并且提供对接Direct3D的相关接口,以满足开发者对3D画面渲染的需求。

RGF目前拥有两个渲染后端,​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​分别为Direct2D及GDI/GDI+。应用执行时可根据场景需求动态切换渲染后端,RGF将保证渲染结果的高度一致性。​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​需要注意的是,仅Direct2D后端支持与Direct3D互操作。

目前RGF仅开源RGF_CJ(​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​RGF仓颉编程语言)版本,可通过链接访问开源仓库。​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​

教程与案例

本项目长期维护,​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​关注 Bilibili UID:​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​3546853029185667,​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​观看视频教程与最新动态 !

RGF_UI可见仓库:​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​链接 RGF_UI

更多案例代码与课程代码详见:​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​链接 RGF_CJ_Example

项目特性

  • 高度一致性的跨技术渲染结果

RGF支持用户按需选择底层技术实现,​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​目前提供Direct2D和GDI/GDI+两种选择。当用户基于RGF框架完成开发后,可以无感切换到另一种底层技术实现中。RGF将会保障渲染结果的一致性。

  • 渲染目标高度兼容

RGF支持各类窗口类型,​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​包括但不限于:​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​普通窗口、弹出式窗口、分层窗口(​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​半透明)、异形窗口等。​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​并且RGF支持基于绑定式渲染表面将内容渲染到非客户区(NC)或任意支持HDC的设备(例如:打印机)。

  • 安全的使用机制

RGF采用生命周期的设计理念,​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​将相关对象的创建、使用、销毁规范管理,​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​力保开发者不会造成内存泄漏等问题。​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​RGF内置生命周期管理宏,可实现自动管理相关对象的释放。

  • 平台原生

RGF专注于Windows操作系统,​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​无跨平台相关的冗余兼容代码和性能浪费。

  • 线程安全

RGF核心渲染流程由C++侧原子操作保护,​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​确保在系统多线程以及仓颉用户态线程下始终安全渲染。​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​此外,锁机制带有超时保护,​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​当出现极端意外情况时自动释放锁,避免程序长时间卡死。

项目架构

RGF架构图

使用说明

编译构建

(​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​注‘ 本项目提供Build脚本进行自动化编译,编译结果自动置入Build文件夹中。使用自动化脚本前,请确保已经完整安装Cangjie编译环境,​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​并且正确配置环境变量)

  1. 选择并下载合适的 Release/Debug 版本库,​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​重命名为libRgf.dll后,​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​置入./libs/目录

  2. (​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​非必须)选择合适版本的静态库libuser32.alibimm32.a置入./libs/目录

  3. 确认cjpm.toml中的库路径配置与链接配置

    • 指定库路径:​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​-L ./libs
    • 链接静态库:​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​-l user32 -l imm32
    • 链接项目库:​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​-l:libRgf.dll
    • 指定子系统:​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​-subsystem windows

(​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​注‘ 若采用静态链接库,则至少应确保程序链接列举的所有库-l:libRgf.a -l stdc++ -l gcc -l user32 -l imm32 -l gdi32 -l ole32 -l gdiplus -l dwrite -l d3d10_1 -l dxgi -l d2d1 -l windowscodecs -l msimg32")

  1. 配置异常抛出语言 (​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​注’ 可跳过,默认英文)

    • 英文:​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​—cfg “RGF_LANG=en”
    • 中文:​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​—cfg “RGF_LANG=zh-cn”
  2. 编译

cjpm update
cjpm build

生命周期

RGF架构图

功能示例

注’ 详细使用示例请参考开源库中的开发者文档

RGF库的基础使用 功能示例

  1. 构建窗口环境,​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​获得RGF上下文

    示例代码如下:​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​

    // 1.引入RGF库
    import rgf.rgf_ui.*
    // 2.进入主方法
    rsMain(
        {context:RgfContext=>
            //3. 注册窗口类
            //4. 创建窗口
        },
        {context:RgfContext=>
            //5. 释放窗口 (可省略)
            //6. 注销窗口类
        }
    )
  2. 注册窗口类

    示例代码如下:​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​
    
注册窗口类部分的传参请参考 链接

    // 此变量置于rsMain函数之前的公共域内
    let winClass:RgfWinContext = RgfWinContext()
    // 此方法置入rsMain函数第一个Lambda中
    rwRegister(winClass,"窗口类名",context,/* 画刷 */,/* style */)
  3. 创建自己的窗口类

    示例代码如下:​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​
    
创建窗口部分的传参请参考 链接

    // 窗口类
    class example <: RgfBase {
        // 内部实现自己的逻辑
    }
    // 此变量置于rsMain函数之前的公共域内
    let winExample:example = example()
    // 将以下创建方法置入rsMain函数第一个Lambda中
    winExample.createWin(winClass,"窗口名",左边,顶边,宽度,高度,父窗口句柄,窗口扩展风格,窗口风格,
        context,substrate:RgfSubstrate.底层技术选择,layered:是否半透明
    )
  4. 释放资源

    程序执行结束后需要释放注册的资源,​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​示例代码如下:

    /* 
     * 此方法置入rsMain函数第二个Lambda中
     * 当主窗口释放时,窗口类实际已经释放。
     * 此处写出只是为了确保生命周期的完整性
     * 若需要确保窗口被释放或手动释放窗口,
     * 可以在必要时调用以下方法。
    */
    winExample.destroyWin();
    // 此方法置入rsMain函数第二个Lambda中
    rwUnregister(winClass)

约束与限制

Windows 7
(​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​仓颉运行时不支持)
Windows 8
(​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​仓颉运行时不支持)
Windows 10Windows 11
  • RGF不同库版本所兼容的运行环境略有差异,​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​具体差异如下:

    • D3D兼容版(​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​DX10)

    本版本最低支持
    Windows 7、带 SP2 的 Windows Vista 和适用于 Windows Vista 的平台更新 [桌面应用 |UWP 应用]
    
并且后续支持与Direct3D互操作

    • D3D兼容版(​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​DX11)

    本版本最低支持
    适用于 Windows 7 的Windows 8和平台更新 [桌面应用 |UWP 应用]
    
并且后续支持与Direct3D互操作

    • 非D3D兼容版(​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​D2D 1.​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​0)

    本版本最低支持
    Windows 7、带 SP2 的 Windows Vista 和适用于 Windows Vista 的平台更新 [桌面应用 |UWP 应用]

    • 非D3D兼容版(​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​D2D 1.1)

    本版本最低支持
    适用于 Windows 7 的Windows 8和平台更新 [桌面应用 |UWP 应用]

    • 屏蔽版本(​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​暂无实现计划)

    本版本最低支持
    Windows XP、Windows 2000 Professional [仅限桌面应用]
    
但本版本将会限制仅使用底层 GDI+ 技术,​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​并且剔除 DirectWrite 的文本渲染能力

(​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​注’ 以上各版本自身还区分启用并行加速和未启用并行加速、32位版本和64位版本)

联系方式

QQ群

参与贡献

欢迎大家提交PR、Issue,​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​欢迎大家参与任何形式的贡献。​‌‎​​‌‎​‌​‎‌‌​​‎​‌‌‌‎‌‌‌‌‌‎‌​‌‌‎‌​​‌‎​