void admPreview::stop( void ) { renderLock(); if(previewMode==ADM_PREVIEW_SEPARATE) DIA_previewEnd(); if( previewMode==ADM_PREVIEW_SIDE || previewMode==ADM_PREVIEW_TOP) { ADM_assert(original); delete original; original=NULL; } renderResize(rdrWindowWUnzoomed,rdrWindowHUnzoomed,rdrWindowWUnzoomed,rdrWindowHUnzoomed); if(previewImage) { delete previewImage; previewImage=NULL; } if(zoom!=ZOOM_1_1) { if(resized) delete resized; if(resizer) delete resizer; resized=NULL; resizer=NULL; } renderUnlock(); }
/// <summary> /// Start rendering. /// </summary> /// <param name="painter">The painter.</param> /// <param name="forceWidthScale">Force a specific scale factor for line widths and marker sizes.</param> void GRRenderer::render( QPainter* painter, double *forceWidthScale /*= 0 */ ) { QMutexLocker renderLock( &mRenderMutex ); qDebug() << "=====Rendering========="; QPaintDevice* thePaintDevice = painter->device(); if ( !thePaintDevice ) { return; } // wait if ( mDrawing ) { qDebug() << "already rendering!"; QCoreApplication::processEvents(); } if ( mDrawing ) { qDebug() << "still rendering - skipping"; return; } mDrawing = true; GRCoordinateTransform* ct; if ( mOverview ) { // mRenderContext.setDrawEditingInformation(!mOverview); } mRenderContext.setPainter( painter ); mRenderContext.setCoordinateTransform( 0 ); mRenderContext.setRenderingStopped( false ); //calculate scale factor //use the specified dpi and not those from the paint device //because sometimes QPainter units are in a local coord sys (e.g. in case of QGraphicsScene) double sceneDpi = mScaleCalculator->dpi(); double scaleFactor = 1.0; if ( mOutputUnits == GRRenderer::Millimeters ) { if ( forceWidthScale ) { scaleFactor = *forceWidthScale; } else { scaleFactor = sceneDpi / 25.4; } } double rasterScaleFactor = ( thePaintDevice->logicalDpiX() + thePaintDevice->logicalDpiY() ) / 2.0 / sceneDpi; // need to finish................. }
void AudioDestinationNode::render(AudioBus* sourceBus, AudioBus* destinationBus, size_t numberOfFrames) { // The audio system might still be invoking callbacks during shutdown, so bail out if so. if (!m_context) return; // We don't want denormals slowing down any of the audio processing // since they can very seriously hurt performance. // This will take care of all AudioNodes because they all process within this scope. DenormalDisabler denormalDisabler; ContextRenderLock renderLock(m_context, "AudioDestinationNode::render"); if (!renderLock.context()) return; // return if couldn't acquire lock if (!m_context->isRunnable()) { destinationBus->zero(); return; } // Let the context take care of any business at the start of each render quantum. m_context->handlePreRenderTasks(renderLock); // Prepare the local audio input provider for this render quantum. if (sourceBus) m_localAudioInputProvider->set(sourceBus); // This will cause the node(s) connected to this destination node to process, which in turn will pull on their input(s), // all the way backwards through the rendering graph. AudioBus* renderedBus = input(0)->pull(renderLock, destinationBus, numberOfFrames); if (!renderedBus) { destinationBus->zero(); } else if (renderedBus != destinationBus) { // in-place processing was not possible - so copy destinationBus->copyFrom(*renderedBus); } // Process nodes which need a little extra help because they are not connected to anything, but still need to process. m_context->processAutomaticPullNodes(renderLock, numberOfFrames); // Let the context take care of any business at the end of each render quantum. m_context->handlePostRenderTasks(renderLock); // Advance current sample-frame. m_currentSampleFrame += numberOfFrames; }
GraphicsSystem::GraphicsSystem () { if (gRenderThread) { mRenderThread=gRenderThread; gKillGraphics=false; }else { boost::unique_lock<boost::mutex> renderLock(*Elysia::gRenderLock); std::tr1::shared_ptr<boost::thread> x(new boost::thread(&myfunc)); gRenderCondition.wait(renderLock); mRenderThread=gRenderThread=x; gKillGraphics=false; } }
void PointCloudDisplay::setBillboardSize( float size ) { { RenderAutoLock renderLock( this ); billboard_size_ = size; cloud_->setBillboardDimensions( size, size ); } causeRender(); if ( billboard_size_property_ ) { billboard_size_property_->changed(); } causeRender(); }
void Deinitialize() { { boost::unique_lock<boost::mutex> renderLock(*Elysia::gRenderLock); Elysia::gToRender.clear(); Elysia::gRenderCondition.notify_one(); Elysia::gRenderCompleteCondition.notify_one(); } gShutDown=true; gKillGraphics=false; fflush(stdout); fflush(stderr); // while(!gShutdownComplete); #ifdef _WIN32 Sleep(1000); #else sleep(1);//need to sleep to allow the gl context to destroy itself (mac requires the main thread exit by itself after the window is destroyed) #endif }
void PointCloudDisplay::setStyle( int style ) { ROS_ASSERT( style < StyleCount ); { RenderAutoLock renderLock( this ); style_ = style; cloud_->setUsePoints( style == Points ); } causeRender(); if ( style_property_ ) { style_property_->changed(); } causeRender(); }
void Renderer::render( const RenderData& data ) { CORE_ASSERT( m_engine != nullptr, "no engine in renderer" ); std::lock_guard<std::mutex> renderLock( m_renderMutex ); m_timerData.renderStart = Core::Timer::Clock::now(); // 0. Save eventual already bound FBO (e.g. QtOpenGLWidget) saveExternalFBOInternal(); // 1. Gather render objects and update them std::vector<RenderObjectPtr> renderObjects; m_engine->getRenderObjectManager()->getRenderObjects(renderObjects); updateRenderObjectsInternal( data, renderObjects ); m_timerData.updateEnd = Core::Timer::Clock::now(); // 2. Feed render queues feedRenderQueuesInternal( data, renderObjects ); m_timerData.feedRenderQueuesEnd = Core::Timer::Clock::now(); // 3. Do picking if needed m_pickingResults.clear(); if ( !m_pickingQueries.empty() ) { doPicking(); } // 4. Do the rendering. renderInternal( data ); m_timerData.mainRenderEnd = Core::Timer::Clock::now(); // 5. Post processing postProcessInternal( data ); m_timerData.postProcessEnd = Core::Timer::Clock::now(); // 6. write image to framebuffer. drawScreenInternal(); m_timerData.renderEnd = Core::Timer::Clock::now(); }
COverlayRenderer::~COverlayRenderer() { CAutoLock renderLock(&m_csRenderLock); CAutoLock queueLock(&m_csOverlayQueue); FreeOverlayQueue(BD_OVERLAY_IG); FreeOverlayQueue(BD_OVERLAY_PG); if (m_hOverlayTimerIG) { CloseHandle(m_hOverlayTimerIG); m_hOverlayTimerIG = NULL; } if (m_hOverlayTimerPG) { CloseHandle(m_hOverlayTimerPG); m_hOverlayTimerPG = NULL; } if (m_hNewOverlayAvailable) CloseHandle(m_hNewOverlayAvailable); if (m_hStopThreadEvent) { SetEvent(m_hStopThreadEvent); CloseHandle(m_hStopThreadEvent); WaitForSingleObject(m_hThread, INFINITE); } if (m_hThread) CloseHandle(m_hThread); CloseOverlay(BD_OVERLAY_PG); CloseOverlay(BD_OVERLAY_IG); }
void QgsMapRenderer::render( QPainter* painter, double* forceWidthScale ) { //Lock render method for concurrent threads (e.g. from globe) QMutexLocker renderLock( &mRenderMutex ); //flag to see if the render context has changed //since the last time we rendered. If it hasnt changed we can //take some shortcuts with rendering bool mySameAsLastFlag = true; QgsDebugMsg( "========== Rendering ==========" ); if ( mExtent.isEmpty() ) { QgsDebugMsg( "empty extent... not rendering" ); return; } if ( mSize.width() == 1 && mSize.height() == 1 ) { QgsDebugMsg( "size 1x1... not rendering" ); return; } QPaintDevice* thePaintDevice = painter->device(); if ( !thePaintDevice ) { return; } // wait if ( mDrawing ) { QgsDebugMsg( "already rendering" ); QCoreApplication::processEvents(); } if ( mDrawing ) { QgsDebugMsg( "still rendering - skipping" ); return; } mDrawing = true; const QgsCoordinateTransform *ct; #ifdef QGISDEBUG QgsDebugMsg( "Starting to render layer stack." ); QTime renderTime; renderTime.start(); #endif if ( mOverview ) mRenderContext.setDrawEditingInformation( !mOverview ); mRenderContext.setPainter( painter ); mRenderContext.setCoordinateTransform( 0 ); //this flag is only for stopping during the current rendering progress, //so must be false at every new render operation mRenderContext.setRenderingStopped( false ); // set selection color QgsProject* prj = QgsProject::instance(); int myRed = prj->readNumEntry( "Gui", "/SelectionColorRedPart", 255 ); int myGreen = prj->readNumEntry( "Gui", "/SelectionColorGreenPart", 255 ); int myBlue = prj->readNumEntry( "Gui", "/SelectionColorBluePart", 0 ); int myAlpha = prj->readNumEntry( "Gui", "/SelectionColorAlphaPart", 255 ); mRenderContext.setSelectionColor( QColor( myRed, myGreen, myBlue, myAlpha ) ); //calculate scale factor //use the specified dpi and not those from the paint device //because sometimes QPainter units are in a local coord sys (e.g. in case of QGraphicsScene) double sceneDpi = mScaleCalculator->dpi(); double scaleFactor = 1.0; if ( mOutputUnits == QgsMapRenderer::Millimeters ) { if ( forceWidthScale ) { scaleFactor = *forceWidthScale; } else { scaleFactor = sceneDpi / 25.4; } } double rasterScaleFactor = ( thePaintDevice->logicalDpiX() + thePaintDevice->logicalDpiY() ) / 2.0 / sceneDpi; if ( mRenderContext.rasterScaleFactor() != rasterScaleFactor ) { mRenderContext.setRasterScaleFactor( rasterScaleFactor ); mySameAsLastFlag = false; } if ( mRenderContext.scaleFactor() != scaleFactor ) { mRenderContext.setScaleFactor( scaleFactor ); mySameAsLastFlag = false; } if ( mRenderContext.rendererScale() != mScale ) { //add map scale to render context mRenderContext.setRendererScale( mScale ); mySameAsLastFlag = false; } if ( mLastExtent != mExtent ) { mLastExtent = mExtent; mySameAsLastFlag = false; } mRenderContext.setLabelingEngine( mLabelingEngine ); if ( mLabelingEngine ) mLabelingEngine->init( this ); // know we know if this render is just a repeat of the last time, we // can clear caches if it has changed if ( !mySameAsLastFlag ) { //clear the cache pixmap if we changed resolution / extent QSettings mySettings; if ( mySettings.value( "/qgis/enable_render_caching", false ).toBool() ) { QgsMapLayerRegistry::instance()->clearAllLayerCaches(); } } // render all layers in the stack, starting at the base QListIterator<QString> li( mLayerSet ); li.toBack(); QgsRectangle r1, r2; while ( li.hasPrevious() ) { if ( mRenderContext.renderingStopped() ) { break; } // Store the painter in case we need to swap it out for the // cache painter QPainter * mypContextPainter = mRenderContext.painter(); // Flattened image for drawing when a blending mode is set QImage * mypFlattenedImage = 0; QString layerId = li.previous(); QgsDebugMsg( "Rendering at layer item " + layerId ); // This call is supposed to cause the progress bar to // advance. However, it seems that updating the progress bar is // incompatible with having a QPainter active (the one that is // passed into this function), as Qt produces a number of errors // when try to do so. I'm (Gavin) not sure how to fix this, but // added these comments and debug statement to help others... QgsDebugMsg( "If there is a QPaintEngine error here, it is caused by an emit call" ); //emit drawingProgress(myRenderCounter++, mLayerSet.size()); QgsMapLayer *ml = QgsMapLayerRegistry::instance()->mapLayer( layerId ); if ( !ml ) { QgsDebugMsg( "Layer not found in registry!" ); continue; } QgsDebugMsg( QString( "layer %1: minscale:%2 maxscale:%3 scaledepvis:%4 extent:%5 blendmode:%6" ) .arg( ml->name() ) .arg( ml->minimumScale() ) .arg( ml->maximumScale() ) .arg( ml->hasScaleBasedVisibility() ) .arg( ml->extent().toString() ) .arg( ml->blendMode() ) ); if ( mRenderContext.useAdvancedEffects() ) { // Set the QPainter composition mode so that this layer is rendered using // the desired blending mode mypContextPainter->setCompositionMode( ml->blendMode() ); } if ( !ml->hasScaleBasedVisibility() || ( ml->minimumScale() <= mScale && mScale < ml->maximumScale() ) || mOverview ) { connect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) ); // // Now do the call to the layer that actually does // the rendering work! // bool split = false; if ( hasCrsTransformEnabled() ) { r1 = mExtent; split = splitLayersExtent( ml, r1, r2 ); ct = transformation( ml ); mRenderContext.setExtent( r1 ); QgsDebugMsg( " extent 1: " + r1.toString() ); QgsDebugMsg( " extent 2: " + r2.toString() ); if ( !r1.isFinite() || !r2.isFinite() ) //there was a problem transforming the extent. Skip the layer { continue; } } else { ct = NULL; } mRenderContext.setCoordinateTransform( ct ); //decide if we have to scale the raster //this is necessary in case QGraphicsScene is used bool scaleRaster = false; QgsMapToPixel rasterMapToPixel; QgsMapToPixel bk_mapToPixel; if ( ml->type() == QgsMapLayer::RasterLayer && qAbs( rasterScaleFactor - 1.0 ) > 0.000001 ) { scaleRaster = true; } // Force render of layers that are being edited // or if there's a labeling engine that needs the layer to register features if ( ml->type() == QgsMapLayer::VectorLayer ) { QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml ); if ( vl->isEditable() || ( mRenderContext.labelingEngine() && mRenderContext.labelingEngine()->willUseLayer( vl ) ) ) { ml->setCacheImage( 0 ); } } QSettings mySettings; bool useRenderCaching = false; if ( ! split )//render caching does not yet cater for split extents { if ( mySettings.value( "/qgis/enable_render_caching", false ).toBool() ) { useRenderCaching = true; if ( !mySameAsLastFlag || ml->cacheImage() == 0 ) { QgsDebugMsg( "Caching enabled but layer redraw forced by extent change or empty cache" ); QImage * mypImage = new QImage( mRenderContext.painter()->device()->width(), mRenderContext.painter()->device()->height(), QImage::Format_ARGB32 ); if ( mypImage->isNull() ) { QgsDebugMsg( "insufficient memory for image " + QString::number( mRenderContext.painter()->device()->width() ) + "x" + QString::number( mRenderContext.painter()->device()->height() ) ); emit drawError( ml ); painter->end(); // drawError is not caught by anyone, so we end painting to notify caller return; } mypImage->fill( 0 ); ml->setCacheImage( mypImage ); //no need to delete the old one, maplayer does it for you QPainter * mypPainter = new QPainter( ml->cacheImage() ); // Changed to enable anti aliasing by default in QGIS 1.7 if ( mySettings.value( "/qgis/enable_anti_aliasing", true ).toBool() ) { mypPainter->setRenderHint( QPainter::Antialiasing ); } mRenderContext.setPainter( mypPainter ); } else if ( mySameAsLastFlag ) { //draw from cached image QgsDebugMsg( "Caching enabled --- drawing layer from cached image" ); mypContextPainter->drawImage( 0, 0, *( ml->cacheImage() ) ); disconnect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) ); //short circuit as there is nothing else to do... continue; } } } // If we are drawing with an alternative blending mode then we need to render to a separate image // before compositing this on the map. This effectively flattens the layer and prevents // blending occuring between objects on the layer // (this is not required for raster layers or when layer caching is enabled, since that has the same effect) bool flattenedLayer = false; if (( mRenderContext.useAdvancedEffects() ) && ( ml->type() == QgsMapLayer::VectorLayer ) ) { QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml ); if (( !useRenderCaching ) && (( vl->blendMode() != QPainter::CompositionMode_SourceOver ) || ( vl->featureBlendMode() != QPainter::CompositionMode_SourceOver ) || ( vl->layerTransparency() != 0 ) ) ) { flattenedLayer = true; mypFlattenedImage = new QImage( mRenderContext.painter()->device()->width(), mRenderContext.painter()->device()->height(), QImage::Format_ARGB32 ); if ( mypFlattenedImage->isNull() ) { QgsDebugMsg( "insufficient memory for image " + QString::number( mRenderContext.painter()->device()->width() ) + "x" + QString::number( mRenderContext.painter()->device()->height() ) ); emit drawError( ml ); painter->end(); // drawError is not caught by anyone, so we end painting to notify caller return; } mypFlattenedImage->fill( 0 ); QPainter * mypPainter = new QPainter( mypFlattenedImage ); if ( mySettings.value( "/qgis/enable_anti_aliasing", true ).toBool() ) { mypPainter->setRenderHint( QPainter::Antialiasing ); } mypPainter->scale( rasterScaleFactor, rasterScaleFactor ); mRenderContext.setPainter( mypPainter ); } } // Per feature blending mode if (( mRenderContext.useAdvancedEffects() ) && ( ml->type() == QgsMapLayer::VectorLayer ) ) { QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml ); if ( vl->featureBlendMode() != QPainter::CompositionMode_SourceOver ) { // set the painter to the feature blend mode, so that features drawn // on this layer will interact and blend with each other mRenderContext.painter()->setCompositionMode( vl->featureBlendMode() ); } } if ( scaleRaster ) { bk_mapToPixel = mRenderContext.mapToPixel(); rasterMapToPixel = mRenderContext.mapToPixel(); rasterMapToPixel.setMapUnitsPerPixel( mRenderContext.mapToPixel().mapUnitsPerPixel() / rasterScaleFactor ); rasterMapToPixel.setYMaximum( mSize.height() * rasterScaleFactor ); mRenderContext.setMapToPixel( rasterMapToPixel ); mRenderContext.painter()->save(); mRenderContext.painter()->scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor ); } if ( !ml->draw( mRenderContext ) ) { emit drawError( ml ); } else { QgsDebugMsg( "Layer rendered without issues" ); } if ( split ) { mRenderContext.setExtent( r2 ); if ( !ml->draw( mRenderContext ) ) { emit drawError( ml ); } } if ( scaleRaster ) { mRenderContext.setMapToPixel( bk_mapToPixel ); mRenderContext.painter()->restore(); } //apply layer transparency for vector layers if (( mRenderContext.useAdvancedEffects() ) && ( ml->type() == QgsMapLayer::VectorLayer ) ) { QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml ); if ( vl->layerTransparency() != 0 ) { // a layer transparency has been set, so update the alpha for the flattened layer // by combining it with the layer transparency QColor transparentFillColor = QColor( 0, 0, 0, 255 - ( 255 * vl->layerTransparency() / 100 ) ); // use destination in composition mode to merge source's alpha with destination mRenderContext.painter()->setCompositionMode( QPainter::CompositionMode_DestinationIn ); mRenderContext.painter()->fillRect( 0, 0, mRenderContext.painter()->device()->width(), mRenderContext.painter()->device()->height(), transparentFillColor ); } } if ( useRenderCaching ) { // composite the cached image into our view and then clean up from caching // by reinstating the painter as it was swapped out for caching renders delete mRenderContext.painter(); mRenderContext.setPainter( mypContextPainter ); //draw from cached image that we created further up if ( ml->cacheImage() ) mypContextPainter->drawImage( 0, 0, *( ml->cacheImage() ) ); } else if ( flattenedLayer ) { // If we flattened this layer for alternate blend modes, composite it now delete mRenderContext.painter(); mRenderContext.setPainter( mypContextPainter ); mypContextPainter->save(); mypContextPainter->scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor ); mypContextPainter->drawImage( 0, 0, *( mypFlattenedImage ) ); mypContextPainter->restore(); delete mypFlattenedImage; mypFlattenedImage = 0; } disconnect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) ); }
void PointCloudDisplay::reset() { RenderAutoLock renderLock( this ); cloud_->clear(); }
void PointCloudDisplay::fixedFrameChanged() { RenderAutoLock renderLock( this ); cloud_->clear(); }
void PointCloudDisplay::transformCloud() { if ( message_.header.frame_id.empty() ) { message_.header.frame_id = fixed_frame_; } tf::Stamped<tf::Pose> pose( btTransform( btQuaternion( 0, 0, 0 ), btVector3( 0, 0, 0 ) ), message_.header.stamp, message_.header.frame_id ); try { tf_->transformPose( fixed_frame_, pose, pose ); } catch(tf::TransformException& e) { ROS_ERROR( "Error transforming point cloud '%s' from frame '%s' to frame '%s'\n", name_.c_str(), message_.header.frame_id.c_str(), fixed_frame_.c_str() ); } Ogre::Vector3 position( pose.getOrigin().x(), pose.getOrigin().y(), pose.getOrigin().z() ); robotToOgre( position ); btScalar yaw, pitch, roll; pose.getBasis().getEulerZYX( yaw, pitch, roll ); Ogre::Matrix3 orientation( ogreMatrixFromRobotEulers( yaw, pitch, roll ) ); // First find the min/max intensity values float min_intensity = 999999.0f; float max_intensity = -999999.0f; typedef std::vector<std_msgs::ChannelFloat32> V_Chan; typedef std::vector<bool> V_bool; V_bool valid_channels(message_.chan.size()); uint32_t point_count = message_.get_pts_size(); V_Chan::iterator chan_it = message_.chan.begin(); V_Chan::iterator chan_end = message_.chan.end(); uint32_t index = 0; for ( ; chan_it != chan_end; ++chan_it, ++index ) { std_msgs::ChannelFloat32& chan = *chan_it; uint32_t val_count = chan.vals.size(); bool channel_size_correct = val_count == point_count; ROS_ERROR_COND(!channel_size_correct, "Point cloud '%s' on topic '%s' has channel 0 with fewer values than points (%d values, %d points)", name_.c_str(), topic_.c_str(), val_count, point_count); valid_channels[index] = channel_size_correct; if ( channel_size_correct && ( chan.name.empty() || chan.name == "intensity" || chan.name == "intensities" ) ) { for(uint32_t i = 0; i < point_count; i++) { float& intensity = chan.vals[i]; // arbitrarily cap to 4096 for now intensity = std::min( intensity, 4096.0f ); min_intensity = std::min( min_intensity, intensity ); max_intensity = std::max( max_intensity, intensity ); } } } float diff_intensity = max_intensity - min_intensity; typedef std::vector< ogre_tools::PointCloud::Point > V_Point; V_Point points; points.resize( point_count ); for(uint32_t i = 0; i < point_count; i++) { Ogre::Vector3 color( color_.r_, color_.g_, color_.b_ ); ogre_tools::PointCloud::Point& current_point = points[ i ]; current_point.x_ = message_.pts[i].x; current_point.y_ = message_.pts[i].y; current_point.z_ = message_.pts[i].z; current_point.r_ = color.x; current_point.g_ = color.y; current_point.b_ = color.z; } chan_it = message_.chan.begin(); index = 0; for ( ; chan_it != chan_end; ++chan_it, ++index ) { if ( !valid_channels[index] ) { continue; } std_msgs::ChannelFloat32& chan = *chan_it; enum ChannelType { CT_INTENSITY, CT_RGB, CT_R, CT_G, CT_B, CT_COUNT }; ChannelType type = CT_INTENSITY; if ( chan.name == "rgb" ) { type = CT_RGB; } else if ( chan.name == "r" ) { type = CT_R; } else if ( chan.name == "g" ) { type = CT_G; } else if ( chan.name == "b" ) { type = CT_B; } typedef void (*TransformFunc)(float, ogre_tools::PointCloud::Point&, float, float, float); TransformFunc funcs[CT_COUNT] = { transformIntensity, transformRGB, transformR, transformG, transformB }; for(uint32_t i = 0; i < point_count; i++) { ogre_tools::PointCloud::Point& current_point = points[ i ]; funcs[type]( chan.vals[i], current_point, min_intensity, max_intensity, diff_intensity ); } } { RenderAutoLock renderLock( this ); scene_node_->setPosition( position ); scene_node_->setOrientation( orientation ); cloud_->clear(); if ( !points.empty() ) { cloud_->addPoints( &points.front(), points.size() ); } } causeRender(); }
void admPreview::start( void ) { aprintf("--killing\n"); renderLock(); getFirstVideoFilter(); preview=videofilters[ nb_active_filter-1].filter; aprintf("--spawning\n"); ADM_assert(!previewImage) previewImage=new ADMImage(preview->getInfo()->width,preview->getInfo()->height); ADM_assert(!original); switch(previewMode) { case ADM_PREVIEW_SEPARATE: DIA_previewInit(preview->getInfo()->width,preview->getInfo()->height); /* no break here, not a mistake */ case ADM_PREVIEW_NONE: rdrWindowWUnzoomed=rdrPhysicalW; rdrWindowHUnzoomed=rdrPhysicalH; break; case ADM_PREVIEW_OUTPUT: rdrWindowWUnzoomed=preview->getInfo()->width; rdrWindowHUnzoomed=preview->getInfo()->height; break; case ADM_PREVIEW_SIDE: { rdrWindowWUnzoomed=rdrPhysicalW+preview->getInfo()->width; rdrWindowHUnzoomed=MAX(rdrPhysicalH,preview->getInfo()->height); original=new ADMImage(rdrWindowWUnzoomed,rdrWindowHUnzoomed); break; } case ADM_PREVIEW_TOP: { rdrWindowWUnzoomed=MAX(rdrPhysicalW,preview->getInfo()->width); rdrWindowHUnzoomed=rdrPhysicalH+preview->getInfo()->height; original=new ADMImage(rdrWindowWUnzoomed,rdrWindowHUnzoomed); break; } default: ADM_assert(0); } if(zoom!=ZOOM_1_1) { int mul; switch(zoom) { case ZOOM_1_4: mul=1;break; case ZOOM_1_2: mul=2;break; case ZOOM_1_1: mul=4;break; case ZOOM_2: mul=8;break; case ZOOM_4: mul=16;break; default : ADM_assert(0); } rdrWindowWZoomed=(rdrWindowWUnzoomed*mul+3)/4; rdrWindowHZoomed=(rdrWindowHUnzoomed*mul+3)/4; if(rdrWindowWZoomed&1) rdrWindowWZoomed++; if(rdrWindowHZoomed&1) rdrWindowHZoomed++; ADM_assert(!resized); resized=new ADMImage(rdrWindowWZoomed,rdrWindowHZoomed); ADM_assert(!resizer); resizer=new ADMImageResizer(rdrWindowWUnzoomed,rdrWindowHUnzoomed,rdrWindowWZoomed,rdrWindowHZoomed); renderResize(rdrWindowWZoomed,rdrWindowHZoomed,rdrWindowWUnzoomed,rdrWindowHUnzoomed); }else { renderResize(rdrWindowWUnzoomed,rdrWindowHUnzoomed,rdrWindowWUnzoomed,rdrWindowHUnzoomed); } renderUnlock(); }
void QgsMapRenderer::render( QPainter* painter, double* forceWidthScale ) { //Lock render method for concurrent threads (e.g. from globe) QMutexLocker renderLock( &mRenderMutex ); //flag to see if the render context has changed //since the last time we rendered. If it hasnt changed we can //take some shortcuts with rendering bool mySameAsLastFlag = true; QgsDebugMsg( "========== Rendering ==========" ); if ( mExtent.isEmpty() ) { QgsDebugMsg( "empty extent... not rendering" ); return; } if ( mSize.width() == 1 && mSize.height() == 1 ) { QgsDebugMsg( "size 1x1... not rendering" ); return; } QPaintDevice* thePaintDevice = painter->device(); if ( !thePaintDevice ) { return; } // wait if ( mDrawing ) { QgsDebugMsg( "already rendering" ); QCoreApplication::processEvents(); } if ( mDrawing ) { QgsDebugMsg( "still rendering - skipping" ); return; } mDrawing = true; QgsCoordinateTransform* ct; #ifdef QGISDEBUG QgsDebugMsg( "Starting to render layer stack." ); QTime renderTime; renderTime.start(); #endif if ( mOverview ) mRenderContext.setDrawEditingInformation( !mOverview ); mRenderContext.setPainter( painter ); mRenderContext.setCoordinateTransform( 0 ); //this flag is only for stopping during the current rendering progress, //so must be false at every new render operation mRenderContext.setRenderingStopped( false ); //calculate scale factor //use the specified dpi and not those from the paint device //because sometimes QPainter units are in a local coord sys (e.g. in case of QGraphicsScene) double sceneDpi = mScaleCalculator->dpi(); double scaleFactor = 1.0; if ( mOutputUnits == QgsMapRenderer::Millimeters ) { if ( forceWidthScale ) { scaleFactor = *forceWidthScale; } else { scaleFactor = sceneDpi / 25.4; } } double rasterScaleFactor = ( thePaintDevice->logicalDpiX() + thePaintDevice->logicalDpiY() ) / 2.0 / sceneDpi; if ( mRenderContext.rasterScaleFactor() != rasterScaleFactor ) { mRenderContext.setRasterScaleFactor( rasterScaleFactor ); mySameAsLastFlag = false; } if ( mRenderContext.scaleFactor() != scaleFactor ) { mRenderContext.setScaleFactor( scaleFactor ); mySameAsLastFlag = false; } if ( mRenderContext.rendererScale() != mScale ) { //add map scale to render context mRenderContext.setRendererScale( mScale ); mySameAsLastFlag = false; } if ( mLastExtent != mExtent ) { mLastExtent = mExtent; mySameAsLastFlag = false; } mRenderContext.setLabelingEngine( mLabelingEngine ); if ( mLabelingEngine ) mLabelingEngine->init( this ); // know we know if this render is just a repeat of the last time, we // can clear caches if it has changed if ( !mySameAsLastFlag ) { //clear the cache pixmap if we changed resolution / extent QSettings mySettings; if ( mySettings.value( "/qgis/enable_render_caching", false ).toBool() ) { QgsMapLayerRegistry::instance()->clearAllLayerCaches(); } } QgsOverlayObjectPositionManager* overlayManager = overlayManagerFromSettings(); QList<QgsVectorOverlay*> allOverlayList; //list of all overlays, used to draw them after layers have been rendered // render all layers in the stack, starting at the base QListIterator<QString> li( mLayerSet ); li.toBack(); QgsRectangle r1, r2; while ( li.hasPrevious() ) { if ( mRenderContext.renderingStopped() ) { break; } // Store the painter in case we need to swap it out for the // cache painter QPainter * mypContextPainter = mRenderContext.painter(); QString layerId = li.previous(); QgsDebugMsg( "Rendering at layer item " + layerId ); // This call is supposed to cause the progress bar to // advance. However, it seems that updating the progress bar is // incompatible with having a QPainter active (the one that is // passed into this function), as Qt produces a number of errors // when try to do so. I'm (Gavin) not sure how to fix this, but // added these comments and debug statement to help others... QgsDebugMsg( "If there is a QPaintEngine error here, it is caused by an emit call" ); //emit drawingProgress(myRenderCounter++, mLayerSet.size()); QgsMapLayer *ml = QgsMapLayerRegistry::instance()->mapLayer( layerId ); if ( !ml ) { QgsDebugMsg( "Layer not found in registry!" ); continue; } QgsDebugMsg( QString( "layer %1: minscale:%2 maxscale:%3 scaledepvis:%4 extent:%5" ) .arg( ml->name() ) .arg( ml->minimumScale() ) .arg( ml->maximumScale() ) .arg( ml->hasScaleBasedVisibility() ) .arg( ml->extent().toString() ) ); if ( !ml->hasScaleBasedVisibility() || ( ml->minimumScale() < mScale && mScale < ml->maximumScale() ) || mOverview ) { connect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) ); // // Now do the call to the layer that actually does // the rendering work! // bool split = false; if ( hasCrsTransformEnabled() ) { r1 = mExtent; split = splitLayersExtent( ml, r1, r2 ); ct = new QgsCoordinateTransform( ml->crs(), *mDestCRS ); mRenderContext.setExtent( r1 ); QgsDebugMsg( " extent 1: " + r1.toString() ); QgsDebugMsg( " extent 2: " + r2.toString() ); if ( !r1.isFinite() || !r2.isFinite() ) //there was a problem transforming the extent. Skip the layer { continue; } } else { ct = NULL; } mRenderContext.setCoordinateTransform( ct ); //decide if we have to scale the raster //this is necessary in case QGraphicsScene is used bool scaleRaster = false; QgsMapToPixel rasterMapToPixel; QgsMapToPixel bk_mapToPixel; if ( ml->type() == QgsMapLayer::RasterLayer && qAbs( rasterScaleFactor - 1.0 ) > 0.000001 ) { scaleRaster = true; } //create overlay objects for features within the view extent if ( ml->type() == QgsMapLayer::VectorLayer && overlayManager ) { QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml ); if ( vl ) { QList<QgsVectorOverlay*> thisLayerOverlayList; vl->vectorOverlays( thisLayerOverlayList ); QList<QgsVectorOverlay*>::iterator overlayIt = thisLayerOverlayList.begin(); for ( ; overlayIt != thisLayerOverlayList.end(); ++overlayIt ) { if (( *overlayIt )->displayFlag() ) { ( *overlayIt )->createOverlayObjects( mRenderContext ); allOverlayList.push_back( *overlayIt ); } } overlayManager->addLayer( vl, thisLayerOverlayList ); } } // Force render of layers that are being edited // or if there's a labeling engine that needs the layer to register features if ( ml->type() == QgsMapLayer::VectorLayer ) { QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml ); if ( vl->isEditable() || ( mRenderContext.labelingEngine() && mRenderContext.labelingEngine()->willUseLayer( vl ) ) ) { ml->setCacheImage( 0 ); } } QSettings mySettings; if ( ! split )//render caching does not yet cater for split extents { if ( mySettings.value( "/qgis/enable_render_caching", false ).toBool() ) { if ( !mySameAsLastFlag || ml->cacheImage() == 0 ) { QgsDebugMsg( "Caching enabled but layer redraw forced by extent change or empty cache" ); QImage * mypImage = new QImage( mRenderContext.painter()->device()->width(), mRenderContext.painter()->device()->height(), QImage::Format_ARGB32 ); mypImage->fill( 0 ); ml->setCacheImage( mypImage ); //no need to delete the old one, maplayer does it for you QPainter * mypPainter = new QPainter( ml->cacheImage() ); // Changed to enable anti aliasing by default in QGIS 1.7 if ( mySettings.value( "/qgis/enable_anti_aliasing", true ).toBool() ) { mypPainter->setRenderHint( QPainter::Antialiasing ); } mRenderContext.setPainter( mypPainter ); } else if ( mySameAsLastFlag ) { //draw from cached image QgsDebugMsg( "Caching enabled --- drawing layer from cached image" ); mypContextPainter->drawImage( 0, 0, *( ml->cacheImage() ) ); disconnect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) ); //short circuit as there is nothing else to do... continue; } } } if ( scaleRaster ) { bk_mapToPixel = mRenderContext.mapToPixel(); rasterMapToPixel = mRenderContext.mapToPixel(); rasterMapToPixel.setMapUnitsPerPixel( mRenderContext.mapToPixel().mapUnitsPerPixel() / rasterScaleFactor ); rasterMapToPixel.setYMaximum( mSize.height() * rasterScaleFactor ); mRenderContext.setMapToPixel( rasterMapToPixel ); mRenderContext.painter()->save(); mRenderContext.painter()->scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor ); } if ( !ml->draw( mRenderContext ) ) { emit drawError( ml ); } else { QgsDebugMsg( "Layer rendered without issues" ); } if ( split ) { mRenderContext.setExtent( r2 ); if ( !ml->draw( mRenderContext ) ) { emit drawError( ml ); } } if ( scaleRaster ) { mRenderContext.setMapToPixel( bk_mapToPixel ); mRenderContext.painter()->restore(); } if ( mySettings.value( "/qgis/enable_render_caching", false ).toBool() ) { if ( !split ) { // composite the cached image into our view and then clean up from caching // by reinstating the painter as it was swapped out for caching renders delete mRenderContext.painter(); mRenderContext.setPainter( mypContextPainter ); //draw from cached image that we created further up mypContextPainter->drawImage( 0, 0, *( ml->cacheImage() ) ); } } disconnect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) ); } else // layer not visible due to scale {