Urho-笔记

@@@@@ Urho 积累

TODO:

  • [ ] Graphics
    • [ ] 3D 渲染
  • [ ] Navigation
    • [ ] 路径导航
  • [ ] Engine 引擎主系统
    • [ ] Initialize():初始化 Engine 子系统对象(也是一个 Object)
  • [ ] 2D 组件
  • [ ] 容器
    • [ ] 基于 AllocatorNode
    • [ ] 常用容器的内部实现,控制大小和编译速度
    • [ ] 可研究实现

上下文

协作图

/ob/%E3%80%901%E3%80%91%E5%B7%A5%E4%BD%9C%E5%8C%BA/%E8%AE%A1%E7%AE%97%E6%9C%BA/%E6%B8%B8%E6%88%8F%E5%BC%80%E5%8F%91%E6%8A%80%E6%9C%AF/%E6%B8%B8%E6%88%8F%E5%BC%95%E6%93%8E/Urho/attachments/class_urho3_d_1_1_engine__coll__graph_org.svg

Context

  • 对象管理
    • Object 类
      • 需要给定一个 context 指针
      • 定义:URHO3D_OBJECT(className, baseTypeName)
    • 注册工厂
      • RegisterFactory<MyClass>()
    • 创建对象
      • SharedPtr<Object> = ctx->CreateObject()
    • 序列化功能
  • 事件管理
    • 派生与 Object 的对象之间
    • 32b hash 标识,无需注册
    • URHO3D_HANDLER(className, function)
      • 包装事件处理函数
    • SubscribeToEvent(type, handler):订阅事件
      • 可以用 bind 灵活绑定使用
    • UnsubscribeFromEvent():取消订阅
    • SendEvent():发送事件
    • GetEventDataMap():获取事件数据
  • 线程

子系统管理

方法

  • RegisterSubsystem() :Object 可以注册为子系统
  • 可以 Get 获取
  • 子系统实例只能存在一个

内置子系统:

  • Time:管理帧更新、帧编号和经过的时间计数,并控制操作系统低分辨率计时器的频率。
  • WorkQueue:在工作线程中执行后台任务。
  • FileSystem:提供目录操作。
  • Log:提供日志服务。
  • ResourceCache:加载资源并缓存它们以供以后访问。
  • Network:提供 UDP 网络和场景复制。
  • Input:处理键盘和鼠标输入。在无头模式下将处于非活动状态。
  • UI:图形用户界面。在无头模式下将处于非活动状态。
  • Audio:提供声音输出。如果声音被禁用,则将处于非活动状态。
  • Engine:创建其他子系统并控制主循环迭代和帧速率限制。

可选:

  • Profiler:使用操作系统性能计数器提供分层功能执行时间测量。如果已编译分析则存在(可从根 CMakeLists.txt 进行配置)
  • EventProfiler:与 Profiler 相同,但用于事件。
  • Graphics:管理应用程序窗口、渲染上下文和资源。如果不处于无头模式则存在。
  • Renderer:渲染 3D 场景并管理渲染质量设置。如果不处于无头模式则存在。
  • Script:提供 AngelScript 执行环境。需要手动创建并注册。
  • Console:提供交互式 AngelScript 控制台和日志显示。通过调用 CreateConsole() 创建。
  • DebugHud:显示渲染模式信息以及统计和分析数据。CreateDebugHud() 创建。
  • Database:管理数据库连接。构建库时需要启用数据库支持的构建选项。

图形 Graphic

  • Technique:对应一个顶点和片段着色器
    • 含义是渲染技术,定义了一套调用 shader 的规则
    • pass:是 Technique 的一个渲染阶段(包含一次完整渲染流程,参考正反面 pass 多流程渲染一个效果)
      • 名称 name 是自定义的?,默认使用 Technique 的 vs 和 ps
      • 相当于 Technique 写了 Shader 在一个文件中,通过 pass 的定义调用不同逻辑,(可以宏定义,变量配置)
      • 当然也可以给 pass 设置特定的着色器
      • /ob/%E3%80%901%E3%80%91%E5%B7%A5%E4%BD%9C%E5%8C%BA/%E8%AE%A1%E7%AE%97%E6%9C%BA/%E6%B8%B8%E6%88%8F%E5%BC%80%E5%8F%91%E6%8A%80%E6%9C%AF/%E6%B8%B8%E6%88%8F%E5%BC%95%E6%93%8E/Urho/attachments/%E5%A4%9Apass%E6%B5%81%E7%A8%8B.png
      • Urho3D 的 pass 似乎定义在源码中?
        • 是否可以自定义 Pass 的 Technique?
  • Drawable:可绘制的基类,描述绘制方式

