//-------------------------------------------------------------------------- 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); } } }