SkCanvasWidget::SkCanvasWidget(QWidget* parent,
        SkDebugger* debugger) : QWidget(parent)
    , fHorizontalLayout(this)
    , fRasterWidget(debugger)
#if SK_SUPPORT_GPU
    , fGLWidget(debugger)
#endif
{

    fDebugger = debugger;

    fHorizontalLayout.setSpacing(6);
    fHorizontalLayout.setContentsMargins(0,0,0,0);
    fRasterWidget.setSizePolicy(QSizePolicy::Expanding,
            QSizePolicy::Expanding);
#if SK_SUPPORT_GPU
    fGLWidget.setSizePolicy(QSizePolicy::Expanding,
            QSizePolicy::Expanding);
#endif

    fHorizontalLayout.addWidget(&fRasterWidget);
#if SK_SUPPORT_GPU
    fHorizontalLayout.addWidget(&fGLWidget);
#endif

    fPreviousPoint.set(0,0);
    fUserMatrix.reset();

#if SK_SUPPORT_GPU
    setWidgetVisibility(kGPU_WidgetType, true);
#endif
    connect(&fRasterWidget, SIGNAL(drawComplete()),
            this->parentWidget(), SLOT(drawComplete()));
}
示例#2
0
SkCanvasWidget::SkCanvasWidget(QWidget* parent,
        SkDebugger* debugger) : QWidget(parent)
    , fHorizontalLayout(this)
    , fRasterWidget(debugger)
    , fGLWidget(debugger)
{

    fDebugger = debugger;

    fHorizontalLayout.setSpacing(6);
    fHorizontalLayout.setContentsMargins(0,0,0,0);
    fRasterWidget.setSizePolicy(QSizePolicy::Expanding,
            QSizePolicy::Expanding);
    fGLWidget.setSizePolicy(QSizePolicy::Expanding,
            QSizePolicy::Expanding);

    fHorizontalLayout.addWidget(&fRasterWidget);
    fHorizontalLayout.addWidget(&fGLWidget);

    fPreviousPoint.set(0,0);
    fUserOffset.set(0,0);
    fUserScaleFactor = 1.0;

    setWidgetVisibility(kGPU_WidgetType, true);
    connect(&fRasterWidget, SIGNAL(drawComplete()),
            this->parentWidget(), SLOT(drawComplete()));
}
示例#3
0
void SkGLWidget::paintGL() {
    if (!this->isHidden() && fCanvas) {
        fDebugger->draw(fCanvas);
        // TODO(chudy): Implement an optional flush button in Gui.
        fCanvas->flush();
        emit drawComplete();
    }
}
示例#4
0
void SkGLWidget::paintGL() {
    if (!this->isHidden() && fCanvas) {
        fCurContext->resetContext();
        fDebugger->draw(fCanvas);
        // TODO(chudy): Implement an optional flush button in Gui.
        fCanvas->flush();
        Q_EMIT drawComplete();
    }
}
示例#5
0
int SkRasterWidget::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    _id = QWidget::qt_metacall(_c, _id, _a);
    if (_id < 0)
        return _id;
    if (_c == QMetaObject::InvokeMetaMethod) {
        switch (_id) {
        case 0: drawComplete(); break;
        default: ;
        }
        _id -= 1;
    }
    return _id;
}
示例#6
0
void SkRasterWidget::paintEvent(QPaintEvent* event) {
    if (!this->isHidden()) {
        fDebugger->draw(fCanvas);
        QPainter painter(this);
        QStyleOption opt;
        opt.init(this);

        style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);

        QPoint origin(0,0);
        QImage image((uchar *)fBitmap.getPixels(), fBitmap.width(),
                fBitmap.height(), QImage::Format_ARGB32_Premultiplied);

#if SK_R32_SHIFT == 0
        painter.drawImage(origin, image.rgbSwapped());
#else
        painter.drawImage(origin, image);
#endif
        painter.end();
        emit drawComplete();
    }
}
void DepthPeelBin::drawImplementation( osg::RenderInfo& renderInfo, osgUtil::RenderLeaf*& previous )
{
    TRACEDUMP("DepthPeelBin::drawImplementation");
    UTIL_GL_ERROR_CHECK("DepthPeelBin::drawImplementation start");

    unsigned int debugMode = Manager::instance()->getDebugMode();

    osg::State& state = *renderInfo.getState();
    const unsigned int contextID = state.getContextID();
    osg::FBOExtensions* fboExt( osg::FBOExtensions::instance( contextID, true ) );
    UTIL_GL_FBO_ERROR_CHECK("DepthPeelBin::drawImplementation start",fboExt);
    osg::GL2Extensions* ext = osg::GL2Extensions::Get( contextID, true );
    UTIL_MEMORY_CHECK( ext, "DepthPeelBin: NULL GL2Extensions", );

    // Get the last applied viewport. When we render to our internal textures,
    // we will render to the lower left corner in an area the size of the viewport.
    // We track the width and height and maintain internal textures large enough
    // to render the largest width and height we've seen.
    const osg::Viewport* vp = dynamic_cast< const osg::Viewport* >(
        state.getLastAppliedAttribute( osg::StateAttribute::VIEWPORT ) );
    const GLsizei width( vp->width() ), height( vp->height() );

    char* pixels( NULL );
    const bool dumpImages = ( ( debugMode & backdropFX::BackdropCommon::debugImages ) != 0 );
    if( dumpImages )
    {
        pixels = new char[ width * height * 4 ];
        UTIL_MEMORY_CHECK( pixels, "DepthPeelBin: debug image pixel buffer", )
    }

    // Fix for redmine issue 8, and the recurrance of this issue
    // in the new depth peel work.
    // The most general way to handle the single StateGraph case
    // is to save the last StateGraph and re-apply it just before
    // we return from ::draw().
    osgUtil::StateGraph* savedStateGraph( NULL );
    if( _stateGraphList.size() )
        savedStateGraph = _stateGraphList.back();

    PerContextInfo& pci = s_contextInfo[ contextID ];
    unsigned int insertStateSetPosition;
    {
        // Get the current Draw FBO and restore it when fboSRH goes out of scope.
        // Get this now, first, before we call pci._init. Also, having it hear means
        // we query OpenGL once. If, instead, we instantiated one of these for every
        // layer, we would query OpenGL every layer. Having just one instance, with
        // its constructor invoked once, is a better solution.
        FBOSaveRestoreHelper fboSRH( fboExt, pci );

        insertStateSetPosition = drawInit( state, previous );

        if( pci._init &&
            ( ( pci._width < width ) || ( pci._height < height ) ) )
        {
            // We've already created textures at a given size, but we
            // now have a larger viewport. Delete those textures and
            // force a re-initialization.
            // NOTE We never resize the textures smaller, only larger.
            osg::notify( osg::INFO ) << "BDFX: DepthPeelBin cleanup. ";
            pci.cleanup( state );
        }
        if( !pci._init )
        {
            osg::notify( osg::INFO ) << "BDFX: DepthPeelBin resize to width: " <<
                width << " height: " << height << std::endl;
            pci.init( state, width, height );
        }

        // Compute the percentage of the texture we will render to.
        // This is the viewport width and height divided by the texture
        // width and height. It's used to ensure we display the appropriate
        // portion of the texture during drawFSTP().
        osg::Vec2f texturePercent( vp->width() / (float)( pci._width ),
            vp->height() / (float)( pci._height ) );
        _texturePercentUniform->set( texturePercent );

        // Uniform locations, used during drawFSTP(). We declare them here and pass
        // them by reference. drawFSTP() inits them after binding the fstpProgram.
        // Then we reuse the values until next frame. Avoids looking up the uniform
        // location (via map keyed by string) for every layer.
        GLint fstpLoc( -1 ), texturePercentLoc( -1 );


        // Opaque pass.
        bool transparentRemaining( false ); // After opaque pass, are there transparent bins?
        int drawCount( 0 );
        {
            osgwTools::glBindFramebuffer( fboExt, GL_FRAMEBUFFER_EXT, pci._fbo );

            state.applyAttribute( _opaqueDepth.get() );
            state.applyMode( GL_DEPTH_TEST, true );
            glClearDepth( 1.0 );
            unsigned int idx;
            for( idx=0; idx<2; idx++ )
            {
                osgwTools::glFramebufferTexture2D( fboExt, GL_DRAW_FRAMEBUFFER_EXT,
                    GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, pci._depthTex[ idx ], 0 );
                glClear( GL_DEPTH_BUFFER_BIT );
            }
            osgwTools::glFramebufferTexture2D( fboExt, GL_DRAW_FRAMEBUFFER_EXT,
                GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, pci._depthTex[ 2 ], 0 );

            state.setActiveTextureUnit( s_textureUnit );
            glBindTexture( GL_TEXTURE_2D, pci._depthTex[ 0 ] );
            state.setActiveTextureUnit( s_textureUnit+1 );
            glBindTexture( GL_TEXTURE_2D, pci._depthTex[ 1 ] );

            glClearColor( 0., 0., 0., 0. );
            glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
            drawCount = drawOpaque( renderInfo, previous, transparentRemaining );

            // Blend the opaque pass into the output buffer.
            // We could probably do this a different way, by attaching
            // the output color buffer to our FBO and rendering directly
            // into it. This is TBD as a later enhancement.
            fboSRH.restore();

            drawFSTP( renderInfo, state, ext, pci, fstpLoc, texturePercentLoc );

            if( dumpImages )
            {
                FBOSaveRestoreHelper fboSRHRead( fboExt, pci, GL_READ_FRAMEBUFFER_EXT );
                osgwTools::glBindFramebuffer( fboExt, GL_READ_FRAMEBUFFER_EXT, pci._fbo );

                std::string fileName = createFileName( state );
                glReadBuffer( GL_COLOR_ATTACHMENT0_EXT );
                glReadPixels( (GLint)( 0 ), (GLint)( 0 ), width, height, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)pixels );
                backdropFX::debugDumpImage( fileName, pixels, width, height );
                osg::notify( osg::NOTICE ) << " - " << fileName << std::endl;

                fileName = createFileName( state, -1, true );
                glReadPixels( (GLint)( 0 ), (GLint)( 0 ), width, height, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, (GLvoid*)pixels );
                backdropFX::debugDumpDepthImage( fileName, (const short*)pixels, width, height );
                osg::notify( osg::NOTICE ) << " - " << fileName << std::endl;
            }
        }


        // drawOpaque() sets this to true if there are transparent bins to render.
        if( transparentRemaining )
        {
            // Transparent passes
            state.setActiveTextureUnit( s_textureUnit );
            glBindTexture( GL_TEXTURE_2D, pci._depthTex[ 2 ] );

            // If we already drew something in the opaque pass, then GL_LESS has already been
            // set. But if we didn't draw anything in the opaque pass (drawCount==0) then the
            // scene graph will almost certainly set depth function to GL_LESS using lazy state
            // setting. In that case, we must apply state _now_ so that the transparent pass can
            // correctly set the depth function to GL_GREATER.
            if( drawCount == 0 )
                state.apply();

            // Create depth peel layers until we hit _maxPasses, or until
            // occlusion query indicates we didn't render anything.
            unsigned int passCount;
            for( passCount = 0; passCount < _maxPasses; passCount++ )
            {
                // Specify the depth buffer to render to.
                osgwTools::glBindFramebuffer( fboExt, GL_FRAMEBUFFER_EXT, pci._fbo );
                osgwTools::glFramebufferTexture2D( fboExt, GL_DRAW_FRAMEBUFFER_EXT,
                    GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, pci._depthTex[ passCount & 0x1 ], 0 );
                osg::notify( osg::DEBUG_FP ) << "  Attaching depth buffer " << pci._depthTex[ passCount & 0x1 ] << std::endl;

                // Use the other depth buffer as an input texture.
                state.setActiveTextureUnit( s_textureUnit+1 );
                glBindTexture( GL_TEXTURE_2D, pci._depthTex[ (passCount+1) & 0x1 ] );
                osg::notify( osg::DEBUG_FP ) << "  Binding depth map " << pci._depthTex[ (passCount+1) & 0x1 ] << std::endl;

                _transparentDepth->apply( state );
                glEnable( GL_DEPTH_TEST );
                glClearDepth( 0.0 );
                glClearColor( 0., 0., 0., 0. );
                glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );

                pci._glBeginQuery( GL_SAMPLES_PASSED_ARB, pci._queryID );
                drawTransparent( renderInfo, previous );
                pci._glEndQuery( GL_SAMPLES_PASSED_ARB );

                if( dumpImages )
                {
                    FBOSaveRestoreHelper fboSRHRead( fboExt, pci, GL_READ_FRAMEBUFFER_EXT );
                    osgwTools::glBindFramebuffer( fboExt, GL_READ_FRAMEBUFFER_EXT, pci._fbo );

                    std::string fileName = createFileName( state, passCount );
                    glReadBuffer( GL_COLOR_ATTACHMENT0_EXT );
                    glReadPixels( (GLint)( 0 ), (GLint)( 0 ), width, height, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)pixels );
                    backdropFX::debugDumpImage( fileName, pixels, width, height );
                    osg::notify( osg::NOTICE ) << " - " << fileName << std::endl;

                    fileName = createFileName( state, passCount, true );
                    glReadPixels( (GLint)( 0 ), (GLint)( 0 ), width, height, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, (GLvoid*)pixels );
                    backdropFX::debugDumpDepthImage( fileName, (const short*)pixels, width, height );
                    osg::notify( osg::NOTICE ) << " - " << fileName << std::endl;
                }

                // Query the number of pixels rendered to see if it's time to stop.
                GLint numPixels( 0 );
                pci._glGetQueryObjectiv( pci._queryID, GL_QUERY_RESULT, &numPixels );
                osg::notify( osg::DEBUG_FP ) << "  BDFX: DP pass " << passCount << ",  numPixels " << numPixels << std::endl;
                if( numPixels < _minPixels )
                {
                    passCount++;
                    break;
                }

                // We rendered something, so now we render the FSTP to combine the layer we just
                // created with the original FBO.
                fboSRH.restore();

                drawFSTP( renderInfo, state, ext, pci, fstpLoc, texturePercentLoc );
            }

            if( debugMode & BackdropCommon::debugConsole )
                osg::notify( osg::DEBUG_FP ) << "BDFX: DepthPeelBin: " << passCount << " pass" <<
                ((passCount==1)?".":"es.") << std::endl;

            // Restore to default.
            glClearDepth( 1.0 );

        } // if transparentRemaining
    }


    // RenderBin::drawImplementation wrap-up: State restore.
    drawComplete( state, insertStateSetPosition );

    if( dumpImages )
        delete[] pixels;

    // Re-apply the last StateGraph used to render the child subgraph.
    // This restores state to the way OSG thinks it should be.
    if( savedStateGraph != NULL )
        state.apply( savedStateGraph->getStateSet() );

    UTIL_GL_ERROR_CHECK("DepthPeelBin::drawImplementation end");
    UTIL_GL_FBO_ERROR_CHECK("DepthPeelBin::drawImplementation end",fboExt);
}