资源 Resource

一个三维场景需要各种资源文件才能构建,庞大的三维场景要做好资源管理,保证不会因为加载卡顿以及无法加载造成的显示错误

可以直接加载序列化的对象,如 Material,Technique 这些。
也就是说材质,渲染都可以定义在 xml 中,也能手动创建组合。

  • AutoloadPaths:可在引擎中配置,自动加载数据

ResourceCache

和 FS 模块协作,一个负责资源加载,一个负责管理

  • 管理资源文件的缓存类

场景 Scene

文档
Scene 继承 Node,做组件和节点的管理,相当于对节点的数据多做了一层解释,使之变得易用,包括组件和节点更新,异步加载等。

1
2
3
4
5
1.渲染 3D 对象、声音播放、物理和脚本逻辑更新都是通过调用 `CreateComponent()` 在节点中创建不同的 「组件」 来启用的。
2.需要注册组件的对象工厂
3.像Light、Camera或StaticModel这样的“普通”组件不应该直接创建到Scene中,而应该创建到子节点中。
4.Node 有名字,Component 没名字,只有类型的 hash 标识
5.Scene 不参与坐标计算,其相关方法无效
  • AsyncProgress 成员(异步处理):
    • 有 xml 和 json 的成员,以及一个资源的 HashMap
    • 控制场景的异步加载
  • SeceneResolver:
    • 节点和组件解析
    • 有两个成员,一个存 Nodes 一个存 Components
  • SetUpdateEnabled():参与主循环更新
  • SetEnabled():对于节点来说的启用禁用
  • SetTemporary():设置临时 Node,不会被场景保存
  • 场景序列化:
    • 把场景配置属性外置

身为 Node 的组件:

  • Octree
  • PhysicsWorld:刚体和碰撞形状需要的前置组件
  • DebugRenderer

协作图

/ob/%E3%80%901%E3%80%91%E5%B7%A5%E4%BD%9C%E5%8C%BA/%E8%AE%A1%E7%AE%97%E6%9C%BA/%E6%B8%B8%E6%88%8F%E5%BC%80%E5%8F%91%E6%8A%80%E6%9C%AF/%E6%B8%B8%E6%88%8F%E5%BC%95%E6%93%8E/Urho/attachments/class_urho3_d_1_1_node__coll__graph_org.svg

Node

继承:

  • Serializable
    • 序列化功能
  • Animatable:类图
    • 可动画的一些属性(字符串自定义)
      • 比如速度、方向等
        实现:
  • 旋转
    • 四元数
  • 缩放
    • vec3
  • 平移(一个仿射矩阵)
    • Matrix 3*4
  • 组件管理
    • 监听组件列表
    • 组件列表
  • 子 Node 列表

Component

继承:

  • Serializable
  • Animatable/ob/%E3%80%901%E3%80%91%E5%B7%A5%E4%BD%9C%E5%8C%BA/%E8%AE%A1%E7%AE%97%E6%9C%BA/%E6%B8%B8%E6%88%8F%E5%BC%80%E5%8F%91%E6%8A%80%E6%9C%AF/%E6%B8%B8%E6%88%8F%E5%BC%95%E6%93%8E/Urho/attachments/Pasted%20image%2020231127154517.png
    /ob/%E3%80%901%E3%80%91%E5%B7%A5%E4%BD%9C%E5%8C%BA/%E8%AE%A1%E7%AE%97%E6%9C%BA/%E6%B8%B8%E6%88%8F%E5%BC%80%E5%8F%91%E6%8A%80%E6%9C%AF/%E6%B8%B8%E6%88%8F%E5%BC%95%E6%93%8E/Urho/attachments/Pasted%20image%2020231127154517.png
    实现:
  • 包含于 Scene/Node 中
  • 无节点相关逻辑
  • 和绘制相关,子类有一个 Drawable,要放到八叉树中

/ob/%E3%80%901%E3%80%91%E5%B7%A5%E4%BD%9C%E5%8C%BA/%E8%AE%A1%E7%AE%97%E6%9C%BA/%E6%B8%B8%E6%88%8F%E5%BC%80%E5%8F%91%E6%8A%80%E6%9C%AF/%E6%B8%B8%E6%88%8F%E5%BC%95%E6%93%8E/Urho/attachments/Pasted%20image%2020231127154541.png

绘制

