查看: 2066|回复: 13

glsl中的framebuffer在osg中怎么赋值?

[复制链接]

该用户从未签到

发表于 2010-6-4 23:59:36 | 显示全部楼层 |阅读模式
本帖最后由 lvzhihan 于 2010-6-5 19:08 编辑

最近在尝试把GLSL Demo中的shader在osg中调用,但是有很多问题。
比如:例子HeatHaze中,调用的规则如下:
<program name="HeatHaze" reflection="off">
<textures stage="0">Framebuffer</textures>
<models>lane All -Alien -BlobbyCloud -PointCloud</models>
<uniform name="FrameBuffer">0</uniform>
<uniform name="FrameWidth" type="float">255.0</uniform>
<uniform name="FrameHeight" type="float">255.0</uniform>
<uniform name="Frequency" type="float">
20
<slider>0 100</slider>
</uniform>

<uniform name="Speed" type="int">
1
<slider>0 10</slider>
</uniform>
<uniform name="Fade" type="float">
0.7
<slider>0 1</slider>
</uniform>

<uniform name="Offset" type="float">
0
<motion length="1s">0 6.2831</motion>
</uniform>

</program>

但是我没有找到Framebuffer这张纹理。
同样Glass这个例子中也有:
<program name="Glass" reflection="off">
<models>Klein All -PointCloud -Alien -BlobbyCloud</models>
<textures mipmap="0" stage="0">House</textures>
<textures mipmap="0" stage="1">Framebuffer</textures>

在Frag中定义是:uniform sampler2D FrameBuffer;
不知该怎么赋值了
求高人指教
shader和配置文件全都上传了。

shaders.rar

4.12 KB, 下载次数: 128, 下载积分: 威望 1

该用户从未签到

发表于 2010-6-5 21:14:31 | 显示全部楼层
我想对一个结点进行前向渲染和后向渲染,不知这样设置对不对?
stateset->setMode(osg::StateAttribute::CULLFACE,osg::StateAttribute::OFF);
CULLFACE的开关作为前后向渲染的设置不知对否?
还有一个问题就是和楼主一样的,对节点前后渲染时用到了GLSL,想把glsl渲染得到的作为一个二维纹理图保存下来,然后传给另外一结点,不知该如何来做?目前是想用一个camera,进行RTT,不知可不可行?

该用户从未签到

 楼主| 发表于 2010-6-5 21:19:43 | 显示全部楼层
找到glsldemo中写的代码了:
    //
    // Grab the frame buffer to enable cool effects like glass and haze.
    // Create a 2048x2048 texture for it, since that's a reasonable power-of-two.
    // Note this fails to grab everything for viewports bigger than 2048x2048.
    //
    if (id == Id::TextureFramebuffer) {
        const int size = 2048;
        if (!texture.glid) {
            glGenTextures(1, &texture.glid);
            glBindTexture(GL_TEXTURE_2D, texture.glid);
            glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, size, size, 0);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        } else {
            glBindTexture(GL_TEXTURE_2D, texture.glid);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
            wxSize s = wxGetApp().GetCanvasSize();
            int w = (int) s.GetWidth();
            int h = (int) s.GetHeight();
            w = w < size ? w : (int) size;
            h = h < size ? h : (int) size;
            glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, w, h);
        }
        return;
    }

该用户从未签到

发表于 2010-6-5 21:27:44 | 显示全部楼层
这个glid是什么东西呢?id是指什么了?谢谢

该用户从未签到

发表于 2010-6-7 08:21:23 | 显示全部楼层
这里的FrameBuffer其实就是一幅普通的纹理图片,不过它应该是使用RTT渲染场景到纹理后得到的,您可以用Camera::attach()来渲染OSG场景到纹理当中

该用户从未签到

发表于 2010-6-7 14:13:17 | 显示全部楼层
嗯,我也是这么做的,但是程序运行之后出现访问冲突的问题,不知道怎么回事?下面是我的代码:
osg::Texture2D *backtexture(osg::ref_ptr<osg::Node> terrainnode)
{
        int tex_width = 128;
        int tex_height = 128;
//        osg::Texture* texture = 0;

        osg::Texture2D* texture2D = new osg::Texture2D;
    texture2D->setTextureSize(tex_width, tex_height);
    texture2D->setInternalFormat(GL_RGBA);
    texture2D->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D:INEAR);
    texture2D->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
        texture2D->setDataVariance(osg::Object:YNAMIC);
