Hillshaderenderer: Fix transparency effects (#3185)

This commit is contained in:
Asger Skovbo Petersen 2016-06-08 13:30:00 +02:00 committed by Nathan Woodrow
parent 2265115f80
commit 85fbeb26f8

View File

@ -18,7 +18,7 @@
#include <QColor>
#include "qgshillshaderenderer.h"
#include "qgsrastertransparency.h"
#include "qgsrasterinterface.h"
#include "qgsrasterblock.h"
#include "qgsrectangle.h"
@ -40,6 +40,10 @@ QgsHillshadeRenderer *QgsHillshadeRenderer::clone() const
QgsHillshadeRenderer* r = new QgsHillshadeRenderer( nullptr, mBand, mLightAzimuth, mLightAngle );
r->setZFactor( mZFactor );
r->setMultiDirectional( mMultiDirectional );
// "Effects"
r->setOpacity( mOpacity );
r->setAlphaBand( mAlphaBand );
r->setRasterTransparency( mRasterTransparency ? new QgsRasterTransparency( *mRasterTransparency ) : nullptr );
return r;
}
@ -98,12 +102,34 @@ QgsRasterBlock *QgsHillshadeRenderer::block( int bandNo, const QgsRectangle &ext
return outputBlock;
}
QgsRasterBlock *alphaBlock = nullptr;
if ( mAlphaBand > 0 && mBand != mAlphaBand )
{
alphaBlock = mInput->block( mAlphaBand, extent, width, height );
if ( !alphaBlock || alphaBlock->isEmpty() )
{
// TODO: better to render without alpha
delete inputBlock;
delete alphaBlock;
return outputBlock;
}
}
else if ( mAlphaBand > 0 )
{
alphaBlock = inputBlock;
}
if ( !outputBlock->reset( QGis::ARGB32_Premultiplied, width, height ) )
{
delete inputBlock;
delete alphaBlock;
return outputBlock;
}
double cellXSize = extent.width() / double( width );
double cellYSize = extent.height() / double( height );
double zenithRad = qMax( 0.0, 90 - mLightAngle ) * M_PI / 180.0;
@ -224,9 +250,33 @@ QgsRasterBlock *QgsHillshadeRenderer::block( int bandNo, const QgsRectangle &ext
double color3 = cosSlope + sinSlope * cos( angle3Rad - aspectRad ) ;
grayValue = qBound( 0.0, 255 * ( weight0 * color0 + weight1 * color1 + weight2 * color2 + weight3 * color3 ) * 0.5, 255.0 );
}
outputBlock->setColor( i, j, qRgb( grayValue, grayValue, grayValue ) );
double currentAlpha = mOpacity;
if ( mRasterTransparency )
{
currentAlpha = mRasterTransparency->alphaValue( x22, mOpacity * 255 ) / 255.0;
}
if ( mAlphaBand > 0 )
{
currentAlpha *= alphaBlock->value( i ) / 255.0;
}
if ( qgsDoubleNear( currentAlpha, 1.0 ) )
{
outputBlock->setColor( i, j, qRgba( grayValue, grayValue, grayValue, 255 ) );
}
else
{
outputBlock->setColor( i, j, qRgba( currentAlpha * grayValue, currentAlpha * grayValue, currentAlpha * grayValue, currentAlpha * 255 ) );
}
}
}
delete inputBlock;
if ( mAlphaBand > 0 && mBand != mAlphaBand )
{
delete alphaBlock;
}
return outputBlock;
}