美文网首页Noesis Gui
教程18:渲染架构

教程18:渲染架构

作者: YottaYuan | 来源:发表于2020-03-14 05:32 被阅读0次

    渲染架构

    NoesisGUI渲染体系结构设计为具有两个并行工作的线程:线程和渲染线程。虽然,如后面所述,这不是严格强制的。您可以有更多线程,甚至根本没有线程。在任何情况下,我们的核心库都不会在后台创建线程。将此职责委托给负责从适当线程调用Noesis的客户端。

    RenderingTutorialImg1.jpg

    主线

    这是所有逻辑交互发生的线程。喜欢的东西的事件调度和布局处理都发生在这个线程。

    提供此功能的对象实现了IView接口。可以通过调用GUI :: CreateView()创建它。

    // Loads XAML and creates a view with it
    Ptr<FrameworkElement> xaml = Noesis::GUI::LoadXaml<FrameworkElement>("Button.xaml");
    Ptr<IView> view = Noesis::GUI::CreateView(xaml);
    
    // Sets logical size
    view->SetSize(width, height);
    

    IView实例不是线程安全的。所有交互都必须在创建它的同一线程中进行。

    // Send input events to view
    view->MouseButtonDown(x, y, button);
    view->MouseButtonUp(x, y, button);
    view->MouseDoubleClick(x, y, button);
    view->MouseMove(x, y);
    

    注意

    违反此线程安全性将被报告为错误

    每帧一次,必须选中视图实例以更新其内部表示。在此步骤中,当前状态被锁定并存储,以供下一部分中描述的渲染线程使用。

    // Updates view passing global time
    view->Update(time);
    

    请注意,尽管您只能与所有者线程中的视图进行交互,但是可以在单独的线程中创建多个视图。这样,您可以并行更新每个视图。尽管每个视图的开销都很低,但建议每个表面只有一个视图。在正常情况下,您将为主相机创建一个视图,并为所需的每个渲染纹理创建一个单独的视图,并在必要时重新使用它们。

    渲染线程

    这是通过RenderDevice抽象类直接与GPU交互的线程。由于Noesis不可知,因此提供一个RenderDevice实现是客户端代码的责任。该应用程序框架提供了许多参考实现。该RenderDevice也暴露了几个功能,以控制内部矢量图形创建的上下文。虽然默认值通常很好。

    Ptr<GLRenderDevice> device = *new GLRenderDevice();
    device->SetGlyphCacheWidth(1024);
    device->SetGlyphCacheHeight(1024);
    device->SetGlyphCacheMeshThreshold(48);
    

    创建设备后,您可以使用它初始化视图中托管的渲染器。渲染线程中与视图的所有交互都是通过IRenderer接口隔离的,您可以通过调用GetRenderer()获得该接口。

    view->GetRenderer()->Init(device);
    

    每次需要渲染新框架时,都必须调用UpdateRenderTree()从主线程收集挂起的更新命令。完成后,您可以同时进行屏幕外和屏幕渲染阶段。请注意,必须在绑定主表面之前完成屏幕外渲染,这对于平铺体系结构至关重要。

    // Applies last changes happened in view
    view->GetRenderer()->UpdateRenderTree();
    
    // Generates offscreen textures
    view->GetRenderer()->RenderOffscreen();
    
    // ------->
    // HERE: Insert code to render your 3D scene
    // <-------
    
    // Render UI in the active render target and viewport dimensions
    view->GetRenderer()->Render();
    

    请注意,只需使用同一设备初始化所有视图即可在同一渲染线程中管理多个视图。这样,您可以与所有视图共享内部纹理,例如渐变和字形。该RenderDevice是一个重量级的对象。应仔细创建此对象的其他实例。

    还要注意,根据设备的实现,您可以将UI渲染与渲染场景的其余部分并行化。例如,这可以通过使用延迟上下文在D3D11中实现。

    通常会有一个渲染线程。但是,如果您有兴趣与不同的渲染设备进行交互,则可以创建多个渲染线程。每个人都必须创建自己的RenderDevice实例。这些对象不是线程安全的,因此不能共享。按照此模式,每个渲染线程负责从一个或几个共享同一RenderDevice实例的视图中收集更新。

    相关文章

      网友评论

        本文标题:教程18:渲染架构

        本文链接:https://www.haomeiwen.com/subject/xlfkshtx.html