1
2
SourceBatch在它的成员geometry_中保存顶点数据。Drawable的成员batches_是一组SourceBatch实例。
Renderer持有一组Viewport/View实例,并将主要的渲染工作委托给View。
  • 调用 View::Update() 收集 Drawable 及其包含的顶点数据。
    • 所以说 Drawable 中只包含顶点数据(SourceBatch)的管理,没有具体渲染逻辑
    • 最终渲染是在 View 上的 Update 中。遍历 Drawable 然后遍历内部的 Batches (SourceBatch)

/ob/%E3%80%901%E3%80%91%E5%B7%A5%E4%BD%9C%E5%8C%BA/%E8%AE%A1%E7%AE%97%E6%9C%BA/%E6%B8%B8%E6%88%8F%E5%BC%80%E5%8F%91%E6%8A%80%E6%9C%AF/%E6%B8%B8%E6%88%8F%E5%BC%95%E6%93%8E/Urho/attachments/Pasted%20image%2020231128175556.png

输入 Input

直接继承 Object,是一个子系统

  • 轮询

  • 事件订阅发布

  • 鼠标,控制器,触摸,键盘等

    • 有相关方法进行控制
  • 包括窗口状态,焦点等

    • 窗口考虑到移动设备场景(无窗口最小化概念,最小化可能不能操作图形资源)

引擎 Engine

应用框架 Application

  • 封装带有主循环的最小框架

主要虚函数:

  • Setup()
  • Start()
  • Stop()

程序入口点宏:URHO3D_DEFINE_APPLICATION_MAIN(MyApplication)

主循环

