渲染完毕再渲染数据_跨平台渲染引擎之路:Urho3D分析与数据驱动

本文分析了Urho3D渲染引擎的主要流程,包括渲染主干、数据驱动和ECS设计模式。通过Hello World示例介绍了Urho3D的使用方式,并详细探讨了渲染过程中的各个关键接口。Urho3D采用数据驱动开发,其中ECS(实体-组件-系统)模式使得游戏开发更为高效,组件仅包含数据,系统负责处理逻辑。文章还对比了面向对象与数据驱动编程的区别,并提供了ECS的相关概念和实现示例。
摘要由CSDN通过智能技术生成

6b2a2884d7e2860b6863322d55669129.png

前言

前面我们分析了 bgfx 这个项目,从这个项目里面获得了许多我们不清楚和想了解的信息,而因为在初期阶段我们更多地是想要搭建出一个能够自由切换渲染后段的渲染引擎,而对于其他如粒子等诸多系统倒不是那么在意,因此对于Urho3D的分析就会更加简单化,只主要侧重在Urho3D的主要渲染流程上,以及一些在过程中接触到的零零散散的事项。

在这段时间里面有接触数据驱动,在目前的许多引擎中都是采用这种方式来进行开发的,因此会在本文中加入对数据驱动的一些内容。

Tips:该文章基于 Urho3D 的 1569ef3247999ba4304e991a1f510826a73268b7(SHA1值)提交进行分析

使用方式

我们以 Urho3D 的 Hello World 为例,简单介绍下该项目的使用方式:

URHO3D_DEFINE_APPLICATION_MAIN(HelloWorld)

HelloWorld::HelloWorld(Context* context) :
    Sample(context)
{
    
}

void HelloWorld::Start()
{
    
    // 执行基类的start()接口
    Sample::Start();

    // 创建"Hello World"文本效果
    CreateText();
    // 订阅更新事件,在这里才订阅其实已经丢失了一些事件了,比如 Graphics 子系统在开启程序窗口的时候会发送 ScreenMode 事件,如果想要订阅到这些事件,可以在构造函数的时候就进行订阅。
    SubscribeToEvents();

    // 在该Sample中开启鼠标模式
    Sample::InitMouseMode(MM_FREE);
}

void HelloWorld::CreateText()
{
    
    auto* cache = GetSubsystem<ResourceCache>();

    // 创建一个新的 Text 对象
    SharedPtr<Text> helloText(new Text(context_));

    // 设置 Text 的文本内容
    helloText->SetText("Hello World from Urho3D!");

    // 设置字体和文字颜色
    helloText->SetFont(cache->GetResource<Font>("Fonts/Anonymous Pro.ttf"), 30);
    helloText->SetColor(Color(0.0f, 1.0f, 0.0f));

    // 设置文字为居中模式
    helloText->SetHorizontalAlignment(HA_CENTER);
    helloText->SetVerticalAlignment(VA_CENTER);

    // 将 Text 实例添加在 UI 子系统中
    GetSubsystem<UI>()->GetRoot()->AddChild(helloText);
}

void HelloWorld::SubscribeToEvents()
{
    
    // 订阅更新事件,当有更新事件过来时通过 HandleUpdate() 接口处理
    SubscribeToEvent(E_UPDATE, URHO3D_HANDLER(HelloWorld, HandleUpdate));
}

void HelloWorld::HandleUpdate(StringHash eventType, VariantMap& eventData)
{
    
    // 目前接收到事件后暂不做任何事情
}

从官方提供的Sample我们可以看到首先所有的Sample都是集成自Sample这个基类的,而Urho3D会自动调用 Start() 接口,我们可以在接口里面做一些初始化、订阅事件的操作,比如订阅更新事件,在接收到事件的事件做动画、更新数值等等,而一些效果如视图(上例中的 Text)则都有定义对应的类和子系统来实现。

渲染主干

Urho3D提供了一个 Application 来控制程序的初始化、渲染等流程,在他所提供的Demo中通过 URHO3D_DEFINE_APPLICATION_MAIN 来传入Demo程序,并在 Application::Run() 函数中开始渲染循环。在 Application::Run() 中,当引擎未退出时,便会不断调用 engine_->RunFrame() 进行渲染操作,这便是Urho3D执行每次渲染操作的入口处。

首先我们带上 engine_->RunFrame() 的代码:

void Engine::RunFrame()
{
    
    assert(initialized_);

    // If not headless, and the graphics subsystem no longer has a window open, assume we should exit
    if (!headless_ && !GetSubsystem<Graphics>()->IsInitialized())
        exiting_ = true;

    if (exiting_)
        return;

    // Note: there is a minimal performance cost to looking up subsystems (uses a hashmap); if they would be looked up several
    // times per frame it would be better to cache the pointers
    auto* time = GetSubsystem<Time>();
    auto* input = GetSubsystem<Input>();
    auto* audio = GetSubsystem<Audio>();

#ifdef URHO3D_PROFILING
    if (EventProfiler::IsActive())
    {
    
        auto* eventProfiler = GetSubsystem<EventProfiler>();
        if (eventProfiler)
            eventProfiler->BeginFrame();
    }
#endif

    tim
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值