查看: 3846|回复: 8

震撼:OSG第一多问题贴,恳切大家帮助!

[复制链接]

该用户从未签到

发表于 2011-10-16 16:14:05 | 显示全部楼层 |阅读模式
本帖最后由 rcyboom 于 2011-10-16 16:29 编辑

/*记得在OSGChina中问过如何将osg渲染进普通qt窗口的问题,虽然照着别人的帮助依葫芦画瓢了一段代码可以运行,但是一直不知道为什么。这几天休假,正好想再学学OSG,于是下载了OSG3.01和QT4.7.4从源代码进行了编译。然后参考学习这个例子。(因为时隔这么久,网络上仍然找不到更详尽的osg嵌入qt的例子,同时不管在中文网还是英文网站,我搜索了一下,推荐的也只是这个例子)。为了方便分析和学习,我将函数拆散以调用顺序全部集成到构造函数中,原来所需的外部参数也放到构造函数中并带默认值。

使用方法:

QOSGWidget可以当做普通QWidget使用,例如新建一个MainWindow工程,在MainWindow的构造函数中创建并且setCenterWidget即可。


代码分析:

*/


#include<QtCore/QTimer>

#include<QtGui/QApplication>

#include<QtGui/QGridLayout>

#include<QObject>

#include<osgViewer/CompositeViewer>

#include<osgViewer/ViewerEventHandlers>

#include<osgGA/TrackballManipulator>

#include<osgDB/ReadFile>

#include<osgQt/GraphicsWindowQt>

#include<iostream>


class QOSGWidget:public QWidget,public osgViewer::CompositeViewer

{

Q_OBJECT

public:

explicit QOSGWidget(osgViewer::ViewerBase::ThreadingModel threadingModel=osgViewer::CompositeViewer::SingleThreaded,

QString WidgetTitle="",bool windowDecoration=false);

virtual void paintEvent(QPaintEvent* event){frame();}

/*由于继承于普通QWidget,需要使用osg的frame来自行绘制。*/

protected:

QTimer _timer;

QWidget* osgwidget;

};


