void ShaderShadowMapEngine::updatePointLightRenderTargets(SSMEngineData *data) { if(data->getMFRenderTargets()->empty() == true) { for(UInt16 i = 0; i < 6; ++i) { FrameBufferObjectUnrecPtr newTarget = FrameBufferObject::createLocal(); newTarget->setWidth (this->getWidth ( )); newTarget->setHeight (this->getHeight ( )); newTarget->setDepthAttachment(data->getShadowTexBuffers(i)); data->editMFRenderTargets()->push_back(newTarget); } } else { for(UInt16 i = 0; i < 6; ++i) { FrameBufferObject *target = data->getRenderTargets(i); if((target->getWidth () != this->getWidth ()) || (target->getHeight() != this->getHeight()) ) { target->setWidth (this->getWidth ()); target->setHeight(this->getHeight()); } } } }
FrameBufferObjectTransitPtr FBOBuilder::operator()( UInt32 width, UInt32 height) const { // // Setup the FBO // FrameBufferObjectUnrecPtr fbo = FrameBufferObject::create(); // // multiple color buffers // for (UINT32 idx = 0; idx < _buffers.size(); ++idx) { // // use textures? // if (_buffers[idx].enable) { ImageUnrecPtr texImg = (_buffers[idx].image == nullptr ? Image::create() : _buffers[idx].image); TextureObjChunkUnrecPtr texObj = (_buffers[idx].texObj == nullptr ? TextureObjChunk::create() : _buffers[idx].texObj); TextureBufferUnrecPtr texBuf = TextureBuffer::create(); if (_buffers[idx].image == nullptr) texImg->set(_buffers[idx].pixel_format, width, height, 1, 1, 1, 0.f, nullptr, _buffers[idx].type, _buffers[idx].main_memory); texObj->setImage(texImg); texBuf->setTexture(texObj); fbo->setColorAttachment(texBuf, idx); } else // // no, then use simple render buffer // { RenderBufferUnrecPtr renBuf = RenderBuffer::create(); renBuf->setInternalFormat(_buffers[idx].pixel_format); fbo->setColorAttachment(renBuf, idx); } fbo->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT + idx); } // // a sole depth buffer // if (_depth && !_stencil) { // // use textures? // if (_ds_buffer.enable) { ImageUnrecPtr texImg = (_ds_buffer.image == nullptr ? Image::create() : _ds_buffer.image); TextureObjChunkUnrecPtr texObj = (_ds_buffer.texObj == nullptr ? TextureObjChunk::create() : _ds_buffer.texObj); TextureBufferUnrecPtr texBuf = TextureBuffer::create(); if (_ds_buffer.image == nullptr) texImg->set(_ds_buffer.pixel_format, width, height, 1, 1, 1, 0.f, nullptr, _ds_buffer.type, _ds_buffer.main_memory); texObj->setImage(texImg); if (_ds_buffer.texObj == nullptr) { texObj->setInternalFormat(GL_DEPTH_COMPONENT24); texObj->setExternalFormat(GL_DEPTH_COMPONENT24); } texBuf->setTexture(texObj); fbo->setDepthAttachment(texBuf); } else // // no, then use simple render buffer // { RenderBufferUnrecPtr renBuf = RenderBuffer::create(); renBuf->setInternalFormat(GL_DEPTH_COMPONENT24); fbo->setDepthAttachment(renBuf); } } else // // or a combined depth/stencil buffer // if (_depth && _stencil) { // // use textures? // if (_ds_buffer.enable) { ImageUnrecPtr texImg = (_ds_buffer.image == nullptr ? Image::create() : _ds_buffer.image); TextureObjChunkUnrecPtr texObj = (_ds_buffer.texObj == nullptr ? TextureObjChunk::create() : _ds_buffer.texObj); TextureBufferUnrecPtr texBuf = TextureBuffer::create(); if (_ds_buffer.image == nullptr) texImg->set(GL_DEPTH_STENCIL_EXT, width, height, 1, 1, 1, 0.f, nullptr, GL_UNSIGNED_INT_24_8, _ds_buffer.main_memory); texObj->setImage(texImg); texObj->setInternalFormat(GL_DEPTH24_STENCIL8_EXT); texObj->setExternalFormat(GL_DEPTH_STENCIL_EXT); texBuf->setTexture(texObj); fbo->setDepthAttachment(texBuf); fbo->setStencilAttachment(texBuf); } else // // no, then use simple render buffer // { RenderBufferUnrecPtr renBuf = RenderBuffer::create(); renBuf->setInternalFormat(GL_DEPTH24_STENCIL8); fbo->setDepthAttachment(renBuf); fbo->setStencilAttachment(renBuf); } } fbo->setWidth (width ); fbo->setHeight(height); return FrameBufferObjectTransitPtr(fbo); }
DepthPeelingStageDataTransitPtr DepthPeelingStage::setupStageData(Int32 iPixelWidth, Int32 iPixelHeight) { DepthPeelingStageDataTransitPtr returnValue = DepthPeelingStageData::createLocal(); if(returnValue == NULL) return returnValue; OSG::Thread::setCurrentLocalFlags(); //Depth, Blend chunks and Background in Data? DepthChunkUnrecPtr pDepthOffChunk = DepthChunk::createLocal(); pDepthOffChunk->setEnable(false); DepthChunkUnrecPtr pDepthOnChunk = DepthChunk::createLocal(); pDepthOnChunk->setEnable(true); returnValue->setDepthChunk(pDepthOnChunk); ShaderProgramVariableChunkUnrecPtr pSPVChunk1 = ShaderProgramVariableChunk::createLocal(); pSPVChunk1->addUniformVariable("uIsPeelPass", true); returnValue->setSpvIsPeelChunk(pSPVChunk1); ShaderProgramVariableChunkUnrecPtr pSPVChunk2 = ShaderProgramVariableChunk::createLocal(); pSPVChunk2->addUniformVariable("uIsPeelPass", false); returnValue->setSpvIsInitialChunk(pSPVChunk2); BlendChunkUnrecPtr pBlendChunk = BlendChunk::createLocal(); pBlendChunk->setSrcFactor(GL_DST_ALPHA); pBlendChunk->setDestFactor(GL_ONE); pBlendChunk->setAlphaSrcFactor(GL_ZERO); pBlendChunk->setAlphaDestFactor(GL_ONE_MINUS_SRC_ALPHA); pBlendChunk->setEquation(GL_FUNC_ADD); SolidBackgroundUnrecPtr pSolidBackground = SolidBackground::createLocal(); pSolidBackground->setColor(Color3f(0.f, 0.f, 0.f)); pSolidBackground->setAlpha(0.f); returnValue->setBackground(pSolidBackground); SimpleSHLChunkUnrecPtr pQuadShader = SimpleSHLChunk::createLocal(); pQuadShader->setFragmentProgram(std::string(blendFS)); pQuadShader->addUniformVariable("uSampler", 0); //2 FBOs (Ping-Pong) FrameBufferObjectUnrecPtr pPeelFBOs[2]; TextureBufferUnrecPtr pPeelColorTexBuffers[2]; TextureBufferUnrecPtr pPeelDepthTexBuffers[2]; TextureObjChunkUnrecPtr pColorTexs[2]; ImageUnrecPtr pColorImgs[2]; TextureObjChunkUnrecPtr pDepthTexs[2]; ImageUnrecPtr pDepthImgs[2]; for (int i=0; i<2; ++i) { //Color textures pColorTexs[i] = TextureObjChunk::createLocal(); pColorImgs[i] = Image ::createLocal(); pColorImgs[i]->set(Image::OSG_RGBA_PF, iPixelWidth, iPixelHeight, 1, 1, 1, 0.0, 0, Image::OSG_FLOAT32_IMAGEDATA, false); pColorTexs[i] ->setImage (pColorImgs[i] ); pColorTexs[i] ->setMinFilter (GL_NEAREST ); pColorTexs[i] ->setMagFilter (GL_NEAREST ); pColorTexs[i] ->setWrapS (GL_CLAMP_TO_EDGE ); pColorTexs[i] ->setWrapT (GL_CLAMP_TO_EDGE ); pColorTexs[i] ->setInternalFormat(GL_RGBA8); pPeelColorTexBuffers[i] = TextureBuffer::createLocal(); pPeelColorTexBuffers[i]->setTexture(pColorTexs[i]); //Depth textures pDepthTexs[i] = TextureObjChunk::createLocal(); pDepthImgs[i] = Image ::createLocal(); pDepthImgs[i]->set(Image::OSG_DEPTH_PF, iPixelWidth, iPixelHeight, 1, 1, 1, 0.0, 0, Image::OSG_FLOAT32_IMAGEDATA, false); pDepthTexs[i] ->setImage (pDepthImgs[i] ); pDepthTexs[i] ->setMinFilter (GL_NEAREST ); pDepthTexs[i] ->setMagFilter (GL_NEAREST ); pDepthTexs[i] ->setWrapS (GL_CLAMP_TO_EDGE ); pDepthTexs[i] ->setWrapT (GL_CLAMP_TO_EDGE ); pDepthTexs[i] ->setInternalFormat(GL_DEPTH_COMPONENT32F); pDepthTexs[i] ->setExternalFormat(GL_DEPTH_COMPONENT); pPeelDepthTexBuffers[i] = TextureBuffer::createLocal(); pPeelDepthTexBuffers[i]->setTexture(pDepthTexs[i]); pPeelFBOs[i] = FrameBufferObject::createLocal(); pPeelFBOs[i]->setSize(iPixelWidth, iPixelHeight); pPeelFBOs[i]->setColorAttachment(pPeelColorTexBuffers[i], 0); pPeelFBOs[i]->setDepthAttachment(pPeelDepthTexBuffers[i]); pPeelFBOs[i]->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT); //Peel material for Quad (!) ChunkMaterialUnrecPtr pPeelMat = ChunkMaterial ::createLocal(); pPeelMat->addChunk(pQuadShader, 0); pPeelMat->addChunk(pColorTexs[i], 0); pPeelMat->addChunk(pDepthOffChunk); pPeelMat->addChunk(pBlendChunk); if (i == 0) { returnValue->setPeelPingFBO(pPeelFBOs[i]); returnValue->setPeelPingMaterial(pPeelMat); } else { returnValue->setPeelPongFBO(pPeelFBOs[i]); returnValue->setPeelPongMaterial(pPeelMat); } } // The final color blend target FrameBufferObjectUnrecPtr pBlendFBO = FrameBufferObject::createLocal(); //Color texture TextureObjChunkUnrecPtr pBlendColorTex = TextureObjChunk::createLocal(); ImageUnrecPtr pBlendColorImg = Image ::createLocal(); pBlendColorImg->set(Image::OSG_RGBA_PF, iPixelWidth, iPixelHeight, 1, 1, 1, 0.0, 0, Image::OSG_FLOAT32_IMAGEDATA, false); pBlendColorTex->setImage (pBlendColorImg ); pBlendColorTex->setMinFilter (GL_NEAREST ); pBlendColorTex->setMagFilter (GL_NEAREST ); pBlendColorTex->setWrapS (GL_CLAMP_TO_EDGE ); pBlendColorTex->setWrapT (GL_CLAMP_TO_EDGE ); pBlendColorTex->setInternalFormat(GL_RGBA8); TextureBufferUnrecPtr pBlendColorTexBuffer = TextureBuffer::createLocal(); pBlendColorTexBuffer->setTexture(pBlendColorTex); TextureBufferUnrecPtr pBlendDepthTexBuffer = TextureBuffer::createLocal(); pBlendDepthTexBuffer->setTexture(pDepthTexs[0]); pBlendFBO->setSize(iPixelWidth, iPixelHeight); pBlendFBO->setColorAttachment(pBlendColorTexBuffer, 0); pBlendFBO->setDepthAttachment(pBlendDepthTexBuffer); pBlendFBO->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT); returnValue->setBlendFBO(pBlendFBO); // Blend Final Material ChunkMaterialUnrecPtr pBlendFinalMat = ChunkMaterial::createLocal(); pBlendFinalMat->addChunk(pDepthOffChunk); pBlendFinalMat->addChunk(pBlendColorTex, 0); SimpleSHLChunkUnrecPtr pBlendFinalShader = SimpleSHLChunk::createLocal(); pBlendFinalShader->setFragmentProgram(std::string(blendFinalFS)); pBlendFinalShader->addUniformVariable("uSampler", 0); pBlendFinalMat->addChunk(pBlendFinalShader, 0); returnValue->setBlendFinalMaterial(pBlendFinalMat); OSG::Thread::resetCurrentLocalFlags(); Thread::getCurrentChangeList()->commitChanges(); return returnValue; }
PostShaderStageDataTransitPtr PostShaderStage::setupStageData(Int32 iPixelWidth, Int32 iPixelHeight) { PostShaderStageDataTransitPtr returnValue = PostShaderStageData::createLocal(); if(returnValue == NULL) return returnValue; OSG::Thread::setCurrentLocalFlags(); // Scene Target FrameBufferObjectUnrecPtr pSceneFBO = FrameBufferObject::createLocal(); //Depth texture _pSceneDepthTex = TextureObjChunk::createLocal(); TextureEnvChunkUnrecPtr pSceneDepthTexEnv = TextureEnvChunk::createLocal(); ImageUnrecPtr pDepthImg = Image ::createLocal(); pDepthImg->set(Image::OSG_L_PF, iPixelWidth, iPixelHeight, 1, 1, 1, 0.0, NULL, Image::OSG_UINT8_IMAGEDATA, false); _pSceneDepthTex ->setImage (pDepthImg ); _pSceneDepthTex ->setMinFilter (GL_LINEAR ); _pSceneDepthTex ->setMagFilter (GL_LINEAR ); _pSceneDepthTex ->setWrapS (GL_CLAMP_TO_EDGE ); _pSceneDepthTex ->setWrapT (GL_CLAMP_TO_EDGE ); _pSceneDepthTex ->setInternalFormat(GL_DEPTH_COMPONENT); _pSceneDepthTex ->setExternalFormat(GL_DEPTH_COMPONENT); pSceneDepthTexEnv->setEnvMode (GL_REPLACE ); TextureBufferUnrecPtr pDepthBuffer = TextureBuffer::createLocal(); //pDepthBuffer->setInternalFormat(GL_DEPTH_COMPONENT24 ); pDepthBuffer->setTexture(_pSceneDepthTex); //Color Buffer _pSceneTex = TextureObjChunk::createLocal(); TextureEnvChunkUnrecPtr pSceneTexEnv = TextureEnvChunk::createLocal(); ImageUnrecPtr pImg = Image ::createLocal(); pImg->set(Image::OSG_RGB_PF, iPixelWidth, iPixelHeight, 1, 1, 1, 0.0, 0, Image::OSG_UINT8_IMAGEDATA, false); _pSceneTex ->setImage (pImg ); _pSceneTex ->setMinFilter (GL_LINEAR ); _pSceneTex ->setMagFilter (GL_LINEAR ); _pSceneTex ->setWrapS (GL_CLAMP_TO_EDGE ); _pSceneTex ->setWrapT (GL_CLAMP_TO_EDGE ); _pSceneTex ->setInternalFormat(getColorBufferFormat()); pSceneTexEnv->setEnvMode (GL_REPLACE ); TextureBufferUnrecPtr pSceneTexBuffer = TextureBuffer::createLocal(); pSceneTexBuffer->setTexture(_pSceneTex); pSceneFBO->setSize(iPixelWidth, iPixelHeight); pSceneFBO->setColorAttachment(pSceneTexBuffer, 0); pSceneFBO->setDepthAttachment(pDepthBuffer ); pSceneFBO->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT); setRenderTarget(pSceneFBO); // general mat chunk //Init all of the render passes _vPostProcessPasses.clear(); UInt32 NumPasses = getNumPasses(); for(UInt32 i =0; i != NumPasses ; ++i) { _vPostProcessPasses.push_back( RenderPassData::create( getVertexShaders(i), getFragmentShaders(i), (i == NumPasses-1), i, iPixelWidth, iPixelHeight, returnValue.get(), getPassSizes(i), _pSceneTex, _pSceneDepthTex, _vPostProcessPasses, pSceneFBO)); } OSG::Thread::resetCurrentLocalFlags(); Thread::getCurrentChangeList()->commitChanges(); return returnValue; }
HDRStageDataTransitPtr HDRStage::setupStageData(Int32 iPixelWidth, Int32 iPixelHeight) { HDRStageDataTransitPtr returnValue = HDRStageData::createLocal(); if(returnValue == NULL) return returnValue; OSG::Thread::setCurrentLocalFlags(); // Scene Target FrameBufferObjectUnrecPtr pSceneFBO = FrameBufferObject::createLocal(); RenderBufferUnrecPtr pDepthBuffer = RenderBuffer ::createLocal(); pDepthBuffer->setInternalFormat(GL_DEPTH_COMPONENT24 ); TextureObjChunkUnrecPtr pSceneTex = TextureObjChunk::createLocal(); TextureEnvChunkUnrecPtr pSceneTexEnv = TextureEnvChunk::createLocal(); ImageUnrecPtr pImg = Image ::createLocal(); pImg->set(Image::OSG_RGB_PF, iPixelWidth, iPixelHeight, 1, 1, 1, 0.0, 0, Image::OSG_FLOAT32_IMAGEDATA, false); pSceneTex ->setImage (pImg ); pSceneTex ->setMinFilter (GL_LINEAR ); pSceneTex ->setMagFilter (GL_LINEAR ); pSceneTex ->setWrapS (GL_CLAMP_TO_EDGE ); pSceneTex ->setWrapT (GL_CLAMP_TO_EDGE ); pSceneTex ->setInternalFormat(getBufferFormat()); pSceneTexEnv->setEnvMode (GL_REPLACE ); TextureBufferUnrecPtr pSceneTexBuffer = TextureBuffer::createLocal(); pSceneTexBuffer->setTexture(pSceneTex); pSceneFBO->setSize(iPixelWidth, iPixelHeight); pSceneFBO->setColorAttachment(pSceneTexBuffer, 0); pSceneFBO->setDepthAttachment(pDepthBuffer ); pSceneFBO->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT); setRenderTarget(pSceneFBO); // Shrink Target (w/2, h/2) FrameBufferObjectUnrecPtr pShrinkFBO = FrameBufferObject::createLocal(); TextureObjChunkUnrecPtr pShrinkTex = TextureObjChunk::createLocal(); TextureEnvChunkUnrecPtr pShrinkTexEnv = TextureEnvChunk::createLocal(); pImg = Image ::createLocal(); pImg->set(Image::OSG_RGB_PF, iPixelWidth / 2, iPixelHeight / 2, 1, 1, 1, 0.0, 0, Image::OSG_FLOAT32_IMAGEDATA, false); pShrinkTex ->setImage (pImg ); pShrinkTex ->setMinFilter (GL_LINEAR ); pShrinkTex ->setMagFilter (GL_LINEAR ); pShrinkTex ->setWrapS (GL_CLAMP_TO_EDGE ); pShrinkTex ->setWrapT (GL_CLAMP_TO_EDGE ); pShrinkTex ->setInternalFormat(getBufferFormat()); pShrinkTexEnv->setEnvMode (GL_REPLACE ); TextureBufferUnrecPtr pShrinkTexBuffer = TextureBuffer::createLocal(); pShrinkTexBuffer->setTexture(pShrinkTex); pShrinkFBO->setSize(iPixelWidth / 2, iPixelHeight / 2); pShrinkFBO->setColorAttachment(pShrinkTexBuffer, 0); pShrinkFBO->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT); returnValue->setShrinkRenderTarget(pShrinkFBO); // blur (w/4, h/4) FrameBufferObjectUnrecPtr pBlurFBO = FrameBufferObject::createLocal(); TextureObjChunkUnrecPtr pBlurTex1 = TextureObjChunk ::createLocal(); TextureEnvChunkUnrecPtr pBlurTex1Env = TextureEnvChunk ::createLocal(); pImg = Image::createLocal(); pImg->set(Image::OSG_RGB_PF, iPixelWidth / 4, iPixelHeight / 4, 1, 1, 1, 0.0, 0, Image::OSG_FLOAT32_IMAGEDATA, false); pBlurTex1 ->setImage (pImg ); pBlurTex1 ->setMinFilter (GL_LINEAR ); pBlurTex1 ->setMagFilter (GL_LINEAR ); pBlurTex1 ->setWrapS (GL_CLAMP_TO_EDGE ); pBlurTex1 ->setWrapT (GL_CLAMP_TO_EDGE ); pBlurTex1 ->setInternalFormat(getBufferFormat()); pBlurTex1Env->setEnvMode (GL_REPLACE ); TextureBufferUnrecPtr pBlurTexBuffer1 = TextureBuffer::createLocal(); pBlurTexBuffer1->setTexture(pBlurTex1); TextureObjChunkUnrecPtr pBlurTex2 = TextureObjChunk::createLocal(); TextureEnvChunkUnrecPtr pBlurTex2Env = TextureEnvChunk::createLocal(); pImg = Image::createLocal(); pImg->set(Image::OSG_RGB_PF, iPixelWidth / 4, iPixelHeight / 4, 1, 1, 1, 0.0, 0, Image::OSG_FLOAT32_IMAGEDATA, false); pBlurTex2 ->setImage (pImg ); pBlurTex2 ->setMinFilter (GL_LINEAR ); pBlurTex2 ->setMagFilter (GL_LINEAR ); pBlurTex2 ->setWrapS (GL_CLAMP_TO_EDGE ); pBlurTex2 ->setWrapT (GL_CLAMP_TO_EDGE ); pBlurTex2 ->setInternalFormat(getBufferFormat()); pBlurTex2Env->setEnvMode (GL_REPLACE ); TextureBufferUnrecPtr pBlurTexBuffer2 = TextureBuffer::createLocal(); pBlurTexBuffer2->setTexture(pBlurTex2); pBlurFBO->setSize(iPixelWidth / 4, iPixelHeight / 4); pBlurFBO->setColorAttachment(pBlurTexBuffer1, 0); pBlurFBO->setColorAttachment(pBlurTexBuffer2, 1); returnValue->setBlurRenderTarget(pBlurFBO); // general mat chunk MaterialChunkUnrecPtr pMatChunk = MaterialChunk::createLocal(); pMatChunk->setLit(false); // tone map material ChunkMaterialUnrecPtr pTonemapMat = ChunkMaterial ::createLocal(); pTonemapMat->addChunk(pMatChunk ); pTonemapMat->addChunk(pSceneTex, 0); pTonemapMat->addChunk(pSceneTexEnv, 0); pTonemapMat->addChunk(pBlurTex1, 1); pTonemapMat->addChunk(pBlurTex1Env, 1); SimpleSHLChunkUnrecPtr pTonemapShader = generateHDRFragmentProgram(); pTonemapShader->addUniformVariable("sceneTex", 0); pTonemapShader->addUniformVariable("blurTex", 1); pTonemapShader->addUniformVariable("blurAmount", getBlurAmount ()); pTonemapShader->addUniformVariable("exposure", getExposure ()); pTonemapShader->addUniformVariable("effectAmount", getEffectAmount()); pTonemapShader->addUniformVariable("gamma", getGamma ()); pTonemapMat->addChunk(pTonemapShader, 0); returnValue->setToneMappingMaterial(pTonemapMat); // Shrink material ChunkMaterialUnrecPtr pShrinkMat = ChunkMaterial::createLocal(); pShrinkMat->addChunk(pMatChunk ); pShrinkMat->addChunk(pSceneTex, 0); pShrinkMat->addChunk(pSceneTexEnv, 0); SimpleSHLChunkUnrecPtr pShrinkShader = generate2DShrinkHalfFilterFP(); pShrinkShader->addUniformVariable("inputTex", 0); pShrinkMat->addChunk(pShrinkShader, 0); returnValue->setShrinkMaterial(pShrinkMat); // Blur material ChunkMaterialUnrecPtr pBlurMat = ChunkMaterial::createLocal(); pBlurMat->addChunk(pMatChunk ); pBlurMat->addChunk(pShrinkTex, 0); pBlurMat->addChunk(pShrinkTexEnv, 0); pBlurMat->addChunk(pBlurTex1, 1); pBlurMat->addChunk(pBlurTex1Env, 1); pBlurMat->addChunk(pBlurTex2, 2); pBlurMat->addChunk(pBlurTex2Env, 2); pBlurMat->addChunk(pShrinkShader, 0); returnValue->setBlurMaterial(pBlurMat); // generate blur fragment programs SimpleSHLChunkUnrecPtr pHBlurShader = generate1DConvolutionFilterFP(getBlurWidth(), false, true, iPixelWidth / 2, iPixelHeight / 2); pHBlurShader->addUniformVariable("inputTex", 0); returnValue->setHBlurShader(pHBlurShader); // VBlur Override SimpleSHLChunkUnrecPtr pVBlurShader = generate1DConvolutionFilterFP(getBlurWidth(), true, true, iPixelWidth / 2, iPixelHeight / 2); pVBlurShader->addUniformVariable("inputTex", 1); returnValue->setVBlurShader(pVBlurShader); OSG::Thread::resetCurrentLocalFlags(); Thread::getCurrentChangeList()->commitChanges(); return returnValue; }
// // FBO solution // static void writeHiResScreenShotFBO(const char* name, UInt32 width, UInt32 height) { size_t num_ports = win->getMFPort()->size(); if (num_ports == 0) return; // // calc image dimensions // UInt32 winWidth = win->getWidth(); UInt32 winHeight = win->getHeight(); if (width < winWidth ) width = winWidth; if (height < winHeight) height = winHeight; Real32 a = Real32(winWidth) / Real32(winHeight); width = UInt32(a*height); // // output stream for writing the final image // std::ofstream stream(name, std::ios::binary); if (stream.good() == false) return; // // Setup the FBO // FrameBufferObjectUnrecPtr fbo = FrameBufferObject::create(); // // We use two render buffers. One for the color buffer and one for the depth and // stencil buffer. This example does not take credit of the stencil buffer. There- // fore a depth buffer would suffice. However, the use of the combined depth and // stencil buffer is useful in other contextes and hence used. // RenderBufferUnrecPtr colBuf = RenderBuffer::create(); RenderBufferUnrecPtr dsBuf = RenderBuffer::create(); // // As we would like to read back the FBO color buffer, we must provide a fitting // image. // ImageUnrecPtr buffer_image = Image::create(); buffer_image->set(Image::OSG_RGBA_PF, winWidth, winHeight); colBuf->setImage(buffer_image); // // We must setup the internal image formats of the two render buffers accordingly. // colBuf->setInternalFormat(GL_RGBA); dsBuf ->setInternalFormat(GL_DEPTH24_STENCIL8_EXT); // // we must inform the FBO about the actual used color render buffers. // fbo->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT); // // The FBO takes responsibility of the render buffers. Notice, that the shared // depth/stencil buffer is provided twice. As the depth render buffer and as the // stencil render buffer. // fbo->setColorAttachment (colBuf, 0); fbo->setDepthAttachment (dsBuf); fbo->setStencilAttachment(dsBuf); // // Also the FBO must be sized correctly. // fbo->setWidth (winWidth ); fbo->setHeight(winHeight); // // In order to read the color buffer back next two statements are necessary. // fbo->setPostProcessOnDeactivate(true); fbo->getColorAttachments(0)->setReadBack(true); // // We tile the final image and render each tile with the screen resolution // into the FBO. The more tiles we use the bigger the resolution of the // final image gets with respect to a provided measure of length. // typedef boost::tuple<TileCameraDecoratorUnrecPtr, bool, SimpleStageUnrecPtr, ViewportUnrecPtr> TupleT; std::vector<TupleT> decorators; decorators.resize(num_ports); // // Remember the stage viewports for later cleanup // std::stack<ViewportUnrecPtr> stage_viewports; // // Setup the tile camera decorators for each viewport of the window and // disable the tile property of tileable viewport backgrounds. // for (size_t i = 0; i < num_ports; ++i) { Viewport* vp = win->getPort(i); TileCameraDecoratorUnrecPtr decorator = TileCameraDecorator::create(); decorator->setFullSize (width, height); decorator->setDecoratee(vp->getCamera()); vp->setCamera(decorator); bool bTiled = false; TileableBackground* tbg = dynamic_cast<TileableBackground*>(vp->getBackground()); if (tbg) { bTiled = tbg->getTile(); tbg->setTile(false); } // // The scene manager root node does not provide the illumination of the // scene. This is governed internally by the manager. However, to take // credit of the illumination we scan to the final parent of the scene // graph. // Node* internalRoot = rootNode(mgr->getRoot()); // // We would like to render the scene but won't detach it from its parent. // The VisitSubTree allows just that. // VisitSubTreeUnrecPtr visitor = VisitSubTree::create(); visitor->setSubTreeRoot(internalRoot); NodeUnrecPtr visit_node = makeNodeFor(visitor); // // We clone the camera of the first viewport and do not swap the buffer on later // rendering. This way the image generation process is not noticable in the // window. // CameraUnrecPtr camera = dynamic_pointer_cast<Camera>(vp->getCamera()->shallowCopy()); // // The stage object does provide a render target for the frame buffer attachment. // SimpleStage has a camera, a background and the left, right, top, bottom // fields to let you restrict rendering to a sub-rectangle of your FBO, i.e. // they give you a viewport. // SimpleStageUnrecPtr stage = SimpleStage::create(); stage->setRenderTarget(fbo); stage->setCamera (decorator); stage->setBackground (vp->getBackground()); // // Give the stage core a place to live // NodeUnrecPtr stage_node = makeNodeFor(stage); stage_node->addChild(visit_node); // // root // | // +- SimpleStage // | // +- VisitSubTree -> ApplicationScene // NodeUnrecPtr root = makeCoredNode<Group>(); root->addChild(stage_node); // // Give the root node a place to live, i.e. create a passive // viewport and add it to the window. // ViewportUnrecPtr stage_viewport = PassiveViewport::create(); stage_viewport->setRoot (root); stage_viewport->setBackground(vp->getBackground()); stage_viewport->setCamera (camera); win->addPort(stage_viewport); // // remember the decorator, the background tile prop setting and the stage setup // decorators[i] = boost::make_tuple(decorator, bTiled, stage, stage_viewport); } // // We write the image in simple ppm format. This one starts with a description // header which we output once on first write. // bool write_header = true; // // Calc the max y start position (width). We process the tiles from bottom // up and from left tp right as determined by the image format. // UInt32 yPosLast = 0; for (; yPosLast < height-winHeight; yPosLast += winHeight); // // Process from bottom to top // for (Int32 yPos = yPosLast; yPos >= 0; yPos -= winHeight) { UInt32 ySize = std::min(winHeight, height - yPos); // // Collect the tile images for each row, i.e. we write the // image in row manner to disk. This way the main memory is // only moderately stressed. // std::vector<ImageUnrecPtr> vecColImages; // // Process from left to right // for (UInt32 xPos = 0; xPos < width; xPos += winWidth) { UInt32 xSize = std::min(winWidth, width - xPos); // // The current tile image // ImageUnrecPtr col_image = Image::create(); col_image->set(Image::OSG_RGBA_PF, xSize, ySize); // // Adapt the tile camera decorator boxes to the current tile // for (size_t i = 0; i < num_ports; ++i) { // // this tile does not fill the whole FBO - adjust to only render // to a part of it // decorators[i].get<2>()->setLeft (0.f); decorators[i].get<2>()->setRight (xSize / float(winWidth)); decorators[i].get<2>()->setBottom(0.f); decorators[i].get<2>()->setTop (ySize / float(winHeight)); TileCameraDecorator* decorator = decorators[i].get<0>(); decorator->setSize( xPos / float(width), yPos / float(height), (xPos + xSize) / float(width), (yPos + ySize) / float(height) ); } // // render the tile // mgr->update(); win->renderNoFinish(mgr->getRenderAction()); win->frameExit(); win->deactivate (); // // Copy the image into the tile image stored for later processing // if(fbo) { RenderBuffer* grabber = dynamic_cast<RenderBuffer*>(fbo->getColorAttachments(0)); if(grabber) { grabber->getImage()->subImage(0, 0, 0, xSize, ySize, 1, col_image); } } vecColImages.push_back(col_image); } // // Write the image format header once // if (write_header) { write_header = false; if (!writePNMImagesHeader(vecColImages, width, height, stream)) break; } // // Write the current column // if (!writePNMImagesData(vecColImages, stream)) break; // // Forget the current column images // vecColImages.clear(); } // // restore window and cleanup // for (size_t i = 0; i < num_ports; ++i) { win->subPortByObj(decorators[i].get<3>()); Viewport* vp = win->getPort(i); vp->setCamera(decorators[i].get<0>()->getDecoratee()); vp->setSize(0, 0, 1, 1); TileableBackground* tbg = dynamic_cast<TileableBackground*>(vp->getBackground()); if (tbg) tbg->setTile(decorators[i].get<1>()); } }
DisplayFilterStageDataTransitPtr DisplayFilterStage::setupStageData(Int32 iPixelWidth, Int32 iPixelHeight) { DisplayFilterStageDataTransitPtr returnValue = DisplayFilterStageData::createLocal(); if(returnValue == NULL) return returnValue; // Scene Buffer FrameBufferObjectUnrecPtr pFBO = FrameBufferObject::createLocal(); RenderBufferUnrecPtr pDBuffer = RenderBuffer ::createLocal(); TextureBufferUnrecPtr pTBuffer = TextureBuffer ::createLocal(); TextureObjChunkUnrecPtr pTex = TextureObjChunk ::createLocal(); ImageUnrecPtr pImg = Image ::createLocal(); pImg->set(Image::OSG_RGB_PF, iPixelWidth, iPixelHeight, 1, 1, 1, 0.0, 0, Image::OSG_UINT8_IMAGEDATA, false); pTex ->setImage (pImg ); pTex ->setMinFilter (GL_NEAREST ); pTex ->setMagFilter (GL_NEAREST ); pTex ->setWrapS (GL_CLAMP_TO_EDGE ); pTex ->setWrapT (GL_CLAMP_TO_EDGE ); pTBuffer->setTexture(pTex); pDBuffer->setInternalFormat(GL_DEPTH_COMPONENT24); pFBO->setSize(iPixelWidth, iPixelHeight); pFBO->setColorAttachment(pTBuffer, 0); pFBO->setDepthAttachment(pDBuffer ); pFBO->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT); pFBO->setEnableMultiSample (this->getEnableMultiSample ()); pFBO->setColorSamples (this->getColorSamples ()); pFBO->setCoverageSamples (this->getCoverageSamples ()); pFBO->setFixedSampleLocation(this->getFixedSampleLocation()); returnValue->setTarget(pFBO); ChunkMaterialUnrecPtr pCMat = ChunkMaterial::createLocal(); pCMat->addChunk(pTex); returnValue->setBaseMaterial(pCMat); returnValue->setWidth (iPixelWidth ); returnValue->setHeight(iPixelHeight); commitChanges(); return returnValue; }