void HDRStage::postProcess(DrawEnv *pEnv) { Window *win = pEnv->getWindow(); if(win->hasExtension(_uiFramebuffer_object_extension) == false) { FNOTICE(("Framebuffer objects not supported on Window %p!\n", win)); return; } GLDrawBuffersEXTProcT glDrawBuffersEXTProc = reinterpret_cast<GLDrawBuffersEXTProcT>( win->getFunction(_uiFuncDrawBuffers)); glColor3f(1.f, 1.f, 1.f); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); HDRStageData *pData = pEnv->getData<HDRStageData *>(_iDataSlotId); if(pData == NULL) { return; } if((pData->getWidth () != pEnv->getPixelWidth() ) || (pData->getHeight() != pEnv->getPixelHeight()) ) { resizeStageData(pData, pEnv->getPixelWidth(), pEnv->getPixelHeight()); } // Shrink to w/2 h/2 FrameBufferObject *pShrinkTarget = pData->getShrinkRenderTarget(); ChunkMaterial *pSHM = pData->getShrinkMaterial(); pShrinkTarget->activate(pEnv); glViewport(0, 0, pEnv->getPixelWidth () / 2, pEnv->getPixelHeight() / 2); State *pShrinkState = pSHM->getState(); pEnv->activateState(pShrinkState, NULL); glBegin(GL_QUADS); { glTexCoord2f(0.00, 0.00); glVertex2f (0.00, 0.00); glTexCoord2f(1.00, 0.00); glVertex2f (1.00, 0.00); glTexCoord2f(1.00, 1.00); glVertex2f (1.00, 1.00); glTexCoord2f(0.00, 1.00); glVertex2f (0.00, 1.00); } glEnd(); pShrinkTarget->deactivate(pEnv); // Shrink to w/4 h/4 FrameBufferObject *pBlurTarget = pData->getBlurRenderTarget(); pBlurTarget->editMFDrawBuffers()->clear(); pBlurTarget->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT); pBlurTarget->activate(pEnv); glViewport(0, 0, pEnv->getPixelWidth () / 4, pEnv->getPixelHeight() / 4); ChunkMaterial *pBLM = pData->getBlurMaterial(); State *pBlurState = pBLM->getState(); pEnv->activateState(pBlurState, NULL); glBegin(GL_QUADS); { glTexCoord2f(0.00, 0.00); glVertex2f (0.00, 0.00); glTexCoord2f(1.00, 0.00); glVertex2f (1.00, 0.00); glTexCoord2f(1.00, 1.00); glVertex2f (1.00, 1.00); glTexCoord2f(0.00, 1.00); glVertex2f (0.00, 1.00); } glEnd(); // HBlur StateOverride oOverride; GLenum aDrawBuffers[] = { GL_COLOR_ATTACHMENT1_EXT }; oOverride.addOverride(pData->getHBlurShader()->getClassId(), pData->getHBlurShader()); pEnv->activateState(pBlurState, &oOverride); glDrawBuffersEXTProc(1, aDrawBuffers); glBegin(GL_QUADS); { glTexCoord2f(0.00, 0.00); glVertex2f (0.00, 0.00); glTexCoord2f(1.00, 0.00); glVertex2f (1.00, 0.00); glTexCoord2f(1.00, 1.00); glVertex2f (1.00, 1.00); glTexCoord2f(0.00, 1.00); glVertex2f (0.00, 1.00); } glEnd(); // VBlur StateOverride oOverride1; oOverride1.addOverride(pData->getVBlurShader()->getClassId(), pData->getVBlurShader()); pEnv->activateState(pBlurState, &oOverride1); aDrawBuffers[0] = GL_COLOR_ATTACHMENT0_EXT; glDrawBuffersEXTProc(1, aDrawBuffers); glBegin(GL_QUADS); { glTexCoord2f(0.00, 0.00); glVertex2f (0.00, 0.00); glTexCoord2f(1.00, 0.00); glVertex2f (1.00, 0.00); glTexCoord2f(1.00, 1.00); glVertex2f (1.00, 1.00); glTexCoord2f(0.00, 1.00); glVertex2f (0.00, 1.00); } glEnd(); pBlurTarget->deactivate(pEnv); // Tonemap pass glDisable(GL_DEPTH_TEST); glViewport(pEnv->getPixelLeft (), pEnv->getPixelBottom(), pEnv->getPixelWidth (), pEnv->getPixelHeight()); ChunkMaterial *pTCM = pData->getToneMappingMaterial(); State *pTState = pTCM->getState(); pEnv->activateState(pTState, NULL); glBegin(GL_QUADS); { glTexCoord2f(0.00, 0.00); glVertex2f (0.00, 0.00); glTexCoord2f(1.00, 0.00); glVertex2f (1.00, 0.00); glTexCoord2f(1.00, 1.00); glVertex2f (1.00, 1.00); glTexCoord2f(0.00, 1.00); glVertex2f (0.00, 1.00); } glEnd(); glEnable(GL_DEPTH_TEST); pEnv->deactivateState(); glPopMatrix(); }
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; }
void HDRStage::postProcess(DrawEnv *pEnv) { UInt32 uiActiveFBO = pEnv->getActiveFBO(); Window *win = pEnv->getWindow(); if(win->hasExtOrVersion(_uiFramebufferObjectExt, 0x0300, 0x0200) == false) { FNOTICE(("Framebuffer objects not supported on Window %p!\n", static_cast<void *>(win))); return; } OSGGETGLFUNCBYID_GL3( glDrawBuffers, osgGlDrawBuffers, _uiFuncDrawBuffers, win); glColor3f(1.f, 1.f, 1.f); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); HDRStageData *pData = pEnv->getData<HDRStageData *>(_iDataSlotId); if(pData == NULL) { return; } // Shrink to w/2 h/2 FrameBufferObject *pShrinkTarget = pData->getShrinkRenderTarget(); ChunkMaterial *pSHM = pData->getShrinkMaterial(); pShrinkTarget->activate(pEnv); glViewport(0, 0, pEnv->getPixelWidth () / 2, pEnv->getPixelHeight() / 2); State *pShrinkState = pSHM->getState(); pEnv->activateState(pShrinkState, NULL); this->renderQuad(); pShrinkTarget->deactivate(pEnv); // Shrink to w/4 h/4 FrameBufferObject *pBlurTarget = pData->getBlurRenderTarget(); pBlurTarget->editMFDrawBuffers()->clear(); pBlurTarget->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT); pBlurTarget->activate(pEnv); glViewport(0, 0, pEnv->getPixelWidth () / 4, pEnv->getPixelHeight() / 4); ChunkMaterial *pBLM = pData->getBlurMaterial(); State *pBlurState = pBLM->getState(); pEnv->activateState(pBlurState, NULL); this->renderQuad(); GLenum aDrawBuffers[] = { GL_COLOR_ATTACHMENT0_EXT }; // HBlur pBlurTarget->activate(pEnv); glViewport(0, 0, pEnv->getPixelWidth () / 4, pEnv->getPixelHeight() / 4); #define OVERSHADER 1 #if OVERSHADER StateOverride oOverride; oOverride.addOverride(pData->getHBlurShader()->getClassId(), pData->getHBlurShader()); pEnv->activateState(pBlurState, &oOverride); #else pData->getHBlurShader()->activate(pEnv); #endif aDrawBuffers[0] = GL_COLOR_ATTACHMENT1_EXT; osgGlDrawBuffers(1, aDrawBuffers); this->renderQuad(); #if !OVERSHADER pData->getHBlurShader()->deactivate(pEnv); #endif // VBlur #if OVERSHADER StateOverride oOverride1; oOverride1.addOverride(pData->getVBlurShader()->getClassId(), pData->getVBlurShader()); pEnv->activateState(pBlurState, &oOverride1); #else pData->getVBlurShader()->activate(pEnv); #endif aDrawBuffers[0] = GL_COLOR_ATTACHMENT0_EXT; osgGlDrawBuffers(1, aDrawBuffers); this->renderQuad(); #if !OVERSHADER pData->getVBlurShader()->deactivate(pEnv); #endif if(uiActiveFBO == 0) { pBlurTarget->deactivate(pEnv); } else { FrameBufferObject::activateFBOById(pEnv, uiActiveFBO); } // Tonemap pass glDisable(GL_DEPTH_TEST); glViewport(pEnv->getPixelLeft (), pEnv->getPixelBottom(), pEnv->getPixelWidth (), pEnv->getPixelHeight()); ChunkMaterial *pTCM = pData->getToneMappingMaterial(); State *pTState = pTCM->getState(); pEnv->activateState(pTState, NULL); this->renderQuad(); glEnable(GL_DEPTH_TEST); pEnv->deactivateState(); glPopMatrix(); }