void DisplayFilterStage::resizeStageData(DisplayFilterStageData *pData, Int32 iPixelWidth, Int32 iPixelHeight) { FrameBufferObject *pFBO = pData->getTarget(); if(pFBO == NULL) return; TextureBuffer *pTexBuffer = dynamic_cast<TextureBuffer *>(pFBO->getColorAttachments(0)); if(pTexBuffer == NULL) return; TextureObjChunk *pTex = pTexBuffer->getTexture(); if(pTex == NULL) return; Image *pImg = pTex->getImage(); if(pImg == NULL) return; pImg->set(Image::OSG_RGB_PF, iPixelWidth, iPixelHeight, 1, 1, 1, 0.0, 0, Image::OSG_UINT8_IMAGEDATA, false); pFBO->setSize(iPixelWidth, iPixelHeight); pData->setWidth (iPixelWidth ); pData->setHeight(iPixelHeight); commitChanges(); }
void DeferredShadingStage::updateStageData( DSStageData *data, FrameBufferObject *shadingTarget, RenderPartition *parentPart ) { FrameBufferObject *gBufferTarget = data->getGBufferTarget(); Int32 targetWidth; Int32 targetHeight; Int32 targetLeft; Int32 targetBottom; if(shadingTarget != NULL) { targetWidth = shadingTarget->getWidth (); targetHeight = shadingTarget->getHeight(); targetLeft = 0; targetBottom = 0; } else { targetWidth = parentPart->getDrawEnv().getPixelWidth (); targetHeight = parentPart->getDrawEnv().getPixelHeight(); targetLeft = parentPart->getDrawEnv().getPixelLeft (); targetBottom = parentPart->getDrawEnv().getPixelBottom(); } if(gBufferTarget->getWidth () != targetWidth || gBufferTarget->getHeight() != targetHeight ) { _targetSizeChanged = true; } if(_targetSizeChanged == true) { gBufferTarget->setSize(targetWidth, targetHeight); } if(getMFPixelFormats()->size() != getMFPixelTypes()->size()) { SWARNING << "DeferredShadingStage::updateStageData: " << "Number of PixelFormats and PixelTypes inconsistent." << std::endl; } UInt32 lightCount = getMFLights ()->size(); UInt32 bufferCount = osgMin(getMFPixelFormats()->size(), getMFPixelTypes ()->size() ); // buffers changed - remove them here, recreate below if((_changeCache & (PixelFormatsFieldMask | PixelTypesFieldMask )) != 0) { gBufferTarget->editMFColorAttachments()->clear ( ); gBufferTarget->editMFColorAttachments()->resize(bufferCount, NULL ); gBufferTarget->editMFDrawBuffers ()->clear ( ); gBufferTarget->editMFDrawBuffers ()->resize(bufferCount, GL_NONE); } for(UInt32 i = 0; i < bufferCount; ++i) { TextureBuffer *buf = dynamic_cast<TextureBuffer *>(gBufferTarget->getColorAttachments(i)); if(buf == NULL) { TextureBufferUnrecPtr newBuf = createGBuffer(i, targetWidth, targetHeight); buf = newBuf; gBufferTarget->editMFColorAttachments()->replace(i, newBuf ); gBufferTarget->editMFDrawBuffers ()->replace(i, GL_COLOR_ATTACHMENT0_EXT + i); } else { updateGBuffer(buf, i, targetWidth, targetHeight); } } if((_changeCache & LightsFieldMask) != 0) { data->editMFLightChunks ()->resize( lightCount, NULL); data->editMFShadingStates ()->resize(1 + lightCount, NULL); data->editMFShadingProgramChunks()->resize(1 + lightCount, NULL); } // update shading states if((_changeCache & (PixelFormatsFieldMask | PixelTypesFieldMask | AmbientProgramFieldMask | LightProgramsFieldMask | LightsFieldMask )) != 0) { // copy ambient and light programs DSStageData::MFShadingProgramChunksType::const_iterator spcIt = data->editMFShadingProgramChunks()->begin(); DSStageData::MFShadingProgramChunksType::const_iterator spcEnd = data->editMFShadingProgramChunks()->end (); for(UInt32 progIdx = 0; spcIt != spcEnd; ++spcIt, ++progIdx) { if(*spcIt == NULL) { ShaderProgramChunkUnrecPtr newSPC = ShaderProgramChunk::createLocal(); //*spcIt = newSPC; data->editMFShadingProgramChunks()->replace(progIdx, newSPC); } (*spcIt)->clearVertexShaders (); (*spcIt)->clearGeometryShaders(); (*spcIt)->clearFragmentShaders(); if(progIdx == 0 && getAmbientProgram() != NULL) { // ambient program copyProgramChunk(*spcIt, getAmbientProgram()); // TODO: there must be a better way to add this uniform (*spcIt)->getFragmentShader(0)->addUniformVariable( "vpOffset", Vec2f(targetLeft, targetBottom)); } else { // light programs if(_mfLightPrograms.size() == 1) { copyProgramChunk(*spcIt, getLightPrograms(0)); // TODO: there must be a better way to add this uniform (*spcIt)->getFragmentShader(0)->addUniformVariable( "vpOffset", Vec2f(targetLeft, targetBottom)); } else if(_mfLightPrograms.size() == _mfLights.size()) { copyProgramChunk(*spcIt, getLightPrograms(progIdx - 1)); // TODO: there must be a better way to add this uniform (*spcIt)->getFragmentShader(0)->addUniformVariable( "vpOffset", Vec2f(targetLeft, targetBottom)); } else { SWARNING << "DeferredShadingStage::updateStageData: " << "Number of Lights and LightPrograms " << "inconsistent." << std::endl; } } } // create light chunks DSStageData::MFLightChunksType::const_iterator lcIt = data->editMFLightChunks()->begin(); DSStageData::MFLightChunksType::const_iterator lcEnd = data->editMFLightChunks()->end (); for(UInt32 lightIdx = 0; lcIt != lcEnd; ++lcIt, ++lightIdx) { if(*lcIt == NULL) { DSLightChunkUnrecPtr newLC = DSLightChunk::createLocal(); //*lcIt = newLC; data->editMFLightChunks()->replace(lightIdx, newLC); } updateLightChunk(*lcIt, getLights(lightIdx)); } // populate shading states DSStageData::MFShadingStatesType::const_iterator stateIt = data->editMFShadingStates()->begin(); DSStageData::MFShadingStatesType::const_iterator stateEnd = data->editMFShadingStates()->end (); for(UInt32 stateIdx = 0; stateIt != stateEnd; ++stateIt, ++stateIdx) { if(*stateIt == NULL) { StateUnrecPtr newState = State::createLocal(); //*stateIt = newState; data->editMFShadingStates()->replace(stateIdx, newState); } // remove all chunks (*stateIt)->clearChunks(); // add G Buffer textures for(UInt32 bufferIdx = 0; bufferIdx < bufferCount; ++bufferIdx) { TextureBuffer *buf = static_cast<TextureBuffer *>( gBufferTarget->getColorAttachments(bufferIdx)); TextureObjChunk *bufTex = buf->getTexture(); (*stateIt)->addChunk(bufTex, bufferIdx); } // add ambient/light programs and light chunks if(stateIdx == 0) { if(getAmbientProgram() != NULL) { (*stateIt)->addChunk( data->getShadingProgramChunks(stateIdx)); } } else { (*stateIt)->addChunk( data->getShadingProgramChunks(stateIdx )); (*stateIt)->addChunk( data->getLightChunks (stateIdx - 1)); } // add blend chunk to light states if(stateIdx > 0) { (*stateIt)->addChunk(data->getBlendChunk()); } } } _changeCache = TypeTraits<BitVector>::BitsClear; _targetSizeChanged = false; }