查看: 1587|回复: 5

FBO窗口与纹理尺寸的匹配问题

[复制链接]

该用户从未签到

发表于 2012-3-3 14:50:27 | 显示全部楼层 |阅读模式
     使用osg的FBO技术时,我将rttCamera设置为RELATIVE_RF, 显示纹理的hudCamera设置为ABSOLUTE_RF,这样可以在rttCamera中使用主场景的漫游器。实现时窗口的大小为默认的全屏(1440, 900),纹理大小为(512, 512),rttCamera的视口矩阵也是按照纹理的尺寸大小设置的。如果使用opengl的固定管线进行渲染,结果跟预期一样,添加到rttCamera的个场景都能被完整的渲染到纹理上,但我用shader实现这一过程时却发生了一些莫名其名的结果。场景只有一部分被渲染到了纹理上,另一部分似乎被rttCamera的视口矩阵给裁掉了。效果分别如下面两幅图所示。
r2t_fix.jpg    r2t_shader.jpg
       我的顶点着色器只是简单的对gl_Position进行了设置:gl_Position = ftransform()。这个固定管线和着色器所长生的差别让我很头痛。考虑了一下感觉可能是在启用shader时,rttCamera使用的是主场景的窗口大小,这样的话rttCamera的viewPort就不能将整个场景覆盖,产生了裁剪的现象。我尝试对rttCamera设置一个GraphicContext,(鉴于FBO是一种虚拟的设备,不知道这样做有没有意义),将GraphicContext的大小设置和纹理一样大,但是还是会发生裁剪。
    小弟刚学osg不久,对于固定管线和shader的差异实在是不知道如何解释,希望各位牛人能够帮忙解答一下。另外使用着色器时,是否一定要将纹理的尺寸设置的与实际的窗口大小一下,如果不用的话该如何实现呢?

该用户从未签到

 楼主| 发表于 2012-3-4 01:01:39 | 显示全部楼层
大牛们,求解答啊。。。。

该用户从未签到

发表于 2012-3-5 09:40:03 | 显示全部楼层
shader与固定管线对于rtt而言没有区别,估计是您的其他代码有问题;此外也不用保证纹理的尺寸设置的与实际的窗口大小一致

该用户从未签到

 楼主| 发表于 2012-3-5 12:01:15 | 显示全部楼层
array 发表于 2012-3-5 09:40
shader与固定管线对于rtt而言没有区别,估计是您的其他代码有问题;此外也不用保证纹理的尺寸设置的与实际的 ...

多谢Array大牛的答复,仔细查了下。
将下面代码:
osg::ref_ptr<osg::StateSet> stas = new osg::StateSet;
stas->setAttributeAndModes(prog.get());
rttCamera->setStateSet(stas.get());
改为:
osg::ref_ptr<osg::StateSet> stas = rttCamera->getOrCreateStateSet();
stas->setAttributeAndModes(prog.get());
即可,但是这两段代码有什么区别么?

该用户从未签到

发表于 2012-3-6 09:18:35 | 显示全部楼层
rttCamera本身可能已经设置了一些渲染状态,setStateSet()等于把这些都抹去并赋予全新的状态,我不知道您是否因此抹掉了一些重要的渲染属性

该用户从未签到

 楼主| 发表于 2012-3-6 11:14:32 | 显示全部楼层
array 发表于 2012-3-6 09:18
rttCamera本身可能已经设置了一些渲染状态,setStateSet()等于把这些都抹去并赋予全新的状态,我不知道您是 ...

我也认为这样,但是我在rttCamera感觉并没有设置渲染属性啊。代码如下(是从您的书上直接copy然后改的)
#include <osg/Camera>
#include <osg/Texture2D>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/PositionAttitudeTransform>

#include <iostream>
#include <osg/Viewport>
#include <osgGA/TrackballManipulator>

const int tex_width = 512;
const int tex_height = 512;