//    texture = texture2D;

        //        代码代码
        osg::ref_ptr<osg::Group> group = new osg::Group;

        osg::ref_ptr<osg::Node> node = new osg::Node;
        node = terrainnode;
       
        osg::StateSet* stateset = node->getOrCreateStateSet();
        stateset->setMode(osg::StateAttribute::CULLFACE,osg::StateAttribute::ON);

        osg::Camera *camera = new osg::Camera();
        camera->setClearMask(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

        const osg::BoundingSphere& bs = terrainnode->getBound();
    if (!bs.valid())
    {
                std::cout<<"the box is not valid!"<<std::endl;
    }

    float znear = 1.0f*bs.radius();
    float zfar  = 3.0f*bs.radius();

        // 2:1 aspect ratio as per flag geometry below.
    float proj_top   = 0.25f*znear;
    float proj_right = 0.5f*znear;

    znear *= 0.9f;
    zfar *= 1.1f;
        // set up projection.
        camera->setViewport(0,0,tex_width,tex_height);
    camera->setProjectionMatrixAsFrustum(-proj_right,proj_right,-proj_top,proj_top,znear,zfar);
    // set view
    camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
        camera->setViewMatrixAsLookAt(bs.center()+osg::Vec3(0.0f,0.0f,0.5f)*bs.radius(),bs.center()+osg::Vec3(0.0f,0.0f,10000.0f),osg::Vec3(0.0f,0.0f,-1.0f));
        camera->setRenderOrder(osg::Camera:RE_RENDER);
        camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);

        osg::Shader* vertexShader = new osg::Shader( osg::Shader::VERTEX );
        osg::Shader* fragmentShader = new osg::Shader( osg::Shader::FRAGMENT );
        vertexShader->loadShaderSourceFromFile( "depth.vert" );
        fragmentShader->loadShaderSourceFromFile( "depth.frag" );
        osg::Program* program = new osg::Program;
        program->addShader( vertexShader );
        program->addShader( fragmentShader);
        stateset->setAttributeAndModes( program, osg::StateAttribute::ON );

        osg::Uniform* param1 = new osg::Uniform( "depthOffset", 0.01f);
        stateset->addUniform( param1 );

    osg::Uniform* param2 = new osg::Uniform( "pNear", znear);
        stateset->addUniform( param2 );

        osg::Uniform* param3 = new osg::Uniform( "pFar", zfar);
        stateset->addUniform( param3 );
        camera->attach(osg::Camera::COLOR_BUFFER,texture2D,0,0,false,0,0);

        camera->addChild(node.get());       
        group->addChild(camera);
       
        return texture2D;
}

该用户从未签到

 楼主| 发表于 2010-6-7 14:48:13 | 显示全部楼层
6# wojiushiwo

你用的这个shader貌似不包含FrameBuffer啊。

该用户从未签到

发表于 2010-6-7 15:10:16 | 显示全部楼层
7# lvzhihan
什么意思呢?就是想把场景前向渲染和背向渲染存为一个2D纹理,然后作为参数传入另一个shader里。

该用户从未签到

发表于 2010-6-7 16:44:05 | 显示全部楼层
camera节点被传递给谁了?如果它没有传递给任何节点的话,那是不允许的。还有我怎么觉得我回答过同一个问题

该用户从未签到

发表于 2010-6-7 17:34:09 | 显示全部楼层
9# array
camera传递给了一个group节点,然后把这个group附给根节点,不知道哪里出错?谢谢

该用户从未签到

发表于 2010-6-8 08:11:56 | 显示全部楼层
然后把这个group附给根节点
我并没有在您的代码中看到这一过程

该用户从未签到

 楼主| 发表于 2010-6-8 10:37:18 | 显示全部楼层
array,我想把这一段直接放到我的程序里,该怎么跟纹理绑定:
int glid;
glGenTextures(1, glid);
            glBindTexture(GL_TEXTURE_2D, &glid);
            glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, size, size, 0);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

该用户从未签到

发表于 2010-6-8 12:51:46 | 显示全部楼层
其实就是类似这样的过程:
  1. camera->attach(COLOR_BUFFER, texture);
  2. node->setTextureAttributeAndModes(0, texture);
复制代码

该用户从未签到

 楼主| 发表于 2010-6-8 14:27:47 | 显示全部楼层
13# array

谢谢,我先试试
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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