QOSGWidget::QOSGWidget(osgViewer::ViewerBase::ThreadingModel threadingModel,QString WidgetTitle,bool windowDecoration):QWidget():osgViewer::CompositeViewer()
{/*设置线程模型和创建图形设备相关参数*/
setThreadingModel(threadingModel);

osg::DisplaySettings* ds=osg::DisplaySettings::instance().get();

osg::ref_ptr<osg::GraphicsContext::Traits>traits=new osg::GraphicsContext::Traits;
traits->windowName=WidgetTitle.toStdString();
traits->windowDecoration=windowDecoration;
traits->x=this->x();
traits->y=this->y();
traits->width=this->width();
traits->height=this->height();
traits->doubleBuffer=true;
traits->alpha=ds->getMinimumNumAlphaBits();
traits->stencil=ds->getMinimumNumStencilBits();
traits->sampleBuffers=ds->getMultiSamples();
traits->samples=ds->getNumMultiSamples();
traits->supportsResize=true;


osg::ref_ptr<osg::Camera>camera=newosg::Camera;


/*关联camera对象的图形窗口到根据traits参数创建的GraphicsWindowQt窗口或者?这里的GraphicsWindowQt是新建的对象实例,应该作何理解呢?是图形渲染窗口呢还是OPenGL设备上下文?camera、GraphicsWindowQt以及view之间的关系怎么理解?*/
camera->setGraphicsContext(new osgQt::GraphicsWindowQt(traits.get()));
camera->setClearColor(osg::Vec4(0.2,0.2,0.6,1.0));


/*设置视口范围,这里设置为1/2窗口大小可以正常显示,可是如果我想在窗口的另外一半显示另外一个视角的渲染结果应该怎么做?是应该新增一个camera对象么?可如果新增另外一个camera的话,如何增加到下面的view中呢?*/
camera->setViewport(new osg::Viewport(0,0,traits->width,traits->height/2));
camera->setProjectionMatrixAsPerspective(30.0f,static_cast<double>(traits->width)/static_cast<double>(traits->height),1.0f,10000.0f);
osgViewer::View *view=new osgViewer::View;
view->setCamera(camera);


/*这里调用了CompositeViewer的addview,如果要实现上面的同一窗口不同视角的话是不是可以新增camera对象和view对象,然后再次调用addview呢?*/
addView(view);

osg::Node *scene=osgDB::readNodeFile("cow.osgt");
view->setSceneData(scene);


/*增加用户事件处理,可是如果注销这一句的话,仍然能用鼠标进行操作,为何?*/
view->addEventHandler(new osgViewer::StatsHandler);


/*设置导航方式,如果注销掉的话,显示的画面不堪入目啊。如果我不想使用导航,仅仅想要固定camera对象的话,是否可以使用类似view->getCamera()->setProjectionMatrix();或者直接使用camera->setProjectionMatrix();来设置呢?*/
view->setCameraManipulator(new osgGA::TrackballManipulator);


/*获取GraphicsWindowQt对象的指针,这里获取的指针对象是否就是上面根据traits参数创建的那一个?如果是的话,在上面保存指针的话/这里是不是就不用进一步转化了?*/
osgQt::GraphicsWindowQt *gw=dynamic_cast<osgQt::GraphicsWindowQt*>(camera->getGraphicsContext());

/*通过GraphicsWindowQt对象的getGLWidget方法获取GLWidget并加入到QOSGWidget的layout中去,看源码显示其为GraphicsWindowQt的友类,而GLWidget又从QGLWidget继承而来,那么是否可以这样认为QOSGWidget的父子关系呢:this->layout->GLWidget ?画面实际绘制在GLWidget 上?那GraphicsWindowQt在这里又处于哪一层,起什么作用呢?如果按照这种模式在qt中运行的话,鼠标消息是发给this呢还是直接由GLWidget 截获?*/
osgwidget=gw?gw->getGLWidget():NULL;
QVBoxLayout *layout=new QVBoxLayout(this);
layout->addWidget(osgwidget);

connect(&_timer,SIGNAL(timeout()),this,SLOT(update()));
_timer.start(10);
}
/*看完这简短的几句代码,不明白的东西有太多了,这还是在没深入OSG渲染流程的情况下。这一是我OSG实在是新手,二是实在看不懂GraphicsWindowQt的源代码,不明白他们的关系和作用分别是什么?而且可以将osg渲染嵌入到普通qt窗口中,同时也可以将qt窗口嵌入到osg场景中,不知道他们分别起什么作用?我编译的osg例子代码中只有osgviewQt可以正常运行,猜测中的那个将qt窗口嵌入osg场景中的osgQtWidgets并没有出现,自行编译也报好多错误,也看不到网络上的“重返德军总部”的效果。除了代码中的问题,我仔细想了下,还有如下几个问题:
1、将osg嵌入qt普通窗口的例子是osgviewQt,另外两个osgQtWidgets和osgQtBrowser是否是反向嵌入的例子?
2、一般将OSG嵌入QT的推荐方法是什么?能否给实现一个能在qt下当做普通qglwidget使用的类呢?这个例子虽然拼凑成功,但是很显然还有很多需要改进的地方,如更换场景root,操作camera等。
3、UI界面的window,viewer,camera,setGraphicsContext,CompositeViewer之间的关系如何,怎么理解?如果同一场景在同一窗口以不同的视角显示是怎么回事?同一场景在2个窗口以不同视角显示有时怎么回事?一个程序中不同rootnode的场景各自拥有单独的camera和view在不同的窗口显示又是怎么回事呢?问题多且杂乱无章,惭愧的首选是自己,但是这确实就是目前我所遇到的拦路狗,不期望哪位大侠能一一解释,不过就算回答一两个也十分感激不尽了。同时,我想大家试试看能否解我所惑,看看是不是很多新手都遇到了我这样不可理喻的问题呢?*/

