2022版本终于来了,带红外模块哦
比较珍贵,一般人负担不起,建议单位购需要的个人建议购买2013
购买2022的私信交流
后面会更新vega prime2022及红外雷达模块的效果和使用情况
vega prime界面(2013)
简单介绍
· C++的强大功能非C所能及的
· VSG是高级跨平台场景图像应用程序接口,将取代Performer
· Vega是基于进程的,VP是基于线程的。线程和进程区别是:
1. 同样作为基本的执行单位,线程的划分比进程小.
2. 进程把内存空间作为自己的资源之一,每个进程均有自己的内存单元.线程却共享内存单元,通过共享的内存空间来交换信息,从而有利于提高执行效率.
·VP是跨平台的
·VEGA内核部分扩展
· 模块接口:VEGA通过C功能调用,而VP是通过模块类
·VP中ADF/ACF文件类型采用XML
XML是eXtensible Markup Language的缩写,意为可扩展的标记语言。XML是一套定义语义标记的规则,这些标记将文档分成许多部件并对这些部件加以标识。它不像超文本标记语言HTML(Hypertext Markup Language)或是格式化的程序。这些语言定义了一套固定的标记,用来描述一定数目的元素。XML是一种元标记语言,用户可以定义自己需要的标记。这些标记必须根据某些通用的原理来创建,XML标记描述的是文档的结构和意义,而不描述页面元素的格式化。可用样式单为文档增加格式化信息。文档本身只说明文档包括什么标记,而不是说明文档看起来是什么样的。
XML优点:⑴ XML遵循严格的语法要求。如果语法有丝毫差错,分析器都会停止对它的进一步处理,相应地,除了错误提示外,你看不到任何的显示信息。⑵ XML允许各种不同的专业(如音乐、化学、数学等)开发与自己的特定领域有关的标记语言。⑶ XML的最大能量来源于它不仅允许你定义自己的一套标记,而且这些标记不必仅限于对于显示格式的描述。XML允许你根据各种不同的规则来制定标记,比如根据商业规则,根据数据描述甚至根据数据关系来制定标记。⑷ 由于XML是非专有的并易于阅读和编写,就使得它成为在不同的应用间交换数据的理想格式。⑸ 由于标记是有含义的,所以即使过了很长时间用户仍然可以很容易的理解XML文档。⑹ XML是基于W3C定制的开放标准,从而使得基于XML的应用具有广泛性。⑺ 在因特网上如果Web页是XML格式的,则搜索会更高效,而且不仅可以搜索数据,还可以在搜索中加入与数据相关的上下文信息,这样就形成了更精确的搜索机制。
VP工作流程
·初始化· 定义· 配置·帧循环·关闭
初始化和关闭是在vp::namespace中定义的,定义,配置,帧循环等是在vpKernel类中定义的。VpApp是基于初始化,定义,配置,帧循环, 关闭工作流程构造的,所有的VpApp类成员函数都是内嵌虚函数,因而易扩展。vpApp同时提供一些实用的键盘输入来触发图象模式通道。
典型的VP程序如下:
#include <vpApp.h>
int main(int argc, char *argv[])
{
//初始化
vp::initialize(argc, argv);
//创建 vpApp实例
vpApp *app = new vpApp;
//载入 acf 文件
if (argc <= 1)
app->define("simple.acf");
else
app->define(argv[1]);
// 配置
app->configure();
// 帧循环
app->run();
app->unref();
// 关闭
vp::shutdown();
return 0;
}
vp::initialize 实现以下功能:
• Check out the licenses from the license server.
• Initialize static variables and singleton classes.
• Initialize memory allocator.
• Initialize rendering library.
• Initialize scene graph.
• Initialize ACF parser.
• Initialize module interface.
• Initialize kernel classes.
vp::shutdown实现以下功能:
1. Free the memories allocated by the kernel classes.
2. Call the shutdown method on modules so that they can clean up the
memories allocated through out the application.
3. Terminate asynchronous threads.
4. Return the licenses back to the license server.
定义:
类实例在定义中创建和初始化。
类实例可通过代码创建或通过传递ACF文件给vpKernel::define方法 (或vpApp::define, 若 vpApp已经使用). ACF文件中的类实例将在VP解析文件时自动创建。
vpKernel::define()
vpKernel::define( const char *filename )
配置:
在定义系统后,VP配置定义阶段设置的值, 如多线程模式,线程优先和处理器分配等,同时也建立基于附加消息的类实例之间的关系。
帧循环:
while ( s_vpKernel->beginFrame() != 0 )
s_vpKernel->endFrame();
vpKernel
上面提到:“初始化和关闭是在vp::namespace中定义的,定义,配置,帧循环等是在vpKernel类中定义的。”学习了解vpKernel是很有必要的。
VpKernel类是vsServiceMgr类的衍生类. 核心功能包括帧循环的控制和vsServices的管理。其它功能包括:
·创建vsTraversalUpdate实例并控制运行
·遍历访问所有的在kernel 登记并由vpKernel::update 触发的vpScenes
·发送相关配置和帧循环控制信息给所有的vpModules
事件处理列举:
• vpKernel::EVENT_CONFIGURE—Subscribers are notified at configuration stage.
• vpKernel::EVENT_ON_FIRST_FRAME—Subscribers are notified at execution of
the first frame cycle.
• vpKernel::EVENT_PRE_UPDATE_TRAVERSAL—Subscribers are notified in
vpKernel::update, before the update traversal starts.
The function signature for this event is virtual void notify(Event, const
vpKernel*). When the event happens, the function is called. So, you have to
know the signature of the function of each event.
• vpKernel::EVENT_POST_UPDATE_TRAVERSAL—Subscribers are notified in
vpKernel::update, after the update traversal finishes.
The function signature for this event is virtual void notify(Event, const
vpKernel*).
• vpKernel::EVENT_ON_LAST_FRAME—Subscribers are notified at execution of the
last frame cycle.
• vpKernel::EVENT_SYNC_SCENE_GRAPH—Subscribers are notified at sending
syncSceneGraph messages to services.
• vpKernel::EVENT_PROCESS_NON_LATENCY_CRITICAL—Subscribers are notified at
performing non-latency-critical processing.
• vpKernel::EVENT_PROCESS_LATENCY_CRITICAL—Subscribers are notified at
performing latency-critical processing.
• vpKernel::EVENT_SHUTDOWN—Subscribers are notified at shutting down the
frame loop.
配置:
配置成功返回vsgu::SUCCESS:
vpKernel::configure()
vpKernel::configure()
判断是否配置:
vpKernel::isConfigured()
vpKernel::isConfigured()
实例:
返回实例:
vpKernel::instance()
vpKernel::instance()
帧循环:
可以分为以下5个主要步骤:
• beginFrame
• syncWithSceneGraph
• processNonLatencyCritical
• endFrame
• processLatencyCritical
更新:
vpKernel::update()
vpKernel::update()
vpPipeline
vpPipeline管理窗口和硬件图象管道之间的映射。
构造函数:
vpPipeline::vpPipeline()
vpPipeline::vpPipeline()
在窗口中加入新窗口:
vpPipeline::addWindow()
vpPipeline::addWindow( vpWindow *window, int location = -1 )
删除窗口:
vpPipeline::removeWindow()
vpPipeline::removeWindow( vpWindow *window )
在指定迭代程序删除窗口
vpPipeline::erase_window()
vpPipeline::erase_window( const_iterator_window it )
迭代程序有vpPipeline::begin_window, vpPipeline::end_window, vpPipeline::get_iterator_window
其他的还有:
vpPipeline::begin_window()
vpPipeline::begin_window() const
vpPipeline::end_window()
vpPipeline::end_window() const
vpPipeline::empty_window()
vpPipeline::empty_window() const
vpPipeline::getNumWindows()
vpPipeline::getNumWindows() const
vpPipeline::getWindow()
vpPipeline::getWindow( int location ) const
vpPipeline::insert_window()
vpPipeline::insert_window( vpWindow *window, const_iterator_window it )
vpPipeline::push_back_window()
vpPipeline::push_back_window( vpWindow *window )
vpPipeline::size_window()
vpPipeline::size_window() const
窗口:
构造函数:
vpWindow::vpWindow()
vpWindow::vpWindow()
在窗口中加入新通道:
vpWindow::addChannel()
vpWindow::addChannel( vpChannel *channel )
删除通道:
vpWindow::removeChannel()
vpWindow::removeChannel( vpChannel *channel )
插入通道:
vpWindow::insertChannel()
vpWindow::insertChannel( vpChannel *channel, int location )
边界:
vpWindow::setBorderEnable()
vpWindow::setBorderEnable( bool enable )
vpWindow::getBorderEnable()
vpWindow::getBorderEnable( const )
标签:
vpWindow::setLabel()
vpWindow::setLabel( const char *label )
vpWindow::getLabel()
vpWindow::getLabel( const )
键盘函数:
vpWindow::setKeyboardFunc()
vpWindow::setKeyboardFunc( KeyboardFunc func )
vpWindow::getKeyboardFunc()
vpWindow::getKeyboardFunc( const )
鼠标函数:
vpWindow::setMouseFunc()
vpWindow::setMouseFunc( MouseFunc func )
vpWindow::getMouseFunc()
vpWindow::getMouseFunc( const )
vpWindow::setInputEnable()
vpWindow::setInputEnable( bool enable )
vpWindow::getInputEnable()
vpWindow::getInputEnable( const )
坐标:
vpWindow::setCoordinates()
vpWindow::setCoordinates( int left, int right, int bottom, int top )
For example:
vpWindow *window;
window->setCoordinates(100, 600, 100, 600);
vpWindow::getCoordinates()
vpWindow::getCoordinates( int *left, int *right, int *bottom, int *top )
int left, right, bottom, top;
vpWindow *window;
window->getCoordinates(&left, &right, &bottom, &top);
窗口原点:
vpWindow::setOrigin()
vpWindow::setOrigin( int x, int y )
vpWindow::getOrigin()
vpWindow::getOrigin( int *x, int *y )
vpWindow::setFullScreenEnable()
vpWindow::setFullScreenEnable()
窗口大小:
vpWindow::setSize()
vpWindow::setSize( int width, int height )
vpWindow::getSize()
vpWindow::getSize( int *width, int *height )
TOM如是说:
虽然VP提供用户界面,但真正要掌握VP,必须熟悉其基础原理和代码编程。基础知识虽然冗杂,但却是学好VP的基础。在最后附上VP附带的一个简单的代码,有助于深化基础知识的理解。
附录A:
#include <vsgu.h>
#include <vp.h>
#include <vpSearchPath.h>
#include <vpApp.h>
#include "vuAllocTracer.h"
#include "vuDistributed.h"
vuAllocTracer tracer(true, true);
// #########################################################
// # To run this distributed rendering sample, use the #
// # Distributed Rendering Utilites to setup a master and #
// # a slave system #
// #########################################################
class myApp : public vpApp {
public:
myApp() : vpApp() {};
~myApp() {};
virtual void run();
private:
};
void myApp::run()
{
vuNotify::setLevel( vuNotify::LEVEL_INFO );
uint frameNum;
if( vuDistributed::getMode() == vuDistributed::MODE_SLAVE ) {
uint seed = 13;
VUNOTIFY_PRINT( ( vuNotify::LEVEL_INFO,
NULL,
"Slave setting seed to = %d\n",
seed ) );
srand(seed);
} else {
uint seed = 5;
VUNOTIFY_PRINT( ( vuNotify::LEVEL_INFO,
NULL,
"Master setting seed to = %d\n",
seed ) );
srand(seed);
}
// rendering loop
while ( (frameNum = vpKernel::instance()->beginFrame()) > 0 ) {
int myframenum = frameNum;
// basic sync mechanism. masters and slaves wait. no data is exchanged.
vuDistributed::sync();
int randomNum = rand();
VUNOTIFY_PRINT( ( vuNotify::LEVEL_INFO,
NULL,
"Original Random Number = %d\n",
randomNum ) );
int masterData;
// if master, cache the random number and send it to the slaves.
if( vuDistributed::getMode() == vuDistributed::MODE_MASTER ) {
masterData = randomNum;
}
场景显示
我们对现实的呈现是通过将模型加入场景(Scene)来实现的。此外还需要与之对应的通道(Channel)来显示场景,并且还要将该通道对应一个窗口(Window)。在显示过程中与硬件显卡打交道的是管道(pipeline)。这四者共同作用才能将场景呈现出来。Vega Prime定义了vpScene,vpChannel,vpWindow和vpPipeline四个相应的类来完成上述工作。
VpPipeline定义了一个逻辑的图形管道,它管理vpWindow到硬件的图形显示管道的映射。同时它也控制选择和绘制阶段的多线程。
<vp:Pipeline name="myPipeline">
<vp:addWindow refTo="Window::myWindow" />
<vp:setMultiThread>MULTITHREAD_INLINE</vp:setMultiThread>
<vp:setId>0</vp:setId>
<vp:setNumCullThreads>0</vp:setNumCullThreads>
<vp:setCullThreadPriority>PRIORITY_NORMAL</vp:setCullThreadPriority>
<vp:setCullThreadProcessor>-1</vp:setCullThreadProcessor>
<vp:setDrawThreadPriority>PRIORITY_NORMAL</vp:setDrawThreadPriority>
<vp:setDrawThreadProcessor>-1</vp:setDrawThreadProcessor>
</vp:Pipeline>
VpWindow定义了基本的显示窗口以及消息处理机制,它提供了方法来配置帧缓冲区和处理输入,比如键盘输入,鼠标输入。
<vp:Window name="myWindow">
<vp:addChannel refTo="Channel::myChannel" />
<vp:setLabel>Vega Prime Window</vp:setLabel>
<vp:setOrigin>
<vp:left>216</vp:left>
<vp:bottom>216</vp:bottom>
</vp:setOrigin>
<vp:setSize>
<vp:width>512</vp:width>
<vp:height>512</vp:height>
</vp:setSize>
<vp:setFullScreenEnable>false</vp:setFullScreenEnable>
<vp:setBorderEnable>true</vp:setBorderEnable>
<vp:setInputEnable>true</vp:setInputEnable>
<vp:setCursorEnable>true</vp:setCursorEnable>
<vp:setStereoEnable>false</vp:setStereoEnable>
<vp:setAntiAliasEnable>true</vp:setAntiAliasEnable>
<vp:setNumColorBits>8</vp:setNumColorBits>
<vp:setNumAlphaBits>0</vp:setNumAlphaBits>
<vp:setNumDepthBits>24</vp:setNumDepthBits>
<vp:setNumStencilBits>0</vp:setNumStencilBits>
<vp:setNumAccumColorBits>0</vp:setNumAccumColorBits>
<vp:setNumAccumAlphaBits>0</vp:setNumAccumAlphaBits>
<vp:setNumMultiSampleBits>0</vp:setNumMultiSampleBits>
</vp:Window>
VpChannel控制场景的绘制区域,允许设置参数控制剪辑平面。
<vp:Channel name="myChannel">
<vp:setOffsetTranslate>
<vp:x>0.000000</vp:x>
<vp:y>0.000000</vp:y>
<vp:z>0.000000</vp:z>
</vp:setOffsetTranslate>
<vp:setOffsetRotate>
<vp:h>0.000000</vp:h>
<vp:p>0.000000</vp:p>
<vp:r>0.000000</vp:r>
</vp:setOffsetRotate>
<vp:setCullMask>FFFFFFFF</vp:setCullMask>
<vp:setRenderMask>FFFFFFFF</vp:setRenderMask>
<vp:setClearColor>
<vp:r>0.000000</vp:r>
<vp:g>0.500000</vp:g>
<vp:b>1.000000</vp:b>
<vp:a>0.000000</vp:a>
</vp:setClearColor>
<vp:setClearBuffers>3</vp:setClearBuffers>
<vp:setDrawArea>
<vp:left>0.000000</vp:left>
<vp:right>1.000000</vp:right>
<vp:bottom>0.000000</vp:bottom>
<vp:top>1.000000</vp:top>
</vp:setDrawArea>
<vp:setFOVSymmetric>
<vp:hfov>45.000000</vp:hfov>
<vp:vfov>-1.000000</vp:vfov>
</vp:setFOVSymmetric>
<vp:setNearFar>
<vp:nr>1.000000</vp:nr>
<vp:fr>35000.000000</vp:fr>
</vp:setNearFar>
<vp:setLODVisibilityRangeScale>1.000000</vp:setLODVisibilityRangeScale>
<vp:setLODTransitionRangeScale>1.000000</vp:setLODTransitionRangeScale>
<vp:setCullThreadPriority>PRIORITY_NORMAL</vp:setCullThreadPriority>
<vp:setCullThreadProcessor>-1</vp:setCullThreadProcessor>
<vp:setGraphicsModeEnable>
<vp:mode>GRAPHICS_MODE_WIREFRAME</vp:mode>
<vp:enable>false</vp:enable>
</vp:setGraphicsModeEnable>
<vp:setGraphicsModeEnable>
<vp:mode>GRAPHICS_MODE_TRANSPARENCY</vp:mode>
<vp:enable>true</vp:enable>
</vp:setGraphicsModeEnable>
<vp:setGraphicsModeEnable>
<vp:mode>GRAPHICS_MODE_TEXTURE</vp:mode>
<vp:enable>true</vp:enable>
</vp:setGraphicsModeEnable>
<vp:setGraphicsModeEnable>
<vp:mode>GRAPHICS_MODE_LIGHT</vp:mode>
<vp:enable>true</vp:enable>
</vp:setGraphicsModeEnable>
<vp:setGraphicsModeEnable>
<vp:mode>GRAPHICS_MODE_FOG</vp:mode>
<vp:enable>true</vp:enable>
</vp:setGraphicsModeEnable>
<vp:setLightPointThreadPriority>PRIORITY_NORMAL</vp:setLightPointThreadPriority>
<vp:setLightPointThreadProcessor>-1</vp:setLightPointThreadProcessor>
</vp:Channel>
VpScene是vsNode的容器,是一个场景的根节点,是更新和选择遍历的起点。
<vp:Scene name="myScene">
<vp:addChild refTo="Object::terrain" />
<vp:addChild refTo="Object::farmhouse" />
<vp:addChild refTo="Object::car" />
<vp:addChild refTo="Object::myObject" />
</vp:Scene>
上述每个类都提供了一系列的API,例如,vpScene提供了addChild()动态的加入一个节点到场景中,vpWindow提供了addChannel()加入一个通道到窗口中,使该通道可见。VSG中相应的类提供了底层支持。除此之外,还需要有camera,camera相当于人的眼睛。Vega Prime用vpObserver类来代表camera。
vpObserver 定位于任何位置,它具有六个自由度。也可以将运动模型加在vpObserver上,这样camera可以自由运动,场景随camera位置的变化而改变。一个vpObserver下可以连接任意多个channel,同时看到多个channel的内容。
<vp:Observer name="myObserver">
<vp:setStrategy refTo="MotionUFO::myMotion" />
<vp:setStrategyEnable>true</vp:setStrategyEnable>
<vp:addChannel refTo="Channel::myChannel" />
<vp:addAttachment refTo="Env::myEnv" />
<vp:setScene refTo="Scene::myScene" />
<vp:setTranslate>
<vp:x>2300.000000</vp:x>
<vp:y>2500.000000</vp:y>
<vp:z>15.000000</vp:z>
</vp:setTranslate>
<vp:setRotate>
<vp:h>-90.000000</vp:h>
<vp:p>0.000000</vp:p>
<vp:r>0.000000</vp:r>
</vp:setRotate>
<vp:setLatencyCriticalEnable>false</vp:setLatencyCriticalEnable>
</vp:Observer>
场景对象
场景中的对象,比如建筑物,是用于显示的基本数据库单元,Vega Prime是用vpObject来描述对象的。一个vpObject可以看作是geometry和texture的集合。每个vpObject都有一个refenrence counter,当vpObject被加入场景时,reference counter自动加1,当vpObject从场景中撤销时,reference counter自动减1。当reference counter减为0时,vpObject将被从内存中删除。VpObject本身是vpGeometry的派生类,是几何节点(geometry node)的集合。几何和场景中其他的节点不同,它生成了cull record(被选择显示)。每个vpObejct都维护一个geometry列表,建筑物贴了纹理的面是geometry。通过遍历对象的geometry列表,我们可以找到贴某种特定纹理的面,并将该纹理替换掉。VpGeometry定义了几何物体的基本接口,它维护名字节点(named node)和几何节点的列表,并提供了叠代指针在运行时访问这些列表。VpGeometry是构建在vsGeometry和vrGeometry之上的,实际的几何图形定义是在vrGeometry中完成的。
<vp:Object name="car">
<vp:setCullMask>FFFFFFFF</vp:setCullMask>
<vp:setRenderMask>FFFFFFFF</vp:setRenderMask>
<vp:setIsectMask>FFFFFFFF</vp:setIsectMask>
<vp:setStrategyEnable>true</vp:setStrategyEnable>
<vp:setTranslate>
<vp:x>1990.000000</vp:x>
<vp:y>1000.000000</vp:y>
<vp:z>0.000000</vp:z>
</vp:setTranslate>
<vp:setRotate>
<vp:h>140.000000</vp:h>
<vp:p>0.000000</vp:p>
<vp:r>0.000000</vp:r>
</vp:setRotate>
<vp:setScale>
<vp:x>1.000000</vp:x>
<vp:y>1.000000</vp:y>
<vp:z>1.000000</vp:z>
</vp:setScale>
<vp:setStaticEnable>false</vp:setStaticEnable>
<vp:setFileName>esprit-dirty.flt</vp:setFileName>
<vp:setLoaderAttribute>
<vp:attr>LOADER_ATTRIBUTE_GENERATE_VERTEX_ARRAYS</vp:attr>
<vp:value>true</vp:value>
</vp:setLoaderAttribute>
<vp:setLoaderAttribute>
<vp:attr>LOADER_ATTRIBUTE_GENERATE_DISPLAY_LISTS</vp:attr>
<vp:value>true</vp:value>
</vp:setLoaderAttribute>
<vp:setLoaderAttribute>
<vp:attr>LOADER_ATTRIBUTE_COMBINE_LIGHT_POINTS</vp:attr>
<vp:value>true</vp:value>
</vp:setLoaderAttribute>
<vp:setLoaderAttribute>
<vp:attr>LOADER_ATTRIBUTE_PRESERVE_QUADS</vp:attr>
<vp:value>false</vp:value>
</vp:setLoaderAttribute>
<vp:setLoaderAttribute>
<vp:attr>LOADER_ATTRIBUTE_OPTIMIZE_GEOM</vp:attr>
<vp:value>true</vp:value>
</vp:setLoaderAttribute>
<vp:setLoaderAttribute>
<vp:attr>LOADER_ATTRIBUTE_COMPUTE_NORMALS</vp:attr>
<vp:value>false</vp:value>
</vp:setLoaderAttribute>
<vp:setLoaderAttribute>
<vp:attr>LOADER_ATTRIBUTE_COMPATIBILITY_MODE</vp:attr>
<vp:value>true</vp:value>
</vp:setLoaderAttribute>
<vp:setFlattenEnable>true</vp:setFlattenEnable>
<vp:setCleanEnable>true</vp:setCleanEnable>
<vp:setAutoPage>AUTO_PAGE_SYNCHRONOUS</vp:setAutoPage>
</vp:Object>