Пример #1
0
    //--------------------------------------------------------------------------
    void UnitInMipmapOut::createAndAttachFBOs(osg::Texture* output, int mrt)
    {
        // check if the texture is 2D texture
        if (dynamic_cast<osg::Texture2D*>(output) == NULL)
        {
            osg::notify(osg::WARN) << "osgPPU::UnitInMipmapOut::createAndAttachFBOs() - currently only 2D textures are supported" << std::endl;
            return;
        }

        // check if we have generated all the fbo's for each mipmap level
        int width = output->getTextureWidth();
        int height = output->getTextureHeight();
        int mwh = std::max(width, height);
        int numLevel = 1 + static_cast<int>(floor(logf(mwh)/logf(2.0f)));

        // set new sizes
        mOutputWidth = width;
        mOutputHeight = height;
        mNumLevels = numLevel;

        // if we do not use shader, then return
        if (mUseShader == false) return;

        // generate fbo and viewport for each mipmap level if not done before
        if ((int)mMipmapFBO.size() != numLevel)
        {
            // generate mipmap levels
            mMipmapFBO.clear();
            mMipmapViewport.clear();
            mMipmapDrawable.clear();
            for (int i=0; i < numLevel; i++)
            {
                // generate viewport for the mipmap level
                osg::ref_ptr<osg::Viewport> vp = new osg::Viewport();
                int w = std::max(1, (int)floor(float(width) / float(pow(2.0f, (float)i)) ));
                int h = std::max(1, (int)floor(float(height) / float(pow(2.0f, (float)i)) ));
                vp->setViewport(0,0, (osg::Viewport::value_type)w, (osg::Viewport::value_type)h);
                mMipmapViewport.push_back(vp);
                
                // generate fbo and assign a mipmap level to it
				osg::ref_ptr<FrameBufferObject> fbo = new FrameBufferObject();
                fbo->setAttachment(osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER0 + mrt), osg::FrameBufferAttachment(dynamic_cast<osg::Texture2D*>(output), i));
                mMipmapFBO.push_back(fbo);

                // generate drawable which is responsible for this level
                osg::Drawable* draw = createTexturedQuadDrawable();
                osg::StateSet* ss = draw->getOrCreateStateSet();
                ss->setAttribute(vp, osg::StateAttribute::ON);
                //ss->setAttribute(fbo, osg::StateAttribute::ON);
                mMipmapDrawable.push_back(draw);
            }
        }
    }
    //------------------------------------------------------------------------------
    void UnitMipmapInMipmapOut::checkIOMipmappedData()
    {
        if (mOutputTex.size() > 0)
        {
            // do only proceed if output texture is valid
            if (mOutputTex.begin()->second == NULL) return;
    
            // clean viewport data
            mIOMipmapViewport.clear();
            mIOMipmapFBO.clear();
            mIOMipmapDrawable.clear();

            // get dimensions of the output data
            int width = (mOutputTex.begin()->second)->getTextureWidth();
            int height = (mOutputTex.begin()->second)->getTextureHeight();
            int mwh = std::max(width, height);
            int numLevels = 1 + static_cast<int>(floor(logf(mwh)/logf(2.0f)));
    
            // generate fbo for each mipmap level 
            for (int level=0; level < numLevels; level++)
            {
                // generate viewport for this level
                osg::ref_ptr<osg::Viewport> vp = new osg::Viewport();
                int w = std::max(1, (int)floor(float(width) / float(pow(2.0f, (float)level)) ));
                int h = std::max(1, (int)floor(float(height) / float(pow(2.0f, (float)level)) ));
                vp->setViewport(0,0, (osg::Viewport::value_type)w, (osg::Viewport::value_type)h);
                mIOMipmapViewport.push_back(vp);
    
                // this is the fbo for this level 
				osg::ref_ptr<FrameBufferObject> fbo = new FrameBufferObject();
    
                // for each output texture do
                std::map<int, osg::ref_ptr<osg::Texture> >::iterator it = mOutputTex.begin();
                for (int mrt = 0; it != mOutputTex.end(); it++, mrt++)
                {   
                    // output texture 
                    osg::ref_ptr<osg::Texture2D> output = dynamic_cast<osg::Texture2D*>(it->second.get());
        
                    // check if we have generated all the fbo's for each mipmap level
                    int _width = output->getTextureWidth();
                    int _height = output->getTextureHeight();
    
                    // if width and height are not equal, then we give some error and stop here 
                    if ((_width != width || _height != height))
                    {
                        osg::notify(osg::FATAL) << "osgPPU::UnitInOut::checkIOMipmappedData() - " << getName() << ": output textures has different dimensions" << std::endl;
                        return; 
                    }
        
                    // set fbo of current level with to this output         
                    fbo->setAttachment(osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER0 + mrt), osg::FrameBufferAttachment(output.get(), level));
                }
    
                // store fbo
                mIOMipmapFBO.push_back(fbo);

                // generate mipmap drawables
                osg::Drawable* draw = createTexturedQuadDrawable();
                osg::StateSet* ss = draw->getOrCreateStateSet();
                ss->setAttribute(vp, osg::StateAttribute::ON);
                //ss->setAttribute(fbo, osg::StateAttribute::ON);
                mIOMipmapDrawable.push_back(draw);
            }
        }
    }