该用户从未签到

 楼主| 发表于 2011-10-16 16:19:44 | 显示全部楼层
额 怎么才能弄整齐一点呢,我写了一下午啊

该用户从未签到

发表于 2011-10-17 09:43:49 | 显示全部楼层
第二个问题,可以参考或使用 osgxi 项目

该用户从未签到

 楼主| 发表于 2011-10-17 12:01:52 | 显示全部楼层
osgxi 真还没听说过,赶紧去google一下。
感谢楼上的回复!

该用户从未签到

 楼主| 发表于 2011-10-17 16:42:46 | 显示全部楼层
这个是OSG example中osgviewerQT的代码,我就是按顺序贴出来并简化了一下。

该用户从未签到

发表于 2011-10-18 10:54:29 | 显示全部楼层
关联camera对象的图形窗口到根据traits参数创建的GraphicsWindowQt窗口或者?这里的GraphicsWindowQt是新建的对象实例,应该作何理解呢?是图形渲染窗口呢还是OPenGL设备上下文?camera、GraphicsWindowQt以及view之间的关系怎么理解?
最长的一帧中已经很详细地解释了他们之间的关系,因此抱歉这里我不想赘述

设置视口范围,这里设置为1/2窗口大小可以正常显示,可是如果我想在窗口的另外一半显示另外一个视角的渲染结果应该怎么做?是应该新增一个camera对象么?可如果新增另外一个camera的话,如何增加到下面的view中呢?
可以用addChild(),也可以用CompositeViewer


这里调用了CompositeViewer的addview,如果要实现上面的同一窗口不同视角的话是不是可以新增camera对象和view对象,然后再次调用addview呢
有什么不可以?


增加用户事件处理,可是如果注销这一句的话,仍然能用鼠标进行操作,为何
鼠标操作是Manipulator的事情


设置导航方式,如果注销掉的话,显示的画面不堪入目啊。如果我不想使用导航,仅仅想要固定camera对象的话,是否可以使用类似view->getCamera()->setProjectionMatrix();或者直接使用camera->setProjectionMatrix();来设置呢
setViewMatrix设置观察矩阵


获取GraphicsWindowQt对象的指针,这里获取的指针对象是否就是上面根据traits参数创建的那一个?如果是的话,在上面保存指针的话/这里是不是就不用进一步转化了?
可以


通过GraphicsWindowQt对象的getGLWidget方法获取GLWidget并加入到QOSGWidget的layout中去,看源码显示其为GraphicsWindowQt的友类,而GLWidget又从QGLWidget继承而来,那么是否可以这样认为QOSGWidget的父子关系呢:this->layout->GLWidget ?画面实际绘制在GLWidget 上?那GraphicsWindowQt在这里又处于哪一层,起什么作用呢?如果按照这种模式在qt中运行的话,鼠标消息是发给this呢还是直接由GLWidget 截获?
显然没有这种父子关系,绘制在GLWidget上没错,GraphicsWindowQt用于连接OSG场景与渲染窗口和封装窗口级别的GL指令


1、将osg嵌入qt普通窗口的例子是osgviewQt,另外两个osgQtWidgets和osgQtBrowser是否是反向嵌入的例子?
2、一般将OSG嵌入QT的推荐方法是什么?能否给实现一个能在qt下当做普通qglwidget使用的类呢?这个例子虽然拼凑成功,但是很显然还有很多需要改进的地方,如更换场景root,操作camera等。
3、UI界面的window,viewer,camera,setGraphicsContext,CompositeViewer之间的关系如何,怎么理解?如果同一场景在同一窗口以不同的视角显示是怎么回事?同一场景在2个窗口以不同视角显示有时怎么回事?一个程序中不同rootnode的场景各自拥有单独的camera和view在不同的窗口显示又是怎么回事呢?问题多且杂乱无章,惭愧的首选是自己,但是这确实就是目前我所遇到的拦路狗,不期望哪位大侠能一一解释,不过就算回答一两个也十分感激不尽了。同时,我想大家试试看能否解我所惑,看看是不是很多新手都遇到了我这样不可理喻的问题呢