相关函数

  • RunFrame ():循环帧(参考:文档
    • 该函数依次调用 Time 子系统的 BeginFrame() 和 EndFrame() 函数,并在其间发送各种更新事件
    • 事件顺序:
      • E_BEGINFRAME
      • E_UPDATE
      • E_POSTUPDATE
      • E_RENDERUPDATE
      • E_POSTENDERUPDATE
      • E_ENDFRAME
    • 场景可监听事件:
      • E_SCENEUPDATE
      • E_SCENESUBSYSTEMUPDATE
      • E_PHYSICSPRESTEP
      • E_PHYSICSPOSTSTEP
      • E_SMOOTHINGUPDATE
      • E_SCENEPOSTUPDATE
  • 有一些 FPS 的和时间相关的 Get/Set 方法
    • SetMaxInactiveFPS():失去焦点时的 FPS 控制
      • 激活状态由 Input 子系统得到
  • Exit():退出渲染
  • ApplyFrameLimit ():sleep 方式控制渲染帧同步
  • 还有一些 Dump 的方法

参数配置:

(在 engineParameters_ 配置,HashMap 宏定义在 Engine/EngineDefs.h 中)

  • Headless (bool) 无头模式启用。默认为 false。
  • LogLevel (int) 日志详细级别。发布版本中默认 LOG_INFO,调试版本中默认 LOG_DEBUG。
  • LogQuiet (bool) 日志安静模式,即。不将警告/信息/调试日志条目写入标准输出。默认为 false。
  • LogName(字符串)日志文件名。默认“Urho3D.log”。
  • FrameLimiter (bool) 是否将最大帧速率限制为 200(桌面)或 60(Android/iOS/tvOS)。默认为真。
  • WorkerThreads (bool) 是否根据可用 CPU 核心为 WorkQueue 子系统创建工作线程。默认为真。
  • EventProfiler (bool) 是否创建 EventProfiler 子系统。默认为真。
  • ResourcePrefixPaths(字符串)要使用的资源前缀路径的分号分隔列表。如果未指定,则默认前缀路径设置为可执行路径。资源前缀路径也可以使用 URHO3D_PREFIX_PATH env-var 定义。当两者都定义时,-pp 设置的路径具有更高的优先级。
  • ResourcePaths(字符串)要使用的以分号分隔的资源路径列表。如果存在相应的包(即数据目录的 Data.pak),则将使用它们。默认“数据;核心数据”。
  • ResourcePackages(字符串)要使用的资源包的分号分隔列表。默认为空。
  • AutoloadPaths(字符串)要使用的以分号分隔的自动加载路径列表。自动加载路径内的任何资源包和子目录都将添加到资源系统中。默认“自动加载”。
  • ExternalWindow (void ptr) 使用外部窗口句柄而不是创建应用程序窗口。默认为空。
  • WindowIcon(字符串)窗口图标图像资源名称。默认为空(使用应用程序默认图标。)
  • WindowTitle(字符串)窗口标题。默认“Urho3D”。
  • WindowWidth (int) 窗口水平尺寸。默认 0(使用桌面分辨率,或在窗口模式下使用 1024。)
  • WindowHeight (int) 窗口垂直尺寸。默认 0(使用桌面分辨率,或窗口模式下的 768。)
  • WindowPositionX (int) 窗口水平位置。默认以屏幕为中心。
  • WindowPositionY (int) 窗口垂直位置。默认以屏幕为中心。
  • FullScreen (bool) 是否创建全屏窗口。默认为真。
  • Borderless (bool) 是否将窗口创建为无边框。默认为 false。
  • WindowRessized (bool) 窗口是否可调整大小。默认为 false。
  • HighDPI (bool) 窗口是否为高 DPI。默认为真。目前仅受 Apple 平台(macOS、iOS 和 tvOS)支持。
  • TripleBuffer (bool) 是否使用三重缓冲。默认为 false。
  • VSync (bool) 呈现渲染窗口内容时是否等待垂直同步。默认为 false。
  • FlushGPU (bool) 是否刷新每个帧的 GPU 命令缓冲区 (Direct3D9) 或限制缓冲帧的数量 (Direct3D11) 以减少输入延迟。对 OpenGL 无效。默认为 false。
  • ForceGL2 (bool) 当为 true 时,即使 OpenGL 3 可用,也会强制使用 OpenGL 2。对 Direct3D 或移动版本没有影响。默认为 false。
  • Multisample (int) 硬件多重采样级别。默认 1(无多重采样。)
  • 方向(字符串)以空格分隔的允许方向列表。仅在 iOS 上有效。所有可能的值为“LandscapeLeft”、“LandscapeRight”、“Portrait”和“PortraitUpsideDown”。默认“横向左横向右”。
  • Monitor (int) 要使用的监视器编号。0 是默认(主)监视器。
  • RefreshRate (int) 要使用的监视器刷新率(以 Hz 为单位)。
  • DumpShaders(字符串)转储使用的着色器变体以进行预缓存的文件名。
  • RenderPath(字符串)默认渲染路径资源名称。默认为空,这会导致使用前向渲染 (bin/CoreData/RenderPaths/Forward.xml)。
  • Shadows (bool) 启用阴影渲染。默认为真。
  • LowQualityShadows (bool) 低质量(1 个样本)阴影模式。默认为 false。
  • MaterialQuality (int) 材料质量级别。默认 2(高)
  • TextureQuality (int) 纹理质量级别。默认 2(高)
  • TextureFilterMode (int) 纹理默认过滤模式。默认 2(三线性)
  • TextureAnisotropy (int) 纹理各向异性级别。默认值 4。这仅对各向异性过滤纹理有效。
  • 声音(布尔)声音启用。默认为真。
  • SoundBuffer (int) 声音缓冲区长度(以毫秒为单位)。默认 100。
  • SoundMixRate (int) 声音输出频率(以 Hz 为单位)。默认 44100。
  • SoundStereo (bool) 立体声输出模式。默认为真。
  • SoundInterpolation (bool) 插值声音输出模式以提高质量。默认为真。
  • TouchEmulation (bool) 桌面平台上的触摸模拟。默认为 false。
  • ShaderCacheDir(字符串)Direct3D 的着色器二进制缓存目录。用户应用程序首选项目录中的默认“urho3d/shadercache”。
  • PackageCacheDir(字符串)网络子系统的包缓存目录。默认情况下不指定。

第三方库

  • [ ] LZ4:压缩包
  • [ ] pugixml
  • [ ] SDL
  • [ ] stb_image

注意事项

  • 在类的公共 API 中,尽可能使用原始指针
  • set 的共享指针需要 setNULL 才能释放引用

@@@@@ 远处物体

相机的 FarClip 距离会控制相机的裁剪,让物体消失

@@@@@ 编译

vs2015 编译需要用 1.7.1 版本以下的

  • SDL 需要源码中的头文件
  • 链接需要以下库
    • opengl32.lib
    • opengl32.lib
    • winmm.lib
    • mincore.lib
    • Version.lib
    • Imm32.lib

@@@@@ 引擎循环

可以从 Application 中拆出主循环的流程,放到另外一共循环中去使用

  • 上下文创建和初始化
  • 引擎创建和初始化
    • 配置外置窗口(EP_EXTERNAL_WINDOW),设置外部窗口句柄
  • 定时器触发引擎渲染帧
  • 获取 timesteps

除了循环本体需要考虑还要考虑界面大小变化设置 SDL 的窗口大小

@@@@@ Shader 渲染

对于自定义 uniform 变量名称,在末尾加上整整形序号(0 开始)