fix NPOT shadows

a) fixes the texture offset calculation
b) arranges he shadow pixmaps as border in the texture to avoid interpolation issues.

BUG: 280116
BUG: 282882
CCBUG: 291161
BUG: 293325
REVIEW: 103888
icc-effect-5.14.5
Thomas Lübking 2012-02-08 19:31:17 +01:00
parent 033ae96f89
commit 7d8ab4c593
1 changed files with 33 additions and 53 deletions

View File

@ -1586,18 +1586,11 @@ void SceneOpenGLShadow::buildQuads()
return;
}
const QRectF outerRect(QPointF(-leftOffset(), -topOffset()), QPointF(topLevel()->width() + rightOffset(), topLevel()->height() + bottomOffset()));
const QRectF outerRect(QPointF(-leftOffset(), -topOffset()),
QPointF(topLevel()->width() + rightOffset(), topLevel()->height() + bottomOffset()));
// calculate the width
const qreal cornerWidth = topLeft.width() + topRight.width() + bottomLeft.width() + bottomRight.width();
const qreal leftRightWidth = left.width() + right.width();
const qreal topBottomWidth = top.width() + bottom.width();
// calculate the height
const qreal cornerHeight = qMax<int>(topLeft.height(), qMax<int>(topRight.height(), qMax<int>(bottomLeft.height(), bottomRight.height())));
const qreal leftRightHeight = qMax<int>(left.height(), right.height());
const qreal width = m_texture->width();
const qreal height = m_texture->height();
const qreal width = topLeft.width() + top.width() + topRight.width();
const qreal height = topLeft.height() + left.height() + bottomLeft.height();
qreal tx1(0.0), tx2(0.0), ty1(0.0), ty2(0.0);
@ -1610,9 +1603,9 @@ void SceneOpenGLShadow::buildQuads()
topLeftQuad[ 3 ] = WindowVertex(outerRect.x(), outerRect.y() + topLeft.height(), tx1, ty2);
m_shadowQuads.append(topLeftQuad);
tx2 = top.width()/width;
ty1 = (cornerHeight + leftRightHeight)/height;
ty2 = (cornerHeight + leftRightHeight + top.height())/height;
tx1 = tx2;
tx2 = (topLeft.width() + top.width())/width;
ty2 = top.height()/height;
WindowQuad topQuad(WindowQuadShadowTop);
topQuad[ 0 ] = WindowVertex(outerRect.x() + topLeft.width(), outerRect.y(), tx1, ty1);
topQuad[ 1 ] = WindowVertex(outerRect.right() - topRight.width(), outerRect.y(), tx2, ty1);
@ -1620,9 +1613,8 @@ void SceneOpenGLShadow::buildQuads()
topQuad[ 3 ] = WindowVertex(outerRect.x() + topLeft.width(), outerRect.y() + top.height(), tx1, ty2);
m_shadowQuads.append(topQuad);
tx1 = topLeft.width()/width;
tx2 = (topLeft.width() + topRight.width())/width;
ty1 = 0.0;
tx1 = tx2;
tx2 = 1.0;
ty2 = topRight.height()/height;
WindowQuad topRightQuad(WindowQuadShadowTopRight);
topRightQuad[ 0 ] = WindowVertex(outerRect.right() - topRight.width(), outerRect.y(), tx1, ty1);
@ -1631,10 +1623,9 @@ void SceneOpenGLShadow::buildQuads()
topRightQuad[ 3 ] = WindowVertex(outerRect.right() - topRight.width(), outerRect.y() + topRight.height(), tx1, ty2);
m_shadowQuads.append(topRightQuad);
tx1 = left.width()/width;
tx2 = leftRightWidth/width;
ty1 = cornerHeight/height;
ty2 = (cornerHeight+right.height())/height;
tx1 = (width - right.width())/width;
ty1 = topRight.height()/height;
ty2 = (topRight.height() + right.height())/height;
WindowQuad rightQuad(WindowQuadShadowRight);
rightQuad[ 0 ] = WindowVertex(outerRect.right() - right.width(), outerRect.y() + topRight.height(), tx1, ty1);
rightQuad[ 1 ] = WindowVertex(outerRect.right(), outerRect.y() + topRight.height(), tx2, ty1);
@ -1642,10 +1633,9 @@ void SceneOpenGLShadow::buildQuads()
rightQuad[ 3 ] = WindowVertex(outerRect.right() - right.width(), outerRect.bottom() - bottomRight.height(), tx1, ty2);
m_shadowQuads.append(rightQuad);
tx1 = (topLeft.width() + topRight.width() + bottomLeft.width())/width;
tx2 = cornerWidth/width;
ty1 = 0.0;
ty2 = bottomRight.height()/height;
tx1 = (width - bottomRight.width())/width;
ty1 = ty2;
ty2 = 1.0;
WindowQuad bottomRightQuad(WindowQuadShadowBottomRight);
bottomRightQuad[ 0 ] = WindowVertex(outerRect.right() - bottomRight.width(), outerRect.bottom() - bottomRight.height(), tx1, ty1);
bottomRightQuad[ 1 ] = WindowVertex(outerRect.right(), outerRect.bottom() - bottomRight.height(), tx2, ty1);
@ -1653,10 +1643,9 @@ void SceneOpenGLShadow::buildQuads()
bottomRightQuad[ 3 ] = WindowVertex(outerRect.right() - bottomRight.width(), outerRect.bottom(), tx1, ty2);
m_shadowQuads.append(bottomRightQuad);
tx1 = top.width()/width;
tx2 = topBottomWidth/width;
ty1 = (cornerHeight + leftRightHeight)/height;
ty2 = (cornerHeight + leftRightHeight + bottom.height())/height;
tx2 = tx1;
tx1 = bottomLeft.width()/width;
ty1 = (height - bottom.height())/height;
WindowQuad bottomQuad(WindowQuadShadowBottom);
bottomQuad[ 0 ] = WindowVertex(outerRect.x() + bottomLeft.width(), outerRect.bottom() - bottom.height(), tx1, ty1);
bottomQuad[ 1 ] = WindowVertex(outerRect.right() - bottomRight.width(), outerRect.bottom() - bottom.height(), tx2, ty1);
@ -1664,10 +1653,9 @@ void SceneOpenGLShadow::buildQuads()
bottomQuad[ 3 ] = WindowVertex(outerRect.x() + bottomLeft.width(), outerRect.bottom(), tx1, ty2);
m_shadowQuads.append(bottomQuad);
tx1 = (topLeft.width() + topRight.width())/width;
tx2 = (topLeft.width() + topRight.width() + bottomLeft.width())/width;
ty1 = 0.0;
ty2 = bottomLeft.height()/height;
tx1 = 0.0;
tx2 = bottomLeft.width()/width;
ty1 = (height - bottomLeft.height())/height;
WindowQuad bottomLeftQuad(WindowQuadShadowBottomLeft);
bottomLeftQuad[ 0 ] = WindowVertex(outerRect.x(), outerRect.bottom() - bottomLeft.height(), tx1, ty1);
bottomLeftQuad[ 1 ] = WindowVertex(outerRect.x() + bottomLeft.width(), outerRect.bottom() - bottomLeft.height(), tx2, ty1);
@ -1675,10 +1663,9 @@ void SceneOpenGLShadow::buildQuads()
bottomLeftQuad[ 3 ] = WindowVertex(outerRect.x(), outerRect.bottom(), tx1, ty2);
m_shadowQuads.append(bottomLeftQuad);
tx1 = 0.0;
tx2 = left.width()/width;
ty1 = cornerHeight/height;
ty2 = (cornerHeight+left.height())/height;
ty2 = ty1;
ty1 = topLeft.height()/height;
WindowQuad leftQuad(WindowQuadShadowLeft);
leftQuad[ 0 ] = WindowVertex(outerRect.x(), outerRect.y() + topLeft.height(), tx1, ty1);
leftQuad[ 1 ] = WindowVertex(outerRect.x() + left.width(), outerRect.y() + topLeft.height(), tx2, ty1);
@ -1697,29 +1684,22 @@ bool SceneOpenGLShadow::prepareBackend()
const QSize bottomLeft(shadowPixmap(ShadowElementBottomLeft).size());
const QSize left(shadowPixmap(ShadowElementLeft).size());
const QSize topLeft(shadowPixmap(ShadowElementTopLeft).size());
// calculate the width
const int cornerWidth = topLeft.width() + topRight.width() + bottomLeft.width() + bottomRight.width();
const int leftRightWidth = left.width() + right.width();
const int topBottomWidth = top.width() + bottom.width();
const int width = qMax<int>(cornerWidth, qMax<int>(leftRightWidth, topBottomWidth));
// calculate the height
const int cornerHeight = qMax<int>(topLeft.height(), qMax<int>(topRight.height(), qMax<int>(bottomLeft.height(), bottomRight.height())));
const int leftRightHeight = qMax<int>(left.height(), right.height());
const int topBottomHeight = qMax<int>(top.height(), bottom.height());
const int height = cornerHeight + leftRightHeight + topBottomHeight;
const int width = topLeft.width() + top.width() + topRight.width();
const int height = topLeft.height() + left.height() + bottomLeft.height();
QImage image(width, height, QImage::Format_ARGB32);
image.fill(Qt::transparent);
QPainter p;
p.begin(&image);
p.drawPixmap(0, 0, shadowPixmap(ShadowElementTopLeft));
p.drawPixmap(topLeft.width(), 0, shadowPixmap(ShadowElementTopRight));
p.drawPixmap(topLeft.width() + topRight.width(), 0, shadowPixmap(ShadowElementBottomLeft));
p.drawPixmap(topLeft.width() + topRight.width() + bottomLeft.width(), 0, shadowPixmap(ShadowElementBottomRight));
p.drawPixmap(0, cornerHeight, shadowPixmap(ShadowElementLeft));
p.drawPixmap(left.width(), cornerHeight, shadowPixmap(ShadowElementRight));
p.drawPixmap(0, cornerHeight + leftRightHeight, shadowPixmap(ShadowElementTop));
p.drawPixmap(top.width(), cornerHeight + leftRightHeight, shadowPixmap(ShadowElementBottom));
p.drawPixmap(topLeft.width(), 0, shadowPixmap(ShadowElementTop));
p.drawPixmap(topLeft.width() + top.width(), 0, shadowPixmap(ShadowElementTopRight));
p.drawPixmap(0, topLeft.height(), shadowPixmap(ShadowElementLeft));
p.drawPixmap(width - right.width(), topRight.height(), shadowPixmap(ShadowElementRight));
p.drawPixmap(0, topLeft.height() + left.height(), shadowPixmap(ShadowElementBottomLeft));
p.drawPixmap(bottomLeft.width(), height - bottom.height(), shadowPixmap(ShadowElementBottom));
p.drawPixmap(bottomLeft.width() + bottom.width(), topRight.height() + right.height(), shadowPixmap(ShadowElementBottomRight));
p.end();
delete m_texture;