查看: 2680|回复: 21

关于Prerender的疑问。

[复制链接]

该用户从未签到

发表于 2009-7-2 15:46:42 | 显示全部楼层 |阅读模式
Array的《最长的一帧》第二十四日,介绍了纹理烘焙技术。再结合OSG的prerender的例子。
好像看懂了,实际动手的时候却还是碰到很多困难。
OSG中prerender的例子是将那架飞机渲染到一个矩形面的纹理上。

附件中是个简单的例子,环境:WinXP,VS2008,OSG2.8(其实就一个CPP文件有用)
,一共有3个简单函数,打算将一个矩形的彩色框渲染到奶牛的纹理中然后显示出来,具体做了如下几步工作:
1.由于奶牛原来的纹理图片非常鲜艳,所以使用OSG自带的数据"Images/primitives.gif"自动生成纹理坐标替换了原来的纹理。(createTexture2DState)
2.生成一个彩色矩形框的Geometry,加入到Geode后返回Geode节点。(createQuad)
3.将彩色矩形框渲染到奶牛的新纹理,作为最终的纹理显示。(createPreRenderSubGraph)

最后的情况是指显示了半秒钟,就崩溃了。
感觉应该是纹理上的问题,617和502是primitives.gif的文件大小,有点不知道该设什么值。(要设视口大小)
请高手们不吝赐教~

RTTTest.rar

7.92 KB, 下载次数: 186, 下载积分: 威望 1

RTT测试代码

该用户从未签到

发表于 2009-7-2 16:15:20 | 显示全部楼层
我没太明白您这段代码要干什么,为什么attach的纹理又被分配了Image对象?
attach关联的纹理对象必须是新创建的,没有使用过的。其纹理坐标大小必须和视口的大小一致。而子场景被烘焙到这块纹理中。

该用户从未签到

 楼主| 发表于 2009-7-2 16:29:27 | 显示全部楼层
您好,我也觉得是这个问题。
我这样做的原因是因为奶牛身上本来就有一个有Image的2D纹理,原先做法是向直接渲染到这个纹理上。
因为不想放弃原来的问题,所以想当然这么做了。
那正确的方法应该是:
重新创建一个新的纹理?那原来的纹理该怎么保留呢?
请您赐教。

该用户从未签到

 楼主| 发表于 2009-7-2 17:01:40 | 显示全部楼层
谢谢Array
在奶牛上新增一个新的Texture,然后设置纹理环境为osg::TexEnv::Blend或者osg::TexEnv::ADD
让camera渲染到新的Texture,好像就可以了。

当这个奶牛的模型是PagedLOD的情况下,是不是要把这个矩形彩色框在每个子节点都进行这样的渲染呢?
如果必须要对每个子节点进行这样的渲染,那么PagedLOD每读入一个子节点,有怎样的回调函数或者事件响应呢???

该用户从未签到

发表于 2009-7-2 21:39:21 | 显示全部楼层
只要给PagedLOD的根节点设置纹理,它会应用到每个子节点上,只要纹理坐标正确就可以。
要想实时地保留原来的纹理又追加新的纹理,那么当然是使用多重纹理来实现了。

该用户从未签到

 楼主| 发表于 2009-7-3 17:37:39 | 显示全部楼层
如何将动态的场景正确的渲染到纹理的对应位置呢?
现在不使用奶牛(纹理拉伸的厉害,辨不清具体)
1.创建一个矩形Geometry,将Images/primitives.gif添加为纹理。
Geometry坐标:
        osg::Vec3Array* vc= new osg::Vec3Array();
        vc->push_back(osg::Vec3(0.0f,0.0f,0.0f));
        vc->push_back(osg::Vec3(1.0f,0.0f,0.0f));
        vc->push_back(osg::Vec3(1.0f,0.0f,1.0f));
        vc->push_back(osg::Vec3(0.0f,0.0f,1.0f));
纹理坐标
        osg::Vec2Array* vt= new osg::Vec2Array();
        vt->push_back(osg::Vec2(0.0f,0.0f));
        vt->push_back(osg::Vec2(1.0f,0.0f));
        vt->push_back(osg::Vec2(1.0f,1.0f));
        vt->push_back(osg::Vec2(0.0f,1.0f));
2.创建一个新的纹理,加入到StateSet,将新的纹理坐标设为和Images/primitives.gif图片相同大小。(作为混合纹理贴图,大小617×512,纹理坐标与第一个纹理相同)
3.创建Camera,临时创建一个彩色矩形框,将矩形框的内容渲染到刚才新增的纹理。

问题如图所示:1.渲染到纹理的时候如何保证全覆盖到纹理? 2.颜色怎么反了?

该用户从未签到

 楼主| 发表于 2009-7-3 17:39:54 | 显示全部楼层
图片1

1

1

该用户从未签到

 楼主| 发表于 2009-7-3 17:40:26 | 显示全部楼层
图片2
2.PNG

该用户从未签到

发表于 2009-7-3 23:55:24 | 显示全部楼层
“颜色反了”说明您的FBO相机的观察矩阵设置反了。至于“渲染到纹理的时候如何保证全覆盖到纹理”,抱歉我不明白您的意思

