osg资料收集.docx
《osg资料收集.docx》由会员分享,可在线阅读,更多相关《osg资料收集.docx(49页珍藏版)》请在冰豆网上搜索。
osg资料收集
OpenSceneGraph中国讨论区-有您OSG在中国才更好'sArchiver
OpenSceneGraph中国讨论区-有您OSG在中国才更好»OpenSceneGraph»MFC下的抗锯齿问题
forest37发表于2008-12-210:
28
MFC下的抗锯齿问题
osg中设置抗锯齿的方法大多都是这样的吧:
[quote]osg:
:
DisplaySettings*ds=osg:
:
DisplaySettings:
:
instance();
ds->setNumMultiSamples(16);
mViewer->setDisplaySettings(ds);[/quote]
可是这段代码在osgviewerMFC下不起作用,除非
直接设置 traits->samples=16;
这样可以在窗口初始化时设置抗锯齿,也就是像素采样率,那如何在程序运行时设置抗锯齿呢?
请高手们指教
[[i]本帖最后由forest37于2008-12-210:
30编辑[/i]]
array发表于2008-12-210:
32
试一试osg:
:
Multisample
这是一个渲染属性,赋给场景根节点好了
forest37发表于2008-12-211:
59
我在窗口初始化时设置traits->samples=16;
并对根节点进行了如下设置
osg:
:
Multisample*pms=newosg:
:
Multisample;
mRoot->getOrCreateStateSet()->setAttributeAndModes(pms,osg:
:
StateAttribute:
:
OFF);
结果是抗锯齿仍然是开着的,any idea?
array发表于2008-12-214:
57
没有设置Multisample的属性?
这个是GL_ARB_multisample扩展的封装,请参看glSampleCoverage函数的用法
还有设置为OFF的话就等于没有设置Multisample了,这时候肯定是窗口初始化的设置有效。
forest37发表于2008-12-215:
59
首先谢谢您的解答
glSampleCoverage是设置采样如何考虑透明度(alpha)的吧
Multisample看上去没什么属性啊,只有一个mode,这个mode无非是质量优先,速度优先,好像没有设置不采样,或者设置采样率的接口啊。
array发表于2008-12-216:
07
有关glSampleCoverage的用法详情可以参看:
[url]http:
//www.opengl.org/sdk/docs/man/xhtml/glSampleCoverage.xml[/url]
mode属性不是在什么机器上都可以设置的,,只有nvidia可以
还有请同时开启setMode(GL_MULTISAMPLE,ON);
billong发表于2009-7-2316:
12
[quote]没有设置Multisample的属性?
这个是GL_ARB_multisample扩展的封装,请参看glSampleCoverage函数的用法
还有设置为OFF的话就等于没有设置Multisample了,这时候肯定是窗口初始化的设置有效。
[size=2][color=#999999]array发表于2008-12-214:
57[/color][url=http:
//bbs.osgchina.org/redirect.php?
goto=findpost&pid=5751&ptid=812][img]http:
//bbs.osgchina.org/images/common/back.gif[/img][/url][/size][/quote]
array大牛
在n卡下只要做一下设置:
在窗口初始化时设置traits->samples=16;
并对根节点进行了如下设置
osg:
:
Multisample*pms=newosg:
:
Multisample;
pms->setSampleCoverage(1,true);//[i]属性设置对了吗?
[/i]
mRoot->getOrCreateStateSet()->setAttributeAndModes(pms,osg:
:
StateAttribute:
:
ON);
那么mRoot节点下的孩子都有抗锯齿的效果,包括导入的osg模型.。
而在a卡下,就没有抗锯齿的功能?
?
?
?
谢谢了。
。
。
。
。
array发表于2009-7-2316:
59
A卡对OpenGL的支持差那是出了名的,在开始仿真循环之前用DisplaySettings:
:
instance()->setNumMultiSamples()试一试
billong发表于2009-7-2613:
20
[quote]A卡对OpenGL的支持差那是出了名的,在开始仿真循环之前用DisplaySettings:
:
instance()->setNumMultiSamples()试一试
[size=2][color=#999999]array发表于2009-7-2316:
59[/color][url=http:
//bbs.osgchina.org/redirect.php?
goto=findpost&pid=11649&ptid=812][img]http:
//bbs.osgchina.org/images/common/back.gif[/img][/url][/size][/quote]
在n卡里怎么setNumMultiSamples(4),最大只能到4啊。
。
。
816什么的在realize()的时候就建立窗口失败
array发表于2009-7-2614:
55
这取决于显卡的支持能力
billong发表于2009-7-2616:
31
[b][url=http:
//bbs.osgchina.org/redirect.php?
goto=findpost&pid=11726&ptid=812]10#[/url][i]array[/i][/b]
我的是9600gt 支持性这么差》?
?
多重采样这么耗显卡吗?
?
11月23日
Navy10-使用自定义矩阵来放置相机
本章目标:
手动放置相机,以实现场景的观览。
----------------------------------------------------------------------
设置矩阵的方向和位置
我们可以使用osg:
:
Matrix类来设置矩阵的数据。
本章中我们将使用双精度类型的矩阵类osg:
:
Matrixd。
要设置矩阵的位置和方向,我们可以使用矩阵类的makeTranslate()和makeRotate()方法。
为了方便起见,这两个方法均提供了多种可重载的类型。
本例中我们使用的makeRotate()方法要求三对角度/向量值作为输入参数。
旋转量由围绕指定向量轴所旋转的角度(表示为弧度值)决定。
这里我们简单地选用X,Y,Z直角坐标系作为旋转参照的向量轴。
将平移矩阵右乘旋转矩阵后,即可创建一个单一的表示旋转和平移的矩阵。
代码如下:
如下是设置场景的代码。
此场景包括一个小型的地形和坦克模型。
坦克位于(10,10,8)的位置。
intmain()
{
osg:
:
Node*groundNode=NULL;
osg:
:
Node*tankNode=NULL;
osg:
:
Group*root=newosg:
:
Group();
osgProducer:
:
Viewerviewer;
osg:
:
PositionAttitudeTransform*tankXform;
groundNode=osgDB:
:
readNodeFile("\\Models\\JoeDirt\\JoeDirt.flt");
tankNode=osgDB:
:
readNodeFile("\\Models\\T72-Tank\\T72-tank_des.flt");
//创建绿色的天空布景。
osg:
:
ClearNode*backdrop=newosg:
:
ClearNode;
backdrop->setClearColor(osg:
:
Vec4(0.0f,0.8f,0.0f,1.0f));
root->addChild(backdrop);
root->addChild(groundNode);
tankXform=newosg:
:
PositionAttitudeTransform();
root->addChild(tankXform);
tankXform->addChild(tankNode);
tankXform->setPosition(osg:
:
Vec3(10,10,8));
tankXform->setAttitude(
osg:
:
Quat(osg:
:
DegreesToRadians(-45.0),osg:
:
Vec3(0,0,1)));
osgGA:
:
TrackballManipulator*Tman=newosgGA:
:
TrackballManipulator();
viewer.setCameraManipulator(Tman);
viewer.setSceneData(root);
viewer.realize();
声明一个用于设置相机的矩阵。
矩阵的位置设置为坦克模型后方60个单元,上方7个单元。
同时设置矩阵的方向。
osg:
:
MatrixdmyCameraMatrix;
osg:
:
MatrixdcameraRotation;
osg:
:
MatrixdcameraTrans;
cameraRotation.makeRotate(
osg:
:
DegreesToRadians(-20.0),osg:
:
Vec3(0,1,0),//滚转角(Y轴)
osg:
:
DegreesToRadians(-15.0),osg:
:
Vec3(1,0,0),//俯仰角(X轴)
osg:
:
DegreesToRadians(10.0),osg:
:
Vec3(0,0,1));//航向角(Z轴)
//相机位于坦克之后60个单元,之上7个单元。
cameraTrans.makeTranslate(10,-50,15);
myCameraMatrix=cameraRotation*cameraTrans;
使用矩阵设置视口摄相机
场景的视口类实例使用当前MatrixManipulator控制器类(TrackballManipulator,DriveManipulator等)矩阵的逆矩阵来设置主摄像机的位置。
为了在视口中使用我们自定义的摄像机位置和方向矩阵,我们需要首先计算自定义矩阵的逆矩阵。
除了求取逆矩阵之外,我们还需要提供世界坐标系的方向。
通常osgGA:
:
MatrixManipulator矩阵(osgProducer:
:
Viewer中使用)使用的坐标系为Z轴向上。
但是Producer和osg:
:
Matrix(也就是上文所创建的)使用Y轴向上的坐标系系统。
因此,在获得逆矩阵之后,我们需要将其从Y轴向上旋转到Z轴向上的形式。
这一要求可以通过沿X轴旋转-90度来实现。
其实现代码如下所示:
while(!
viewer.done())
{
if(manuallyPlaceCamera)
{
osg:
:
Matrixdi=myCameraMatrix.inverse(myCameraMatrix);
Tman->setByInverseMatrix(
osg:
:
Matrix(i.ptr())
*osg:
:
Matrix:
:
rotate(-3.1415926/2.0,1,0,0));
}
viewer.frame();
}
注意:
按下V键可以手动切换摄像机。
20:
25 |添加评论 |固定链接 |写入日志 |NPS教程
11月17日
Navy09.1-处理键盘输入实现更新回调
本章目标:
上一个教程我们讲解了键盘事件处理器类,它用于注册响应函数。
本章提供了用于键盘输入的更方便的方案。
我们将重载一个GUIEventHandler类,而不必再创建和注册函数。
在这个类中我们将添加新的代码,以便执行特定的键盘和鼠标事件响应动作。
我们还将提出一种键盘事件处理器与更新回调通讯的方法。
----------------------------------------------------------------------
问题的提出:
教程08演示了如何将回调与DOF节点相关联,以实现场景中DOF节点位置的持续更新。
那么,如果我们希望使用键盘输入来控制场景图形中的节点,应该如何处理呢?
例如,如果我们有一个基于位置变换节点的坦克模型,并希望在按下w键的时候控制坦克向前运动,我们需要进行如下一些操作:
1.读取键盘事件;
2.保存键盘事件的结果;
3.在更新回调中响应键盘事件。
解决方案:
第一步:
基类osgGA:
:
GUIEventHandler用于定义用户自己的GUI键盘和鼠标事件动作。
我们可以从基类派生自己的类并重载其handle方法,以创建自定义的动作。
同时还编写accept方法来实现GUIEventHandlerVisitor(OSG2.0版本中此类已经废弃)的功能。
其基本的框架结构如下所示:
classmyKeyboardEventHandler:
publicosgGA:
:
GUIEventHandler
{
public:
virtualboolhandle(constosgGA:
:
GUIEventAdapter&ea,osgGA:
:
GUIActionAdapter&);
virtualvoidaccept(osgGA:
:
GUIEventHandlerVisitor&v) {v.visit(*this);};
};
boolmyKeyboardEventHandler:
:
handle(constosgGA:
:
GUIEventAdapter&ea,osgGA:
:
GUIActionAdapter&aa)
{
switch(ea.getEventType())
{
case(osgGA:
:
GUIEventAdapter:
:
KEYDOWN):
{
switch(ea.getKey())
{
case'w':
std:
:
cout<<"wkeypressed"<:
endl;
returnfalse;
break;
default:
returnfalse;
}
}
default:
returnfalse;
}
}
上述类的核心部分就是我们从基类中重载的handle方法。
这个方法有两个参数:
一个GUIEventAdapter类的实例,用于接收GUI事件;另一个是GUIActionAdapter类的实例,用于生成并向GUI系统发送请求,例如重绘请求和持续更新请求。
我们需要根据第一个参数编写代码以包含更多的事件,例如KEYUP,DOUBLECLICK,DRAG等。
如果要处理按下按键的事件,则应针对KEYDOWN这个分支条件来扩展相应的代码。
事件处理函数的返回值与事件处理器列表中当前处理器触发的键盘和鼠标事件相关。
如果返回值为true,则系统认为事件已经处理,不再传递给下一个事件处理器。
如果返回值为false,则传递给下一个事件处理器,继续执行对事件的响应。
为了“安装”我们的事件处理器,我们需要创建它的实例并添加到osgViewer:
:
Viewer的事件处理器列表。
代码如下:
myKeyboardEventHandler*myFirstEventHandler=newmyKeyboardEventHandler();
viewer.getEventHandlerList().push_front(myFirstEventHandler);
第二步:
到目前为止,我们的键盘处理器还并不完善。
它的功能仅仅是在每次按下w键时向控制窗口输出。
如果我们希望按下键时可以控制场景图形中的元素,则需要在键盘处理器和更新回调之间建立一个通讯结构。
为此,我们将创建一个用于保存键盘状态的类。
这个事件处理器类用于记录最近的键盘和鼠标事件状态。
而更新回调类也需要建立与键盘处理器类的接口,以实现场景图形的正确更新。
现在我们开始创建基本的框架结构。
用户可以在此基础上进行自由的扩展。
下面的代码是一个类的定义,用于允许键盘事件处理器和更新回调之间通讯。
classtankInputDeviceStateType
{
public:
tankInputDeviceStateType:
:
tankInputDeviceStateType():
moveFwdRequest(false){}
boolmoveFwdRequest;
};
下一步的工作是确认键盘事件处理器和更新回调都有正确的数据接口。
这些数据将封装到tankInputdeviceStateType的实例中。
因为我们仅使用一个事件处理器来控制坦克,因此可以在事件处理器中提供指向tankInputDeviceStateType实例的指针。
我们将向事件处理器添加一个数据成员(指向tankInputDeviceStateType的实例)。
同时我们还会将指针设置为构造函数的输入参量。
以上所述的改动,即指向tankInputDeviceStateType实例的指针,以及新的构造函数如下所示:
classmyKeyboardEventHandler:
publicosgGA:
:
GUIEventHandler{
public:
myKeyboardEventHandler(tankInputDeviceStateType*tids)
{
tankInputDeviceState=tids;
}
//……
protected:
tankInputDeviceStateType*tankInputDeviceState;
};
我们还需要修改handle方法,以实现除了输出到控制台之外更多的功能。
我们通过修改标志参量的值,来发送坦克向前运动的请求。
boolmyKeyboardEventHandler:
:
handle(constosgGA:
:
GUIEventAdapter&ea,osgGA:
:
GUIActionAdapter&aa)
{
switch(ea.getEventType())
{
case(osgGA:
:
GUIEventAdapter:
:
KEYDOWN):
{
switch(ea.getKey())
{
case'w':
tankInputDeviceState->moveFwdRequest=true;
returnfalse;
break;
default:
returnfalse;
}
}
default:
returnfalse;
}
}
第三步:
用于更新位置的回调类也需要编写键盘状态数据的接口。
我们为更新回调添加与上述相同的参数。
这其中包括一个指向同一tankInputDeviceStateType实例的指针。
类的构造函数则负责将这个指针传递给成员变量。
获得指针之后,我们就可以在回调内部使用其数值了。
目前的回调只具备使坦克向前运动的代码,前提是用户执行了相应的键盘事件。
回调类的内容如下所示:
classupdateTankPosCallback:
publicosg:
:
NodeCallback{
public:
updateTankPosCallback:
:
updateTankPosCallback(tankInputDeviceStateType*tankIDevState)
:
rotation(0.0),tankPos(-15.,0.,0.)
{
tankInputDeviceState=tankIDevState;
}
virtualvoidoperator()(osg:
:
Node*node,osg:
:
NodeVisitor*nv)
{
osg:
:
PositionAttitudeTransform*pat=
dynamic_cast:
PositionAttitudeTransform*>(node);
if(pat)
{
if(tankInputDeviceState->moveFwdRequest)
{
tankPos.set(tankPos.x()+.01,0,0);
pat->setPosition(tankPos);
}
}
traverse(node,nv);
}
protected:
osg:
:
Vec3dtankPos;
tankInputDeviceStateType*tankInputDeviceState;
};
现在,键盘和更新回调之间的通讯框架已经基本完成。
下一步是创建一个tankInputDeviceStateType的实例。
这个实例将作为事件处理器构造函数的参数传入。
同时它也是模型位置更新回调类的构造函数参数。
当事件处理器添加到视口的事件处理器列表中之后,我们就可以进入仿真循环并执行相应的功能了。
//定义用于记录键盘事件的类的实例。
tankInputDeviceStateType*tIDevState=newtankInputDeviceStateType;
//设置坦克的更新回调。
//其构造函数将传递上面的实例指针作为实参。