理论教育 VegaPrime虚拟现实开发技术:构建最小应用程序

VegaPrime虚拟现实开发技术:构建最小应用程序

时间:2023-11-24 理论教育 版权反馈
【摘要】:从上一节导出的main 函数认识最小的Vega Prime应用程序。这个main 是Vega Prime 最基本的应用程序配置,如图4.3.2所示。图4.3.2Vega Prime 最小应用整个应用包含了配置Vega Prime应用的API,包括用来初始化、定义、配置和退出仿真循环的API 命令和类。Vega Prime的API 通过模板和继承性的使用使得仿真循环更加简洁而有效,实时控制包括装载ACF、配置ACF、应用运行和仿真循环、取消引用及最后退出VP 仿真循环。

VegaPrime虚拟现实开发技术:构建最小应用程序

从上一节导出的main 函数认识最小的Vega Prime应用程序。这个main 是Vega Prime 最基本的应用程序配置,如图4.3.2所示。

图4.3.2 Vega Prime 最小应用

整个应用包含了配置Vega Prime应用的API,包括用来初始化、定义、配置和退出仿真循环的API 命令和类。

基于STL(标准模板库)和C++的API 显得非常紧凑和灵活。Vega Prime的API 通过模板和继承性的使用使得仿真循环更加简洁而有效,实时控制包括装载ACF、配置ACF、应用运行和仿真循环、取消引用及最后退出VP 仿真循环。

1.初始化

vp::initialize 执行以下任务:

● 检查license 是否正确;

● 初始化静态变量(static variables)和单例类(singleton classes);

● 初始化内存分配(memory allocator);

● 初始化渲染库(rendering library);

● 初始化场景(scene graph);

● 初始化ACF 剖析程序(ACF parser);

● 初始化模块界面(module interface);

● 初始化内核(kernel classes)。

需要注意的是,在自己定制的应用中,ACF 中的模块不需要初始化。

vpModule::initializeModule 是告诉用户如何初始化自己的应用中所添加的模块。初始化所添加模块和用户定制模块需要使用以下句法:

//

//初始化所有模块

vpModule::initializeModule("vp");

vpModule::initializeModule("vpEnv");

vpModule::initializeModule("vpMotion");

vpModule::initializeModule("vpLADBM");

vpModule::initializeModule("vpFx");

vpModule::initializeModule("vpIR");

2.vpApp 类

vpApp 类用来定义一个典型的VP应用的框架。它在vpApp.h 中被定义了。所有子方法(member methods)都使用内联函数,使用者可以复制和修改vpApp 类。

vpApp的主体封装了Vega Prime应用中经常用到的vpKernel的功能,vpApp 类控制实时功能,包括定义ACF、配置仿真类、仿真循环、更新和退出。

vpApp *app=new vpApp;

从vpApp 类创建一个实例对象,这是虚拟仿真应用开始的最简单方法。如果对C++很熟悉,现在就可以轻松运用vpApp 了。

vpApp 类的所有成员都可以多次定制以满足应用的需求,用户可以通过继承vpApp 类来创建自己的类。

3.定义语句

定义语句可以替代ACF 执行功能,参数就是用字符串来替代ACF。与以往的Vega 不同的是,在Vega Prime 中,可以多次定制并且实时调用多个ACF。这个功能代替了Vega的vgScan 函数。

调入ACF 文件,假定argv[1]就是当前的ACF 文件:(www.daowen.com)

if (argv[1])

app->define(argv[1]);

函数原型为:

define(const char* filename);

virtual int vpApp::define(const char *filename);

描述——装载和解析ACF 文件。

自变量——filename 是所需ACF 文件的名称。这个值可以用一行语句来表示,也可以通过复杂的语句来表示。

4.配置

配置从ACF 中分解而来,同时将不同的类关联起来。例如,它将系统中定义的pipeline添加给服务管理器,并且为每个类配置相关的联系。config 功能是相互的,通过unconfig 可以将应用配置返回到config 前的状态。config 方法经常被用户反复运用。

配置示例:

app->configure();

5.仿真循环

仿真循环包括一个功能呼叫:

void vpApp::run()

run()执行主要的仿真循环,这个功能会持续呼叫beginFrame(),接下来是endFrame()用来结束循环。当然还可以在循环过程中用breakFrameLoop()来结束循环,接着这项功能会呼叫unconfigure()。

这种方法也经常被用户反复运用于自己定义的应用中。

6.仿真更新

更新kernel 发生在主循环的中间:

vpKernel::update()

这种方法在主循环的中间通过应用来调用,否则它会被vpKernel::endFrame()自动调用,这个过程发生在pKernel::processNonLatencyCritical 信息传递给kernel 之前,发生在仿真循环的non-latency-critical 阶段。

关于帧的准确位置有几点说明。所有仿真对象都由应用程序来定位,要么是通过使用vsTraversalUpdate 来自动更新,要么是通过代码来手动更新。因此,应用程序的仿真更新部分大概分为3 部分:

● Pre-update:包括仿真循环的代码和由vpKernel::EVENT_PRE_UPDATE_TRAVERSAL事件执行的代码。

● VSG 更新:VSG 场景更新由vpKernel::update 内部触发。

● Post-update:包括vpKernel::EVENT_POST_UPDATE_TRAVERSAL 事件执行的代码和主仿真循环中vpKernel::update 执行后的代码。

依赖于vsTraversalLocate 或者直接获取信息(如vsTransform)的位置查询是保持不变的,它们并不修改或更新场景。因此,通常来说位置查询可能产生不同的结果,这要看位置查询是在场景更新前还是更新后。如果在更新前执行,结果就会和预期的不同;如果在更新后执行,结果就会和预期的一致。因此,建议所有的位置查询都在仿真更新后执行。

7.关闭

退出Vega Prime。

vp::shutdown();

vp::shutdown 执行以下任务:

● 释放被kernel classes 分配的内存;

● 结束各模块以释放它们在应用中所占用的内存;

● 终止多线程;

● 将licenses 返回给license server。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