osg::Texture* createRttTexture( int texWidth, int texHeight )
{
    osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
    texture->setInternalFormat( GL_RGBA );
    texture->setFilter( osg::Texture::MIN_FILTER, osg::Texture:INEAR );
    texture->setFilter( osg::Texture::MAG_FILTER, osg::Texture::LINEAR );
   
    texture->setTextureSize( texWidth, texHeight );
    return texture.release();
}

osg::Camera* createRttCamera( int texWidth, int texHeight, const osg::BoundingSphere& bs )
{
    osg::ref_ptr<osg::Camera> rttCamera = new osg::Camera;
    rttCamera->setClearMask( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );   
        rttCamera->setViewport( 0, 0, texWidth, texHeight );
    rttCamera->setRenderOrder( osg::Camera:RE_RENDER );
    rttCamera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT );

        const char* simpleVert = {
                "//uniform mat4 uCamPMV;\n"
                "void main\n"       
                "{\n"
                "gl_Position = ftransform();\n"
                "}"
        };
        const char* simpleFrag =
        {
                "void main\n"
                "{\n"
                "        gl_FragColor = vec4(0.5, 0.5 ,0.1, 1.0);"
                "}\n"
        };

        osg::ref_ptr<osg::Program>  prog = new osg::Program;
        osg::ref_ptr<osg::Shader>   vert = new osg::Shader(osg::Shader::VERTEX);
        osg::ref_ptr<osg::Shader>   frag = new osg::Shader(osg::Shader::FRAGMENT);

        vert->loadShaderSourceFromFile("simple.vert");
        frag->loadShaderSourceFromFile("simple.frag");
        prog->addShader(vert.get());
        prog->addShader(frag.get());

        osg::ref_ptr<osg::StateSet> stas = new osg::StateSet;//rttCamera->getOrCreateStateSet();
        stas->setAttributeAndModes(prog.get());
        rttCamera->setStateSet(stas.get());

        return rttCamera.release();
}

int main( int argc, char** argv )
{
    osg::ArgumentParser arguments( &argc, argv );
    osg::Node* model = osgDB::readNodeFiles( arguments );
    if ( !model ) model = osgDB::readNodeFile( "rocky.ive" );
    osg::Camera* rttCamera = createRttCamera( tex_width, tex_height, model->getBound() );
    osg::Texture* rttTexture = createRttTexture( tex_width, tex_height);
   
    rttCamera->addChild( model );
    rttCamera->attach( osg::Camera::COLOR_BUFFER, rttTexture );

        osg::ref_ptr<osg::Geode> quad = new osg::Geode;
        quad->addDrawable( osg::createTexturedQuadGeometry(
                osg::Vec3(0.0,0.0,0.0), osg::Vec3(1.0,0.0,0.0), osg::Vec3(0.0, 1.0, 0.0)));
       
        quad->getOrCreateStateSet()->setTextureAttributeAndModes(0, rttTexture, osg::StateAttribute::ON);
        quad->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);

        osg::Camera* hudCamera = new osg::Camera;
        hudCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
        hudCamera->setRenderOrder(osg::Camera::POST_RENDER);
        hudCamera->setViewport(0, 0, 300, 300);
        hudCamera->setClearColor(osg::Vec4(0.5, 0.5, 0.5, 1.0));
        hudCamera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        hudCamera->setProjectionMatrixAsOrtho2D(0.0, 1.0, 0.0, 1.0);
        hudCamera->setViewMatrix(osg::Matrix::identity());

        hudCamera->addChild(quad.get());

        osg::ref_ptr<osg::PositionAttitudeTransform> pat = new osg::PositionAttitudeTransform;
        pat->addChild(model);
   
    osg::ref_ptr<osg::Group> root = new osg::Group;
    root->addChild(hudCamera);
    root->addChild(rttCamera);
        root->addChild(pat.get());
   
    osgViewer::Viewer viewer;
    viewer.setSceneData( root.get() );

    return viewer.run();
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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