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())); }
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())); }
void SkGLWidget::paintGL() { if (!this->isHidden() && fCanvas) { fDebugger->draw(fCanvas); // TODO(chudy): Implement an optional flush button in Gui. fCanvas->flush(); emit drawComplete(); } }
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(); } }
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; }
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); }