• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

marble

  • sources
  • kde-4.14
  • kdeedu
  • marble
  • src
  • lib
  • marble
EquirectScanlineTextureMapper.cpp
Go to the documentation of this file.
1 //
2 // This file is part of the Marble Virtual Globe.
3 //
4 // This program is free software licensed under the GNU LGPL. You can
5 // find a copy of this license in LICENSE.txt in the top directory of
6 // the source code.
7 //
8 // Copyright 2007 Carlos Licea <carlos _licea@hotmail.com>
9 // Copyright 2011 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
10 //
11 
12 
13 // local
14 #include"EquirectScanlineTextureMapper.h"
15 
16 // posix
17 #include <cmath>
18 
19 // Qt
20 #include <QRunnable>
21 
22 // Marble
23 #include "GeoPainter.h"
24 #include "MarbleDebug.h"
25 #include "ScanlineTextureMapperContext.h"
26 #include "StackedTileLoader.h"
27 #include "TextureColorizer.h"
28 #include "ViewportParams.h"
29 
30 using namespace Marble;
31 
32 class EquirectScanlineTextureMapper::RenderJob : public QRunnable
33 {
34 public:
35  RenderJob( StackedTileLoader *tileLoader, int tileLevel, QImage *canvasImage, const ViewportParams *viewportParams, MapQuality mapQuality, int yTop, int yBottom );
36 
37  virtual void run();
38 
39 private:
40  StackedTileLoader *const m_tileLoader;
41  const int m_tileLevel;
42  QImage *const m_canvasImage;
43  const ViewportParams *const m_viewport;
44  const MapQuality m_mapQuality;
45  const int m_yPaintedTop;
46  const int m_yPaintedBottom;
47 };
48 
49 EquirectScanlineTextureMapper::RenderJob::RenderJob( StackedTileLoader *tileLoader, int tileLevel, QImage *canvasImage, const ViewportParams *viewport, MapQuality mapQuality, int yTop, int yBottom )
50  : m_tileLoader( tileLoader ),
51  m_tileLevel( tileLevel ),
52  m_canvasImage( canvasImage ),
53  m_viewport( viewport ),
54  m_mapQuality( mapQuality ),
55  m_yPaintedTop( yTop ),
56  m_yPaintedBottom( yBottom )
57 {
58 }
59 
60 
61 EquirectScanlineTextureMapper::EquirectScanlineTextureMapper( StackedTileLoader *tileLoader )
62  : TextureMapperInterface(),
63  m_tileLoader( tileLoader ),
64  m_radius( 0 ),
65  m_oldYPaintedTop( 0 )
66 {
67 }
68 
69 void EquirectScanlineTextureMapper::mapTexture( GeoPainter *painter,
70  const ViewportParams *viewport,
71  int tileZoomLevel,
72  const QRect &dirtyRect,
73  TextureColorizer *texColorizer )
74 {
75  if ( m_canvasImage.size() != viewport->size() || m_radius != viewport->radius() ) {
76  const QImage::Format optimalFormat = ScanlineTextureMapperContext::optimalCanvasImageFormat( viewport );
77 
78  if ( m_canvasImage.size() != viewport->size() || m_canvasImage.format() != optimalFormat ) {
79  m_canvasImage = QImage( viewport->size(), optimalFormat );
80  }
81 
82  if ( !viewport->mapCoversViewport() ) {
83  m_canvasImage.fill( 0 );
84  }
85 
86  m_radius = viewport->radius();
87  m_repaintNeeded = true;
88  }
89 
90  if ( m_repaintNeeded ) {
91  mapTexture( viewport, tileZoomLevel, painter->mapQuality() );
92 
93  if ( texColorizer ) {
94  texColorizer->colorize( &m_canvasImage, viewport, painter->mapQuality() );
95  }
96 
97  m_repaintNeeded = false;
98  }
99 
100  painter->drawImage( dirtyRect, m_canvasImage, dirtyRect );
101 }
102 
103 void EquirectScanlineTextureMapper::mapTexture( const ViewportParams *viewport, int tileZoomLevel, MapQuality mapQuality )
104 {
105  // Reset backend
106  m_tileLoader->resetTilehash();
107 
108  // Initialize needed constants:
109 
110  const int imageHeight = m_canvasImage.height();
111  const qint64 radius = viewport->radius();
112  // Calculate how many degrees are being represented per pixel.
113  const float rad2Pixel = (float)( 2 * radius ) / M_PI;
114 
115  // Calculate translation of center point
116  const qreal centerLat = viewport->centerLatitude();
117 
118  int yCenterOffset = (int)( centerLat * rad2Pixel );
119 
120  // Calculate y-range the represented by the center point, yTop and
121  // what actually can be painted
122  const int yTop = imageHeight / 2 - radius + yCenterOffset;;
123  int yPaintedTop = imageHeight / 2 - radius + yCenterOffset;
124  int yPaintedBottom = imageHeight / 2 + radius + yCenterOffset;
125 
126  if (yPaintedTop < 0) yPaintedTop = 0;
127  if (yPaintedTop > imageHeight) yPaintedTop = imageHeight;
128  if (yPaintedBottom < 0) yPaintedBottom = 0;
129  if (yPaintedBottom > imageHeight) yPaintedBottom = imageHeight;
130 
131  const int numThreads = m_threadPool.maxThreadCount();
132  const int yStep = ( yPaintedBottom - yPaintedTop ) / numThreads;
133  for ( int i = 0; i < numThreads; ++i ) {
134  const int yStart = yPaintedTop + i * yStep;
135  const int yEnd = yPaintedTop + (i + 1) * yStep;
136  QRunnable *const job = new RenderJob( m_tileLoader, tileZoomLevel, &m_canvasImage, viewport, mapQuality, yStart, yEnd );
137  m_threadPool.start( job );
138  }
139 
140  // Remove unused lines
141  const int clearStart = ( yPaintedTop - m_oldYPaintedTop <= 0 ) ? yPaintedBottom : 0;
142  const int clearStop = ( yPaintedTop - m_oldYPaintedTop <= 0 ) ? imageHeight : yTop;
143 
144  QRgb * const itClearBegin = (QRgb*)( m_canvasImage.scanLine( clearStart ) );
145  QRgb * const itClearEnd = (QRgb*)( m_canvasImage.scanLine( clearStop ) );
146 
147  for ( QRgb * it = itClearBegin; it < itClearEnd; ++it ) {
148  *(it) = 0;
149  }
150 
151  m_threadPool.waitForDone();
152 
153  m_oldYPaintedTop = yPaintedTop;
154 
155  m_tileLoader->cleanupTilehash();
156 }
157 
158 void EquirectScanlineTextureMapper::RenderJob::run()
159 {
160  // Scanline based algorithm to do texture mapping
161 
162  const int imageHeight = m_canvasImage->height();
163  const int imageWidth = m_canvasImage->width();
164  const qint64 radius = m_viewport->radius();
165  // Calculate how many degrees are being represented per pixel.
166  const qreal rad2Pixel = (qreal)( 2 * radius ) / M_PI;
167  const float pixel2Rad = 1.0/rad2Pixel; // FIXME chainging to qreal may crash Marble when the equator is visible
168 
169  const bool interlaced = ( m_mapQuality == LowQuality );
170  const bool highQuality = ( m_mapQuality == HighQuality
171  || m_mapQuality == PrintQuality );
172  const bool printQuality = ( m_mapQuality == PrintQuality );
173 
174  // Evaluate the degree of interpolation
175  const int n = ScanlineTextureMapperContext::interpolationStep( m_viewport, m_mapQuality );
176 
177  // Calculate translation of center point
178  const qreal centerLon = m_viewport->centerLongitude();
179  const qreal centerLat = m_viewport->centerLatitude();
180 
181  const int yCenterOffset = (int)( centerLat * rad2Pixel );
182 
183  const int yTop = imageHeight / 2 - radius + yCenterOffset;
184 
185  qreal leftLon = + centerLon - ( imageWidth / 2 * pixel2Rad );
186  while ( leftLon < -M_PI ) leftLon += 2 * M_PI;
187  while ( leftLon > M_PI ) leftLon -= 2 * M_PI;
188 
189  const int maxInterpolationPointX = n * (int)( imageWidth / n - 1 ) + 1;
190 
191 
192  // initialize needed variables that are modified during texture mapping:
193 
194  ScanlineTextureMapperContext context( m_tileLoader, m_tileLevel );
195 
196 
197  // Scanline based algorithm to do texture mapping
198 
199  for ( int y = m_yPaintedTop; y < m_yPaintedBottom; ++y ) {
200 
201  QRgb * scanLine = (QRgb*)( m_canvasImage->scanLine( y ) );
202 
203  qreal lon = leftLon;
204  const qreal lat = M_PI/2 - (y - yTop )* pixel2Rad;
205 
206  for ( int x = 0; x < imageWidth; ++x ) {
207 
208  // Prepare for interpolation
209  bool interpolate = false;
210  if ( x > 0 && x <= maxInterpolationPointX ) {
211  x += n - 1;
212  lon += (n - 1) * pixel2Rad;
213  interpolate = !printQuality;
214  }
215  else {
216  interpolate = false;
217  }
218 
219  if ( lon < -M_PI ) lon += 2 * M_PI;
220  if ( lon > M_PI ) lon -= 2 * M_PI;
221 
222  if ( interpolate ) {
223  if (highQuality)
224  context.pixelValueApproxF( lon, lat, scanLine, n );
225  else
226  context.pixelValueApprox( lon, lat, scanLine, n );
227 
228  scanLine += ( n - 1 );
229  }
230 
231  if ( x < imageWidth ) {
232  if ( highQuality )
233  context.pixelValueF( lon, lat, scanLine );
234  else
235  context.pixelValue( lon, lat, scanLine );
236  }
237 
238  ++scanLine;
239  lon += pixel2Rad;
240  }
241 
242  // copy scanline to improve performance
243  if ( interlaced && y + 1 < m_yPaintedBottom ) {
244 
245  const int pixelByteSize = m_canvasImage->bytesPerLine() / imageWidth;
246 
247  memcpy( m_canvasImage->scanLine( y + 1 ),
248  m_canvasImage->scanLine( y ),
249  imageWidth * pixelByteSize );
250  ++y;
251  }
252  }
253 }
QImage::scanLine
uchar * scanLine(int i)
interpolate
void interpolate(MarbleWidget *widget, qreal value)
Definition: examples/cpp/animation-video/main.cpp:68
Marble::ViewportParams::size
QSize size() const
Definition: ViewportParams.cpp:260
Marble::GeoPainter
A painter that allows to draw geometric primitives on the map.
Definition: GeoPainter.h:98
Marble::EquirectScanlineTextureMapper::mapTexture
virtual void mapTexture(GeoPainter *painter, const ViewportParams *viewport, int tileZoomLevel, const QRect &dirtyRect, TextureColorizer *texColorizer)
Definition: EquirectScanlineTextureMapper.cpp:69
Marble::TextureColorizer::colorize
void colorize(QImage *origimg, const ViewportParams *viewport, MapQuality mapQuality)
Definition: TextureColorizer.cpp:228
Marble::PrintQuality
Print quality.
Definition: MarbleGlobal.h:87
Marble::MapQuality
MapQuality
This enum is used to choose the map quality shown in the view.
Definition: MarbleGlobal.h:82
ScanlineTextureMapperContext.h
MarbleDebug.h
TextureColorizer.h
Marble::StackedTileLoader
Tile loading from a quad tree.
Definition: StackedTileLoader.h:59
QRunnable
Marble::EquirectScanlineTextureMapper::EquirectScanlineTextureMapper
EquirectScanlineTextureMapper(StackedTileLoader *tileLoader)
Definition: EquirectScanlineTextureMapper.cpp:61
Marble::LowQuality
Low resolution (e.g. interlaced)
Definition: MarbleGlobal.h:84
QRect
QThreadPool::maxThreadCount
maxThreadCount
QImage::fill
void fill(uint pixelValue)
Marble::TextureMapperInterface
Definition: TextureMapperInterface.h:27
Marble::ViewportParams::mapCoversViewport
bool mapCoversViewport() const
Definition: ViewportParams.cpp:398
EquirectScanlineTextureMapper.h
Marble::ScanlineTextureMapperContext::optimalCanvasImageFormat
static QImage::Format optimalCanvasImageFormat(const ViewportParams *viewport)
Definition: ScanlineTextureMapperContext.cpp:429
Marble::radius
static qreal radius(qreal zoom)
Definition: thumbnailer.cpp:99
Marble::StackedTileLoader::cleanupTilehash
void cleanupTilehash()
Cleans up the internal tile hash.
Definition: StackedTileLoader.cpp:100
QtConcurrent::run
QFuture< T > run(Function function,...)
GeoPainter.h
Marble::ViewportParams
A public class that controls what is visible in the viewport of a Marble map.
Definition: ViewportParams.h:44
Marble::GeoPainter::drawImage
void drawImage(const GeoDataCoordinates &centerPosition, const QImage &image)
Draws an image at the given position. The image is placed with its center located at the given center...
Definition: GeoPainter.cpp:428
Marble::TextureColorizer
Definition: TextureColorizer.h:33
ViewportParams.h
This file contains the headers for ViewportParams.
QImage
Marble::ViewportParams::centerLatitude
qreal centerLatitude() const
Definition: ViewportParams.cpp:294
QThreadPool::waitForDone
void waitForDone()
Marble::TextureMapperInterface::m_repaintNeeded
bool m_repaintNeeded
Definition: TextureMapperInterface.h:42
Marble::ViewportParams::radius
int radius() const
Definition: ViewportParams.cpp:195
Marble::HighQuality
High quality (e.g. antialiasing for lines)
Definition: MarbleGlobal.h:86
Marble::ScanlineTextureMapperContext::interpolationStep
static int interpolationStep(const ViewportParams *viewport, MapQuality mapQuality)
Definition: ScanlineTextureMapperContext.cpp:401
QImage::size
QSize size() const
M_PI
#define M_PI
Definition: GeoDataCoordinates.h:26
Marble::ScanlineTextureMapperContext
Definition: ScanlineTextureMapperContext.h:30
QImage::height
int height() const
Marble::GeoPainter::mapQuality
MapQuality mapQuality() const
Returns the map quality.
Definition: GeoPainter.cpp:191
QThreadPool::start
void start(QRunnable *runnable, int priority)
QImage::format
Format format() const
Marble::StackedTileLoader::resetTilehash
void resetTilehash()
Resets the internal tile hash.
Definition: StackedTileLoader.cpp:90
StackedTileLoader.h
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:13:39 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

marble

Skip menu "marble"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal