Ejemplo n.º 1
0
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;
}
Ejemplo n.º 3
0
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();
}