5#include "SunLightBlending.h"
7#include "MarbleDebug.h"
8#include "MarbleGlobal.h"
10#include "TextureTile.h"
11#include "TileLoaderHelper.h"
21SunLightBlending::SunLightBlending(
const SunLocator *sunLocator)
23 , m_sunLocator(sunLocator)
24 , m_levelZeroColumns(0)
29SunLightBlending::~SunLightBlending() =
default;
31void SunLightBlending::blend(
QImage *
const tileImage, TextureTile
const *
const top)
const
33 if (tileImage->
depth() != 32)
38 const TileId
id = top->id();
39 const qreal global_width = tileImage->
width() * TileLoaderHelper::levelToColumn(m_levelZeroColumns,
id.zoomLevel());
40 const qreal global_height = tileImage->
height() * TileLoaderHelper::levelToRow(m_levelZeroRows,
id.zoomLevel());
41 const qreal lon_scale = 2 * M_PI / global_width;
42 const qreal lat_scale = -M_PI / global_height;
43 const int tileHeight = tileImage->
height();
44 const int tileWidth = tileImage->
width();
47 const int n = maxDivisor(30, tileWidth);
48 const int ipRight = n * (int)(tileWidth / n);
50 const QImage *nighttile = top->image();
52 for (
int cur_y = 0; cur_y < tileHeight; ++cur_y) {
53 const qreal lat = lat_scale * (
id.y() * tileHeight + cur_y) - 0.5 * M_PI;
54 const qreal a = sin((lat + DEG2RAD * m_sunLocator->getLat()) / 2.0);
55 const qreal c = cos(lat) * cos(-DEG2RAD * m_sunLocator->getLat());
57 QRgb *scanline = (QRgb *)tileImage->
scanLine(cur_y);
58 const QRgb *nscanline = (QRgb *)nighttile->
scanLine(cur_y);
60 qreal lastShade = -10.0;
64 while (cur_x < tileWidth) {
65 const bool interpolate = (cur_x != 0 && cur_x < ipRight && cur_x + n < tileWidth);
70 const int check = cur_x + n;
71 const qreal checklon = lon_scale * (
id.x() * tileWidth + check);
72 shade = m_sunLocator->shading(checklon, a, c);
76 if (shade == lastShade && shade == 1.0) {
82 if (shade == lastShade && shade == 0.0) {
83 for (
int t = 0; t < n; ++t) {
84 SunLocator::shadePixelComposite(*scanline, *nscanline, shade);
92 qreal lon = lon_scale * (
id.x() * tileWidth + cur_x);
93 for (
int t = 0; t < n; ++t) {
94 shade = m_sunLocator->shading(lon, a, c);
95 SunLocator::shadePixelComposite(*scanline, *nscanline, shade);
105 if (cur_x < tileWidth) {
106 qreal lon = lon_scale * (
id.x() * tileWidth + cur_x);
107 shade = m_sunLocator->shading(lon, a, c);
108 SunLocator::shadePixelComposite(*scanline, *nscanline, shade);
119void SunLightBlending::setLevelZeroLayout(
int levelZeroColumns,
int levelZeroRows)
121 m_levelZeroColumns = levelZeroColumns;
122 m_levelZeroRows = levelZeroRows;
126int SunLightBlending::maxDivisor(
int maximum,
int fullLength)
132 int nEvalMin = fullLength;
133 for (
int it = 1; it <= maximum; ++it) {
137 int nEval = fullLength / it + fullLength % it;
138 if (nEval < nEvalMin) {
KGUIADDONS_EXPORT QColor shade(const QColor &, qreal lumaAmount, qreal chromaAmount=0.0)
Binds a QML item to a specific geodetic location in screen coordinates.