[Marble-devel] [PATCH 05/13] Implement sun light blending with citylights theme as Blending sub class.
Torsten Rahn
tackat at t-online.de
Wed Mar 31 09:36:10 CEST 2010
Wow, I had almost forgotten how scary (but pretty efficient) this optimized piece
of code was.
Looks good to me. Ship it.
On Dienstag 30 März 2010 20:31:09 Jens-Michael Hoffmann wrote:
> Implement sun light blending with citylights theme as Blending sub class.
>
> As a side effect a lot of stuff could be removed from MergedLayerDecorator.
> However there are some regressions at the moment:
> - the blending is no longer available on celestial bodies other than earth,
> - is only possible with citylights theme (no plain darkening),
> - is always active (cannot be turned off),
> - only support current (and not arbitrary) date and time,
> - centering the sun and following time source (with different speeds) does
> no longer work.
> ---
> marble/data/maps/earth/bluemarble/bluemarble.dgml | 6 +
> marble/src/lib/BlendingFactory.cpp | 2 +
> marble/src/lib/CMakeLists.txt | 1 +
> marble/src/lib/MergedLayerDecorator.cpp | 241
> +-------------------- marble/src/lib/MergedLayerDecorator.h |
> 19 +--
> marble/src/lib/blendings/SunLightBlending.cpp | 207
> ++++++++++++++++++ marble/src/lib/blendings/SunLightBlending.h |
> 45 ++++
> 7 files changed, 266 insertions(+), 255 deletions(-)
> create mode 100644 marble/src/lib/blendings/SunLightBlending.cpp
> create mode 100644 marble/src/lib/blendings/SunLightBlending.h
>
> diff --git a/marble/data/maps/earth/bluemarble/bluemarble.dgml
> b/marble/data/maps/earth/bluemarble/bluemarble.dgml index d4c5d5e..6924820
> 100644
> --- a/marble/data/maps/earth/bluemarble/bluemarble.dgml
> +++ b/marble/data/maps/earth/bluemarble/bluemarble.dgml
> @@ -44,6 +44,12 @@
> <storageLayout maximumTileLevel="1"/>
> <blending name="CloudsBlending" />
> </texture>
> + <texture name="citylights_data">
> + <sourcedir format="JPG"> earth/citylights </sourcedir>
> + <installmap> citylights.jpg </installmap>
> + <storageLayout maximumTileLevel="3"/>
> + <blending name="SunLightBlending" />
> + </texture>
> </layer>
>
> <layer name="mwdbii" backend="vector" role="polyline">
> diff --git a/marble/src/lib/BlendingFactory.cpp
> b/marble/src/lib/BlendingFactory.cpp index c32f11b..c9247a3 100644
> --- a/marble/src/lib/BlendingFactory.cpp
> +++ b/marble/src/lib/BlendingFactory.cpp
> @@ -15,6 +15,7 @@
>
> #include "BlendingFactory.h"
>
> +#include "blendings/SunLightBlending.h"
> #include "BlendingAlgorithms.h"
> #include "MarbleDebug.h"
>
> @@ -81,6 +82,7 @@ BlendingFactory::BlendingFactory()
>
> // Special purpose blendings
> m_blendings.insert( "CloudsBlending", new CloudsBlending );
> + m_blendings.insert( "SunLightBlending", new SunLightBlending );
> }
>
> }
> diff --git a/marble/src/lib/CMakeLists.txt b/marble/src/lib/CMakeLists.txt
> index c9a6f31..59e4505 100644
> --- a/marble/src/lib/CMakeLists.txt
> +++ b/marble/src/lib/CMakeLists.txt
> @@ -59,6 +59,7 @@ set(marblewidget_SRCS
> ${geodata_SRCS}
> ${graphicsview_SRCS}
> ${screengraphicsitem_SRCS}
> + blendings/SunLightBlending.cpp
> Blending.cpp
> BlendingAlgorithms.cpp
> BlendingFactory.cpp
> diff --git a/marble/src/lib/MergedLayerDecorator.cpp
> b/marble/src/lib/MergedLayerDecorator.cpp index daca26c..a846d15 100644
> --- a/marble/src/lib/MergedLayerDecorator.cpp
> +++ b/marble/src/lib/MergedLayerDecorator.cpp
> @@ -17,71 +17,24 @@
>
> #include "MergedLayerDecorator.h"
>
> +#include <QtCore/QString>
> +#include <QtGui/QImage>
> #include <QtGui/QPainter>
>
> -#include "SunLocator.h"
> -#include "StackedTileLoader.h"
> #include "global.h"
> -#include "MarbleDebug.h"
> -#include "GeoSceneDocument.h"
> -#include "GeoSceneHead.h"
> -#include "GeoSceneMap.h"
> -#include "GeoSceneSettings.h"
> -#include "GeoSceneTexture.h"
> -#include "MapThemeManager.h"
> -#include "StackedTile.h"
> -#include "TileLoaderHelper.h"
> -#include "Planet.h"
>
> using namespace Marble;
>
> MergedLayerDecorator::MergedLayerDecorator( StackedTileLoader * const
> tileLoader, SunLocator* sunLocator ) - : m_tileLoader( tileLoader ),
> - m_tile( 0 ),
> + : m_tile( 0 ),
> m_id(),
> - m_sunLocator( sunLocator ),
> - m_showTileId( false ),
> - m_cityLightsTheme( 0 ),
> - m_cityLightsTextureLayer( 0 )
> + m_showTileId( false )
> {
> }
>
> -void MergedLayerDecorator::initCityLights()
> -{
> - // look for the texture layers inside the themes
> - // As long as we don't have an Layer Management Class we just lookup
> - // the name of the layer that has the same name as the theme ID
> -
> - mDebug() << Q_FUNC_INFO;
> - m_cityLightsTheme = MapThemeManager::loadMapTheme(
> "earth/citylights/citylights.dgml" ); - if (m_cityLightsTheme) {
> - QString cityLightsId = m_cityLightsTheme->head()->theme();
> - m_cityLightsTextureLayer = static_cast<GeoSceneTexture*>(
> - m_cityLightsTheme->map()->layer( cityLightsId
> )->datasets().first() ); - }
> -}
> -
> -MergedLayerDecorator::~MergedLayerDecorator()
> -{
> - delete m_cityLightsTheme;
> -}
> -
> void MergedLayerDecorator::paint( const QString& themeId, GeoSceneDocument
> *mapTheme ) {
> -// QTime time;
> -// time.start();
> -
> - if ( m_sunLocator->getShow() && mapTheme ) {
> -
> - // Initialize citylights layer if it hasn't happened already
> - if ( !m_cityLightsTheme ) {
> - initCityLights();
> - }
> -// QTime time2;
> -// time2.start();
> - paintSunShading();
> - }
> if ( m_showTileId ) {
> paintTileId( themeId );
> }
> @@ -97,170 +50,6 @@ bool MergedLayerDecorator::showTileId() const
> return m_showTileId;
> }
>
> -StackedTile * MergedLayerDecorator::loadDataset( GeoSceneTexture
> *textureLayer ) -{
> - const TileId decorationTileId( textureLayer->sourceDir(),
> m_id.zoomLevel(), m_id.x(), m_id.y()); - StackedTile * const tile =
> m_tileLoader->loadTile( decorationTileId, true ); - tile->setUsed( true
> );
> - return tile;
> -}
> -
> -void MergedLayerDecorator::paintSunShading()
> -{
> - if ( m_tile->depth() != 32 )
> - return;
> -
> - // TODO add support for 8-bit maps?
> - // add sun shading
> - const qreal global_width = m_tile->width()
> - * TileLoaderHelper::levelToColumn(
> m_cityLightsTextureLayer->levelZeroColumns(), -
> m_id.zoomLevel() );
> - const qreal global_height = m_tile->height()
> - * TileLoaderHelper::levelToRow(
> m_cityLightsTextureLayer->levelZeroRows(), -
> m_id.zoomLevel() );
> - const qreal lon_scale = 2*M_PI / global_width;
> - const qreal lat_scale = -M_PI / global_height;
> - const int tileHeight = m_tile->height();
> - const int tileWidth = m_tile->width();
> -
> - // First we determine the supporting point interval for the
> interpolation. - const int n = maxDivisor( 30, tileWidth );
> - const int ipRight = n * (int)( tileWidth / n );
> -
> - //Don't use city lights on non-earth planets!
> - if ( m_sunLocator->getCitylights() && m_sunLocator->planet()->id() ==
> "earth" ) { -
> - StackedTile * tile = loadDataset( m_cityLightsTextureLayer );
> - if ( tile->state() == StackedTile::TileEmpty )
> - return;
> -
> - QImage * nighttile = tile->resultTile();
> -
> - for ( int cur_y = 0; cur_y < tileHeight; ++cur_y ) {
> - qreal lat = lat_scale * ( m_id.y() * tileHeight + cur_y ) -
> 0.5*M_PI; - qreal a = sin( ( lat+DEG2RAD *
> m_sunLocator->getLat() )/2.0 ); - qreal c = cos(lat)*cos(
> -DEG2RAD * m_sunLocator->getLat() ); -
> - QRgb* scanline = (QRgb*)m_tile->scanLine( cur_y );
> - QRgb* nscanline = (QRgb*)nighttile->scanLine( cur_y );
> -
> - qreal shade = 0;
> - qreal lastShade = -10.0;
> -
> - int cur_x = 0;
> -
> - while ( cur_x < tileWidth ) {
> -
> - bool interpolate = ( cur_x != 0 && cur_x < ipRight &&
> cur_x + n < tileWidth ); -
> - if ( interpolate ) {
> - int check = cur_x + n;
> - qreal checklon = lon_scale * ( m_id.x() * tileWidth
> + check ); - shade = m_sunLocator->shading( checklon,
> a, c ); -
> - // if the shading didn't change across the
> interpolation - // interval move on and don't change
> anything. - if ( shade == lastShade && shade == 1.0 ) {
> - scanline += n;
> - nscanline += n;
> - cur_x += n;
> - continue;
> - }
> - if ( shade == lastShade && shade == 0.0 ) {
> - for ( int t = 0; t < n; ++t ) {
> - m_sunLocator->shadePixelComposite( *scanline,
> *nscanline, shade ); - ++scanline;
> - ++nscanline;
> - }
> - cur_x += n;
> - continue;
> - }
> - for ( int t = 0; t < n ; ++t ) {
> - qreal lon = lon_scale * ( m_id.x() * tileWidth +
> cur_x ); - shade = m_sunLocator->shading( lon, a, c
> ); - m_sunLocator->shadePixelComposite( *scanline,
> *nscanline, shade ); - ++scanline;
> - ++nscanline;
> - ++cur_x;
> - }
> - }
> -
> - else {
> - // Make sure we don't exceed the image memory
> - if ( cur_x < tileWidth ) {
> - qreal lon = lon_scale * ( m_id.x() * tileWidth +
> cur_x ); - shade = m_sunLocator->shading( lon, a, c
> ); - m_sunLocator->shadePixelComposite( *scanline,
> *nscanline, shade ); - ++scanline;
> - ++nscanline;
> - ++cur_x;
> - }
> - }
> - lastShade = shade;
> - }
> - }
> - } else {
> - for ( int cur_y = 0; cur_y < tileHeight; ++cur_y ) {
> - qreal lat = lat_scale * ( m_id.y() * tileHeight + cur_y ) -
> 0.5*M_PI; - qreal a = sin( (lat+DEG2RAD *
> m_sunLocator->getLat() )/2.0 ); - qreal c = cos(lat)*cos(
> -DEG2RAD * m_sunLocator->getLat() ); -
> - QRgb* scanline = (QRgb*)m_tile->scanLine( cur_y );
> -
> - qreal shade = 0;
> - qreal lastShade = -10.0;
> -
> - int cur_x = 0;
> -
> - while ( cur_x < tileWidth ) {
> -
> - bool interpolate = ( cur_x != 0 && cur_x < ipRight &&
> cur_x + n < tileWidth ); -
> - if ( interpolate ) {
> - int check = cur_x + n;
> - qreal checklon = lon_scale * ( m_id.x() * tileWidth
> + check ); - shade = m_sunLocator->shading( checklon,
> a, c ); -
> - // if the shading didn't change across the
> interpolation - // interval move on and don't change
> anything. - if ( shade == lastShade && shade == 1.0 ) {
> - scanline += n;
> - cur_x += n;
> - continue;
> - }
> - if ( shade == lastShade && shade == 0.0 ) {
> - for ( int t = 0; t < n; ++t ) {
> - m_sunLocator->shadePixel( *scanline, shade );
> - ++scanline;
> - }
> - cur_x += n;
> - continue;
> - }
> - for ( int t = 0; t < n ; ++t ) {
> - qreal lon = lon_scale * ( m_id.x() * tileWidth +
> cur_x ); - shade = m_sunLocator->shading( lon, a, c
> ); - m_sunLocator->shadePixel( *scanline, shade );
> - ++scanline;
> - ++cur_x;
> - }
> - }
> -
> - else {
> - // Make sure we don't exceed the image memory
> - if ( cur_x < tileWidth ) {
> - qreal lon = lon_scale * ( m_id.x() * tileWidth +
> cur_x ); - shade = m_sunLocator->shading( lon, a, c
> ); - m_sunLocator->shadePixel( *scanline, shade );
> - ++scanline;
> - ++cur_x;
> - }
> - }
> - lastShade = shade;
> - }
> - }
> - }
> -}
> -
> void MergedLayerDecorator::paintTileId( const QString& themeId )
> {
> QString filename = QString( "%1_%2.jpg" )
> @@ -333,26 +122,4 @@ void MergedLayerDecorator::setInfo( TileId const& id )
> m_id = id;
> }
>
> -// TODO: This should likely go into a math class in the future ...
> -
> -int MergedLayerDecorator::maxDivisor( int maximum, int fullLength )
> -{
> - // Find the optimal interpolation interval n for the
> - // current image canvas width
> - int best = 2;
> -
> - int nEvalMin = fullLength;
> - for ( int it = 1; it <= maximum; ++it ) {
> - // The optimum is the interval which results in the least amount
> - // supporting points taking into account the rest which can't
> - // get used for interpolation.
> - int nEval = fullLength / it + fullLength % it;
> - if ( nEval < nEvalMin ) {
> - nEvalMin = nEval;
> - best = it;
> - }
> - }
> - return best;
> -}
> -
> #include "MergedLayerDecorator.moc"
> diff --git a/marble/src/lib/MergedLayerDecorator.h
> b/marble/src/lib/MergedLayerDecorator.h index d3f45f3..af046b3 100644
> --- a/marble/src/lib/MergedLayerDecorator.h
> +++ b/marble/src/lib/MergedLayerDecorator.h
> @@ -16,21 +16,18 @@
> #ifndef MERGED_LAYER_DECORATOR_H
> #define MERGED_LAYER_DECORATOR_H
>
> -#include <QtGui/QImage>
> #include <QtCore/QObject>
>
> #include "TileId.h"
> -#include "global.h"
>
> +class QImage;
> class QString;
> class QUrl;
>
> namespace Marble
> {
> class GeoSceneDocument;
> -class GeoSceneTexture;
> class SunLocator;
> -class StackedTile;
> class StackedTileLoader;
>
> class MergedLayerDecorator : public QObject
> @@ -39,7 +36,6 @@ class MergedLayerDecorator : public QObject
>
> public:
> MergedLayerDecorator( StackedTileLoader * const tileLoader,
> SunLocator* sunLocator ); - virtual ~MergedLayerDecorator();
>
> // The Parameter themeId is only used for displaying the TileId,
> // which is a debugging feature, therefore at this point QString
> remains. @@ -55,24 +51,11 @@ class MergedLayerDecorator : public QObject
> Q_SIGNALS:
> void repaintMap();
>
> - private:
> - StackedTile * loadDataset( GeoSceneTexture *textureLayer );
> - int maxDivisor( int maximum, int fullLength );
> -
> - void initCityLights();
> -
> - void paintSunShading();
> - void paintClouds();
> -
> protected:
> Q_DISABLE_COPY( MergedLayerDecorator )
> - StackedTileLoader * const m_tileLoader;
> QImage* m_tile;
> TileId m_id;
> - SunLocator* m_sunLocator;
> bool m_showTileId;
> - GeoSceneDocument *m_cityLightsTheme;
> - GeoSceneTexture *m_cityLightsTextureLayer;
> };
>
> }
> diff --git a/marble/src/lib/blendings/SunLightBlending.cpp
> b/marble/src/lib/blendings/SunLightBlending.cpp new file mode 100644
> index 0000000..8debf33
> --- /dev/null
> +++ b/marble/src/lib/blendings/SunLightBlending.cpp
> @@ -0,0 +1,207 @@
> +// Copyright 2010 Jens-Michael Hoffmann <jmho at c-xx.com>
> +//
> +// This library is free software; you can redistribute it and/or
> +// modify it under the terms of the GNU Lesser General Public
> +// License as published by the Free Software Foundation; either
> +// version 2.1 of the License, or (at your option) any later version.
> +//
> +// This library is distributed in the hope that it will be useful,
> +// but WITHOUT ANY WARRANTY; without even the implied warranty of
> +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> +// Lesser General Public License for more details.
> +//
> +// You should have received a copy of the GNU Lesser General Public
> +// License along with this library. If not, see
> <http://www.gnu.org/licenses/>. +
> +#include "SunLightBlending.h"
> +
> +#include "ExtDateTime.h"
> +#include "MarbleDebug.h"
> +#include "Planet.h"
> +#include "SunLocator.h"
> +#include "TextureTile.h"
> +#include "global.h"
> +
> +#include <QtGui/QImage>
> +
> +#include <cmath>
> +
> +namespace Marble
> +{
> +
> +SunLightBlending::SunLightBlending()
> + : Blending(),
> + m_sunLocator( new SunLocator( new ExtDateTime, new Planet( "earth"
> ))) +{
> +}
> +
> +SunLightBlending::~SunLightBlending()
> +{
> + delete m_sunLocator;
> +}
> +
> +void SunLightBlending::blend( QImage * const bottom,
> QSharedPointer<TextureTile> const & top ) const +{
> + QImage const * const topImage = top->image();
> + Q_ASSERT( topImage );
> + Q_ASSERT( bottom->size() == topImage->size() );
> + int const tileWidth = bottom->width();
> + int const tileHeight = bottom->height();
> + mDebug() << "SunLightBlending::blend, tile width/height:" << tileWidth
> << tileHeight; +
> + // number of pixels in current zoom level
> + // TODO: fix calculation, take levelZero(Columns|Rows) into account
> + int const globalWidth = tileWidth << top->id().zoomLevel();
> + int const globalHeight = tileHeight << top->id().zoomLevel();
> + mDebug() << "SunLightBlending::blend, global width/height:" <<
> globalWidth << globalHeight; +
> + qreal const lonScale = 2.0 * M_PI / globalWidth;
> + qreal const latScale = -M_PI / globalHeight;
> +
> + m_sunLocator->update();
> + qreal const sunZenithLon = m_sunLocator->getLon() * DEG2RAD;
> + qreal const sunZenithLat = m_sunLocator->getLat() * DEG2RAD;
> + mDebug() << "SunLightBlending::blend, sun zenith lon/lat:" <<
> sunZenithLon << sunZenithLat; +
> + // First we determine the supporting point interval for the
> interpolation. + int const n = maxDivisor( 30, tileWidth );
> + int const ipRight = n * (int)( tileWidth / n );
> +
> + for ( int y = 0; y < tileHeight; ++y ) {
> +
> + qreal const lat = latScale * ( top->id().y() * tileHeight + y ) -
> 0.5 * M_PI; + qreal const a = sin(( lat + sunZenithLat ) / 2.0 );
> + qreal const c = cos( lat ) * cos( -sunZenithLat );
> +
> + QRgb * bottomScanline = (QRgb*) bottom->scanLine( y );
> + QRgb * topScanline = (QRgb*) topImage->scanLine( y );
> +
> + qreal shade = 0.0;
> + qreal lastShade = -10.0;
> +
> + int x = 0;
> + while ( x < tileWidth ) {
> + bool const interpolate = ( x != 0 && x < ipRight && x + n <
> tileWidth ); + if ( interpolate ) {
> + int const check = x + n;
> + qreal const checkLon = lonScale * ( top->id().x() *
> tileWidth + check ); + shade = shading( checkLon -
> sunZenithLon, a, c ); +
> + // if the shading didn't change across the interpolation
> + // interval move on and don't change anything.
> + if ( shade == lastShade && shade == 1.0 ) {
> + bottomScanline += n;
> + topScanline += n;
> + x += n;
> + continue;
> + }
> + if ( shade == lastShade && shade == 0.0 ) {
> + for ( int t = 0; t < n; ++t ) {
> + shadePixelComposite( *bottomScanline,
> *topScanline, shade ); + ++bottomScanline;
> + ++topScanline;
> + }
> + x += n;
> + continue;
> + }
> + for ( int t = 0; t < n ; ++t ) {
> + qreal const lon = lonScale * ( top->id().x() *
> tileWidth + x ); + shade = shading( lon - sunZenithLon,
> a, c );
> + shadePixelComposite( *bottomScanline, *topScanline,
> shade ); + ++bottomScanline;
> + ++topScanline;
> + ++x;
> + }
> + }
> + else {
> + // Make sure we don't exceed the image memory
> + if ( x < tileWidth ) {
> + qreal const lon = lonScale * ( top->id().x() *
> tileWidth + x ); + shade = shading( lon - sunZenithLon,
> a, c );
> + shadePixelComposite( *bottomScanline, *topScanline,
> shade ); + ++bottomScanline;
> + ++topScanline;
> + ++x;
> + }
> + }
> + lastShade = shade;
> + }
> + }
> +}
> +
> +void SunLightBlending::shadePixelComposite( QRgb & bottom, QRgb const top,
> qreal const brightness ) const +{
> + if ( brightness > 0.99999 )
> + // daylight - no change
> + return;
> +
> + if ( brightness < 0.00001 ) {
> + // night
> + bottom = top;
> + }
> + else {
> + // gradual shadowing
> + int const bottomRed = qRed( bottom );
> + int const bootomGreen = qGreen( bottom );
> + int const bottomBlue = qBlue( bottom );
> +
> + int const topRed = qRed( top );
> + int const topGreen = qGreen( top );
> + int const topBlue = qBlue( top );
> +
> + bottom = qRgb( (int)( brightness * bottomRed + ( 1.0 - brightness
> ) * topRed ), + (int)( brightness * bootomGreen + (
> 1.0 - brightness ) * topGreen ), + (int)( brightness
> * bottomBlue + ( 1.0 - brightness ) * topBlue )); + }
> +}
> +
> +// deltaLon = lon - sunLon
> +qreal SunLightBlending::shading( qreal const deltaLon, qreal const a,
> qreal const c ) const +{
> + // haversine formula
> + qreal const b = sin( deltaLon / 2.0 );
> + qreal const h = ( a * a ) + c * ( b * b );
> +
> + /*
> + h = 0.0 // directly beneath sun
> + h = 0.5 // sunrise/sunset line
> + h = 1.0 // opposite side of earth to the sun
> + theta = 2*asin(sqrt(h))
> + */
> +
> + // this equals 18 deg astronomical twilight and is correct for earth
> or venus + qreal const twilightZone = 0.1;
> +
> + qreal brightness;
> + if ( h <= 0.5 - twilightZone / 2.0 )
> + brightness = 1.0;
> + else if ( h >= 0.5 + twilightZone / 2.0 )
> + brightness = 0.0;
> + else
> + brightness = ( 0.5 + twilightZone / 2.0 - h ) / twilightZone;
> +
> + return brightness;
> +}
> +
> +// TODO: This should likely go into a math class in the future ...
> +int SunLightBlending::maxDivisor( int const maximum, int const fullLength
> ) const +{
> + // Find the optimal interpolation interval n for the
> + // current image canvas width
> + int best = 2;
> +
> + int nEvalMin = fullLength;
> + for ( int it = 1; it <= maximum; ++it ) {
> + // The optimum is the interval which results in the least amount
> + // supporting points taking into account the rest which can't
> + // get used for interpolation.
> + int nEval = fullLength / it + fullLength % it;
> + if ( nEval < nEvalMin ) {
> + nEvalMin = nEval;
> + best = it;
> + }
> + }
> + return best;
> +}
> +
> +}
> diff --git a/marble/src/lib/blendings/SunLightBlending.h
> b/marble/src/lib/blendings/SunLightBlending.h new file mode 100644
> index 0000000..47ec8c4
> --- /dev/null
> +++ b/marble/src/lib/blendings/SunLightBlending.h
> @@ -0,0 +1,45 @@
> +// Copyright 2010 Jens-Michael Hoffmann <jmho at c-xx.com>
> +//
> +// This library is free software; you can redistribute it and/or
> +// modify it under the terms of the GNU Lesser General Public
> +// License as published by the Free Software Foundation; either
> +// version 2.1 of the License, or (at your option) any later version.
> +//
> +// This library is distributed in the hope that it will be useful,
> +// but WITHOUT ANY WARRANTY; without even the implied warranty of
> +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> +// Lesser General Public License for more details.
> +//
> +// You should have received a copy of the GNU Lesser General Public
> +// License along with this library. If not, see
> <http://www.gnu.org/licenses/>. +
> +#ifndef MARBLE_SUN_LIGHT_BLENDING_H
> +#define MARBLE_SUN_LIGHT_BLENDING_H
> +
> +#include <QtCore/QtGlobal>
> +#include <QtGui/QColor>
> +
> +#include "Blending.h"
> +
> +namespace Marble
> +{
> +
> +class SunLocator;
> +
> +class SunLightBlending: public Blending
> +{
> + public:
> + SunLightBlending();
> + virtual ~SunLightBlending();
> + virtual void blend( QImage * const bottom, QSharedPointer<TextureTile>
> const & top ) const; +
> + private:
> + void shadePixelComposite( QRgb & bottom, QRgb const top, qreal const
> brightness ) const; + qreal shading( qreal const deltaLon, qreal const
> a, qreal const c ) const; + int maxDivisor( int const maximum, int
> const fullLength ) const; + SunLocator * const m_sunLocator;
> +};
> +
> +}
> +
> +#endif
More information about the Marble-devel
mailing list