该用户从未签到

 楼主| 发表于 2009-7-6 09:24:16 | 显示全部楼层
我创建的彩色矩形框坐标和“Images/primitives.gif”纹理的Geometry坐标一致,
我的意思是将彩色矩形框的四个顶点准确的渲染到那个新增纹理的四个角上。
使得彩色矩形框渲染到的纹理能和原来的纹理在四个角上重合。
目前状态是边上一圈还是没有被彩色矩形框覆盖到。
感觉应该和setProjectionMatrixAsFrustum以及setViewMatrixAsLookAt有关,改怎样设置呢?

该用户从未签到

发表于 2009-7-6 19:38:59 | 显示全部楼层
投影矩阵的范围再稍作调整应该就可以了

该用户从未签到

 楼主| 发表于 2009-7-7 11:41:41 | 显示全部楼层
在OpenGL中找到的glOrtho(正射投影)
应该相当于Camera的setProjectionMatrixAsOrtho。
感觉应该更好啊,难道不能用??一会测试一下~~

该用户从未签到

 楼主| 发表于 2009-7-7 18:12:49 | 显示全部楼层
试了一下,setProjectionMatrixAsOrtho也是不行。投影关系可能还没搞清楚。setProjectionMatrixAsFrustum就更难调了。
不知道该怎么计算。
赐教啊~

差了一点点

差了一点点

该用户从未签到

发表于 2009-7-7 19:29:50 | 显示全部楼层
setProjectionMatrixAsOrtho没有问题。您最好让我看一下您目前的代码实现,不然我无法判断是什么地方的错误

该用户从未签到

 楼主| 发表于 2009-7-8 09:35:09 | 显示全部楼层
呵呵,感谢Array,这回对了。犯了个低级错误。
创建新的2DTexture的时候把尺寸(617,502)写成了(617,512)
使得顶上部分一直没能被渲染到。真是该死~~

终于对了

终于对了

该用户从未签到

 楼主| 发表于 2009-7-10 18:53:46 | 显示全部楼层
想了想,还是继续占用这个贴吧~
终于找到一个PagedLOD的地形和对应的shp文件。

想把shp文件渲染到PagedLOD的纹理中,目前做法:
1.加载根节点,对根节点进行纹理遍历,找到一个图片2D纹理。
2.使用RTT将SHP渲染到新增纹理,与原纹理一起贴。

如图,能成功,但是只要距离一近,路就没了~(就渲染了一张)
请问Array前辈,如何解决?

你说“只要贴在根节点,纹理坐标正确就会应用的各个子节点”,我就是想这么做~
可是,好像做的不对啊~~请指教啊
1.PNG

该用户从未签到

发表于 2009-7-10 20:55:56 | 显示全部楼层
没有代码,我无法判断您的问题。只能说我就是这么做的~~

该用户从未签到

 楼主| 发表于 2009-7-13 18:23:08 | 显示全部楼层
呵呵,代码超级简单:
1.读取文件
node = osgDB::readNodeFile("E:\\Project\\OSG\\Data\\terrain\\terrain.ive");
osg::Node *shpNode = osgDB::readNodeFile("E:\\Project\\OSG\\Data\\WGS84\\DAOLU_Project.shp");
2.遍历纹理(这个类就是肖鹏的教材里的类,应该不会有问题,只找到一个纹理,可以断定是地形文件根节点的那个纹理)
TextureVisitor textureTV;
node->accept( textureTV );
3. RTT(对找到的纹理,进行RTT操作,根节点有效果,RTT应该正确了)
4.加入Group中
root->addChild(node);
root->addChild(RTT的相机);
5.run

大概过程就是这样,应该很清楚了(代码反而比较罗嗦了,自我感觉,也应该只是渲染了根节点的纹理,因为这个纹理是地形的Geode下的Geometry的纹理,理论上不可能影响到子节点啊,至于到底如何才能应用到子节点呢?)。

还有一个疑问,因为上面的方法暂时没能应用到子节点,所以我在节点的UpdateCallback里面去遍历纹理来RTT,RTT过的就设个标志。
首先申明,这个方法超级烂,速度慢的要命。但是效果倒是出来了。
问题也来了,之前明明设置的黄色的路,现在就变成白色的了。(不管设什么颜色都没用~~,就算是根节点也是白色,不是黄色~)
请Array前辈再指点指点:)

该用户从未签到

发表于 2009-7-13 22:57:23 | 显示全部楼层
抱歉我不太明白您做了什么……

该用户从未签到

 楼主| 发表于 2009-7-14 09:03:44 | 显示全部楼层
2# array



可能我说的没能让您明白。
简单点就是,如何设置PagedLOD根节点的纹理,使其应用到各个子节点??

该用户从未签到

发表于 2009-7-14 09:31:02 | 显示全部楼层
关注ing

该用户从未签到

发表于 2009-7-14 12:47:48 | 显示全部楼层
20# juminghua


我想没有什么特殊的设置
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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