1、是
2、随意
3、不想解释,因为解释过太多次了。不自己仔细考虑和查找资料就提问,这根本就不是好的学习方式。事实上以您现有的学习态度,不可能很好地学习任何一种工具;因为您目前还只是一个机器人,并没有自己思考过什么

该用户从未签到

 楼主| 发表于 2011-10-18 11:18:40 | 显示全部楼层
本帖最后由 rcyboom 于 2011-10-18 11:21 编辑

额 您的指责虽然有点尖锐但是不可否认都是对的,我会在线下仔细去查看你间或提到的资料的。
关于第三个问题,我想您可能误会我的意思了,我学过很长一段时间的Opengl,当然是自学,因为我从事的工作和电脑无关,我就是大学期间自己买了电脑凭爱好瞎折腾而已,学过很多但是都不精通也没做过项目,虽然我梦想过从事和计算机有关的行业,不管是软件还是硬件,但目前看来不太可能,我就是您再另外一个帖子中谈到的那种“拿着人民的税款喝茶看报的人”,但是不可否认这类人中也有想着上进的或者实现自己梦想的一部分,这或许就是圈内和圈外的区别,环境不同理念不同做法就不同而已。
我2分钟前刚在另外一个帖子就您的解答进行了进一步咨询,没想到刚提交您就已经解答了这个帖子的大部分问题,首先对您能够耐心看完这个帖子表示感谢,其次您也解答了很多我的问题,在这里再次表示感谢!
回到问题中来,对于Openggl中的窗口、视口、摄像机我觉得已经掌握了,但那是在OPengl状态机中的概念、我的问题简单说来就是OSG中这些有什么不同,因为OSG中多了一些类型化的概念。
另外刚刚上面那个帖子:
http://bbs.osgchina.org/viewthread.php?tid=5896&highlight=%CB%B0
我觉得我就是想把OSG当做一个优秀的库来用,我没有时间也没有那个能力像OSG源代码共享自己的一份力量,但我期望开发者名录里面多出现几个中国人的名字,更期待多出现一些中文的资料。虽然作为开源的使用者光索取不贡献不是很道德,但使用也就是推广,不是么?另外,作为一个成年人,我接收也倡议向OSG在中国的发展作出共享,我建议贵站能否提供一个有组织的文档中文化小组,让大家都投入进来呢?甚至开辟一个捐赠通道也可以的,我相信虽然我不富有,但爱心还是有的。当然,作为中国人的弊病,这两个首先得是有组织有计划的。。。

该用户从未签到

发表于 2011-10-21 16:56:17 | 显示全部楼层
Camera是场景节点,它的子节点即需要显示的内容;GraphicsContext是渲染设备,在通常的程序中,它也就是渲染窗口和GL设备上下文的表达;Viewer是这一切的载体,并包装了数据更新和用户事件处理的过程

至于您其他的想法,我几年前就有这样的想法,很可惜做不到,把中国人组织起来是一件天方夜谭的事情,这个不需要再次证明了。捐赠也是不切实际的想法。此外OSG也不是红十字会或者贫困儿童,不需要“爱心”和关怀。您只要自己愿意用这个库,并且能从中有所得,这就足够了;您愿意参与推广的话当然欢迎,但是您将面对的是分文不得,各种各样的白眼,不屑一顾,以及工作和生活上的困难,还有热情的迅速消退

该用户从未签到

发表于 2014-3-5 15:00:33 | 显示全部楼层
很不错的啊,谢谢楼主的那些啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表