--- a/ganeswidgets/src/hgvgquadrenderer.cpp Mon May 03 13:32:54 2010 +0300
+++ b/ganeswidgets/src/hgvgquadrenderer.cpp Fri May 14 16:57:01 2010 +0300
@@ -16,6 +16,7 @@
*/
#include "hgvgquadrenderer.h"
+#include "hgtransformedquad.h"
#include "hgquad.h"
#include "hgvgimage.h"
#include "trace.h"
@@ -29,231 +30,46 @@
#include <qpainter>
-class HgVgQuad
-{
-public:
- HgVgQuad(HgVgQuadRenderer* renderer);
- ~HgVgQuad();
-
- int index() const;
- bool isPointInside(const QPointF& point) const;
- void transformQuad(int index, const QMatrix4x4& matrix, HgQuad* quad,
- const QRectF& rect, qreal mirroringPlaneY, const QVector2D& translate);
- void draw();
-
- void getTransformedPoints(QPolygonF& polygon) const;
-
- void computeMirrorMatrix(const QMatrix4x4& tm, const QMatrix4x4& projView,
- const QRectF& rect, qreal mirroringPlaneY,
- const QVector2D& translate);
-
- bool perspectiveTransformPoints(QVector2D* points, const QMatrix4x4& matrix,
- const QRectF& rect);
-
- void computeWarpMatrix(VGfloat* matrix, int pxWidth, int pxHeight, const QVector2D* points,
- const QVector2D& translate);
-
- void drawImage(HgVgImage* image, qreal alpha);
-
- int mIndex;
- HgQuad* mQuad;
- QVector2D mTransformedPoints[4];
- VGfloat mMatrix[9];
- VGfloat mMirrorMatrix[9];
- HgVgQuadRenderer* mRenderer;
- bool mDegenerate;
-private:
- HgVgQuad(const HgVgQuad&);
- HgVgQuad& operator=(const HgVgQuad&);
-};
-
-static bool quadSorter(HgVgQuad* a, HgVgQuad* b)
-{
- return a->mQuad->position().z() < b->mQuad->position().z();
-}
-
-HgVgQuad::HgVgQuad(HgVgQuadRenderer* renderer) : mRenderer(renderer)
-{
-
-}
-
-HgVgQuad::~HgVgQuad()
+static void matrixFromTransform(VGfloat* matrix, const QTransform& tm)
{
-
-}
-
-int HgVgQuad::index() const
- {
- return mIndex;
- }
-
-bool HgVgQuad::isPointInside(const QPointF& point) const
-{
- QPolygonF poly;
- getTransformedPoints(poly);
- QRectF rect = poly.boundingRect();
- if (rect.contains(point))
- {
- return true;
- }
- return false;
-}
-
-
-void HgVgQuad::computeMirrorMatrix(const QMatrix4x4& trans, const QMatrix4x4& projView,
- const QRectF& rect, qreal mirroringPlaneY, const QVector2D& translate)
-{
- HgQuad* quad = mQuad;
+ matrix[0] = tm.m11();
+ matrix[1] = tm.m12();
+ matrix[2] = tm.m13();
- QMatrix4x4 mirror = trans;
+ matrix[3] = tm.m21();
+ matrix[4] = tm.m22();
+ matrix[5] = tm.m23();
- qreal distToPlane = qAbs(quad->position().y() - mirroringPlaneY);
-
- mirror.translate(quad->position().x(), mirroringPlaneY - distToPlane/2, quad->position().z());
- mirror.scale(quad->scale().x(), -quad->scale().y()/2);
- mirror.rotate(quad->rotation());
-
- QMatrix4x4 modelViewProjMatrix = projView * mirror;
-
- QVector2D temp[4];
-
- perspectiveTransformPoints(temp, modelViewProjMatrix, rect);
-
- HgVgImage* image = (HgVgImage*)mQuad->image();
-
- if (image == NULL)
- {
- image = mRenderer->defaultImage();
- if (!image) {
- return;
- }
- }
-
- int pxWidth = image->mirrorImageWidth();
- int pxHeight = image->mirrorImageHeight();
-
- computeWarpMatrix(mMirrorMatrix, pxWidth, pxHeight, temp, translate);
+ matrix[6] = tm.m31();
+ matrix[7] = tm.m32();
+ matrix[8] = tm.m33();
}
-void HgVgQuad::transformQuad(int index, const QMatrix4x4& projView, HgQuad* quad,
- const QRectF& rect, qreal mirroringPlaneY, const QVector2D& translate)
+class HgVgQuad : public HgTransformedQuad
{
- mIndex = index;
- mQuad = quad;
-
- QMatrix4x4 tm;
- tm.setToIdentity();
- tm.rotate(quad->outerRotation());
-
- if (mQuad->mirrorImageEnabled())
+public:
+
+ HgVgQuad(HgVgQuadRenderer* renderer) : HgTransformedQuad(-1), mRenderer(renderer)
{
- computeMirrorMatrix(tm, projView, rect, mirroringPlaneY, translate);
- }
-
- tm.translate(quad->position());
- tm.rotate(quad->rotation());
- tm.scale(quad->scale().x(), quad->scale().y());
-
- tm = projView * tm;
- //QMatrix4x4 tmt = tm.transposed();
-
- mDegenerate = false;
- if (!perspectiveTransformPoints(mTransformedPoints, tm, rect))
- {
- mDegenerate = true;
+
}
- HgVgImage* image = (HgVgImage*)mQuad->image();
-
- if (image == NULL)
+ ~HgVgQuad()
{
- image = mRenderer->defaultImage();
- if (!image)
- return;
- }
-
- int pxWidth = image->width();
- int pxHeight = image->height();
-
-
- computeWarpMatrix(mMatrix, pxWidth, pxHeight, mTransformedPoints, translate);
-
- for (int i = 0; i < 4; i++)
- mTransformedPoints[i] += translate;
-
-}
-
-bool HgVgQuad::perspectiveTransformPoints(QVector2D* outPoints, const QMatrix4x4& matrix,
- const QRectF& rect)
-{
- const QVector4D points[] =
- {
- QVector4D(-0.5f, -0.5f, 0.0f, 1.0f),
- QVector4D( 0.5f, -0.5f, 0.0f, 1.0f),
- QVector4D( 0.5f, 0.5f, 0.0f, 1.0f),
- QVector4D(-0.5f, 0.5f, 0.0f, 1.0f)
- };
-
- qreal hw = rect.width() * 0.5f;
- qreal hh = rect.height() * 0.5f;
-
- for (int i = 0; i < 4; i++)
- {
- QVector4D temp = matrix * points[i];
-
- outPoints[i] = QVector2D(
- hw + temp.x() / temp.w() * hw,
- hh + temp.y() / temp.w() * hh);
-
+
}
-
- return true;
-}
-void HgVgQuad::computeWarpMatrix(VGfloat* matrix, int pxWidth, int pxHeight, const QVector2D* points,
- const QVector2D& translate)
-{
-
- vguComputeWarpQuadToQuad(
- points[0].x() + translate.x(), points[0].y() + translate.y(),
- points[1].x() + translate.x(), points[1].y() + translate.y(),
- points[2].x() + translate.x(), points[2].y() + translate.y(),
- points[3].x() + translate.x(), points[3].y() + translate.y(),
- 0, pxHeight,
- pxWidth, pxHeight,
- pxWidth, 0,
- 0, 0,
- matrix);
-/*
- INFO("P0 x:" << points[0].x() << " y:" << points[0].y());
- INFO("P1 x:" << points[1].x() << " y:" << points[1].y());
- INFO("P2 x:" << points[2].x() << " y:" << points[2].y());
- INFO("P3 x:" << points[3].x() << " y:" << points[3].y());*/
-}
-
-
-void HgVgQuad::draw()
-{
- if (!mQuad->visible())
- return;
-
- if (mDegenerate)
- return;
-
- HgVgImage* image = (HgVgImage*)mQuad->image();
-
-
- if (image == NULL || image->alpha() == 0)
+ void draw(QPainter* painter, const QRectF& rect)
{
- if (mRenderer->defaultImage()) {
- drawImage(mRenderer->defaultImage(), 1.0f);
- }
- }
- else
- {
- image->upload(mQuad->mirrorImageEnabled());
+ Q_UNUSED(painter)
+ Q_UNUSED(rect)
- if (image->image() == VG_INVALID_HANDLE)
+ if (!mQuad->visible())
+ return;
+
+ HgVgImage* image = (HgVgImage*)mQuad->image();
+
+ if (image == NULL || image->alpha() == 0)
{
if (mRenderer->defaultImage()) {
drawImage(mRenderer->defaultImage(), 1.0f);
@@ -261,75 +77,94 @@
}
else
{
-
- if ( mQuad->alpha() < 1.0f )
+ image->upload(mQuad->mirrorImageEnabled());
+
+ if (image->image() == VG_INVALID_HANDLE)
{
if (mRenderer->defaultImage()) {
- drawImage(mRenderer->defaultImage(), 1.0f - mQuad->alpha());
+ drawImage(mRenderer->defaultImage(), 1.0f);
}
}
+ else
+ {
+
+ if ( mQuad->alpha() < 1.0f )
+ {
+ if (mRenderer->defaultImage()) {
+ drawImage(mRenderer->defaultImage(), 1.0f - mQuad->alpha());
+ }
+ }
+
+ drawImage(image, mQuad->alpha());
+ }
+ }
+
+
+ }
+
+ void drawImage(HgVgImage* image, qreal alpha)
+ {
+ Q_UNUSED(alpha)
- drawImage(image, mQuad->alpha());
+ VGImage vgImage = image->image();
+
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+
+ VGfloat m[9];
+ vgGetMatrix(m);
+
+ computeWarpMatrix(mMatrix, image->width(), image->height(), mTransformedPoints, QVector2D());
+
+ vgMultMatrix(mMatrix);
+ vgDrawImage(vgImage);
+
+ vgLoadMatrix(m);
+
+ if (mQuad->mirrorImageEnabled())
+ {
+ VGImage mirrorImage = image->mirrorImage();
+ if (mirrorImage == VG_INVALID_HANDLE)
+ return;
+
+ computeWarpMatrix(mMirrorMatrix, image->mirrorImageWidth(), image->mirrorImageHeight(), mMirroredPoints, QVector2D());
+ vgMultMatrix(mMirrorMatrix);
+
+ vgDrawImage(mirrorImage);
+ vgLoadMatrix(m);
}
+
}
-
-}
+private:
-void HgVgQuad::drawImage(HgVgImage* image, qreal alpha)
-{
- Q_UNUSED(alpha)
+ void computeWarpMatrix(VGfloat* matrix, int pxWidth, int pxHeight, const QVector2D* points,
+ const QVector2D& translate)
+ {
- //VGfloat values[] = { 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0 };
- //values[3] = alpha;
-
- //vgSetfv(VG_COLOR_TRANSFORM_VALUES, 8, values);
-
- VGImage vgImage = image->image();
-
- vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
-
- VGfloat m[9];
- vgGetMatrix(m);
-
- vgMultMatrix(mMatrix);
- vgDrawImage(vgImage);
+ vguComputeWarpQuadToQuad(
+ points[0].x(), points[0].y(),
+ points[1].x(), points[1].y(),
+ points[2].x(), points[2].y(),
+ points[3].x(), points[3].y(),
+ 0, pxHeight,
+ pxWidth, pxHeight,
+ pxWidth, 0,
+ 0, 0,
+ matrix);
- vgLoadMatrix(m);
+ }
- if (mQuad->mirrorImageEnabled())
- {
- VGImage mirrorImage = image->mirrorImage();
- if (mirrorImage == VG_INVALID_HANDLE)
- return;
-
- vgMultMatrix(mMirrorMatrix);
-
- vgDrawImage(mirrorImage);
- vgLoadMatrix(m);
- }
-
-}
-
-
-void HgVgQuad::getTransformedPoints(QPolygonF& poly) const
-{
- poly.append(mTransformedPoints[0].toPointF());
- poly.append(mTransformedPoints[1].toPointF());
- poly.append(mTransformedPoints[2].toPointF());
- poly.append(mTransformedPoints[3].toPointF());
-}
+ HgVgQuadRenderer* mRenderer;
+ VGfloat mMatrix[9];
+ VGfloat mMirrorMatrix[9];
+};
HgVgQuadRenderer::HgVgQuadRenderer(int maxQuads) :
- HgQuadRenderer(maxQuads),
+ HgTransformedQuadRenderer(maxQuads),
mDefaultVgImage(NULL)
{
- for (int i = 0; i < maxQuads; i++)
- {
- mTransformedQuads.append(new HgVgQuad(this));
- }
- mImageFader = new HgImageFader();
+ init(maxQuads);
}
HgVgQuadRenderer::~HgVgQuadRenderer()
@@ -337,133 +172,52 @@
delete mDefaultVgImage;
}
-HgQuad* HgVgQuadRenderer::getQuadAt(const QPointF& point) const
-{
- FUNC_LOG
-
- // TODO: need to use sorted quads here, in reversed order.
- QList<HgVgQuad*>::const_iterator i = mSortedQuads.begin();
- while(i != mSortedQuads.end())
- {
- HgVgQuad* q = (*i);
- if (q->isPointInside(point))
- {
- return q->mQuad;
- }
- i++;
- }
-
- return NULL;
-}
-
-
-void HgVgQuadRenderer::transformQuads(const QMatrix4x4& view, const QMatrix4x4& proj,
- const QRectF& rect)
+void HgVgQuadRenderer::drawQuads(QPainter* painter, const QRectF& rect,
+ const QMatrix4x4& viewMatrix, const QMatrix4x4& projectionMatrix,
+ Qt::Orientation orientation,
+ const QTransform& sceneTransform)
{
- QMatrix4x4 pv = proj * view;
-
- mSortedQuads.clear();
-
- for (int i = 0; i < mQuads.size(); i++)
- {
- HgQuad* q = mQuads[i];
-
- HgVgQuad* tq = mTransformedQuads[i];
-
- if (q->visible())
- {
- tq->transformQuad(i, pv, q, rect, mMirroringPlaneY, mTranslation);
- mSortedQuads.append(tq);
- }
- }
-
- qSort(mSortedQuads.begin(), mSortedQuads.end(), quadSorter);
-}
-
-void HgVgQuadRenderer::drawQuads(const QRectF& rect, QPainter* painter)
-{
- Q_UNUSED(rect)
-
-
+ // start direct vg
painter->beginNativePainting();
- // need to save old scissoring rects, otherwise hb
- // screws up with rendering
-/* VGint oldScissoring = vgGeti(VG_SCISSORING);
- VGint numRects = 32;//vgGeti(VG_MAX_SCISSOR_RECTS);
- VGint oldRects[32*4];
- vgGetiv(VG_SCISSOR_RECTS, numRects, oldRects);
-
- // setup our new scissoring rects
- VGint sRect[4];
- sRect[0] = rect.left();
- sRect[1] = rect.top();
- sRect[2] = rect.width();
- sRect[3] = rect.height();
- vgSeti(VG_SCISSORING, VG_TRUE);
- vgSetiv(VG_SCISSOR_RECTS, 4, sRect);
- */
- // setup root transform
- vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
- vgLoadIdentity();
- vgTranslate(rect.left(), rect.top());
-
+ // setup default vg states
vgSeti(VG_COLOR_TRANSFORM, VG_FALSE);
vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER);
vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL);
-
- // draw quads
- for (int i = 0; i < mSortedQuads.size(); i++)
- {
- mSortedQuads[i]->draw();
- }
-
- // set back old scissor rects
- // vgSeti(VG_SCISSORING, oldScissoring);
- // vgSetiv(VG_SCISSOR_RECTS, numRects, oldRects);
+
+ // setup root transform
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+ VGfloat toVgMatrix[9];
+ matrixFromTransform(toVgMatrix, qtToVgTransform(painter, sceneTransform, rect, orientation));
+ vgLoadMatrix(toVgMatrix);
+ // transform quads to screen
+ transformQuads(viewMatrix, projectionMatrix, QPointF(rect.width()/2, rect.height()/2),
+ QSizeF(rect.width(), rect.height()));
+
+ drawTransformedQuads(painter, rect);
+
+ // end directt vg
painter->endNativePainting();
}
-bool HgVgQuadRenderer::getQuadTranformedPoints(QPolygonF& points, int index) const
-{
- for (int i = 0; i < mSortedQuads.count(); i++)
- {
- HgVgQuad* quad = mSortedQuads[i];
- if (quad->mQuad)
- {
- bool bOk;
- if (quad->mQuad->userData().toInt(&bOk) == index)
- {
- quad->getTransformedPoints(points);
- return true;
- }
- }
- }
-
- return false;
-}
-
HgImage* HgVgQuadRenderer::createNativeImage()
{
return new HgVgImage(this);
}
+HgTransformedQuad* HgVgQuadRenderer::createNativeQuad()
+{
+ return new HgVgQuad(this);
+}
+
HgVgImage* HgVgQuadRenderer::defaultImage()
{
if (mDefaultVgImage && mDefaultVgImage->image() == VG_INVALID_HANDLE) {
mDefaultVgImage->upload(true);
}
-/* if (mDefaultVgImage == NULL)
- {
- QImage defaultImage(64,64,QImage::Format_RGB16);
- defaultImage.fill(qRgb(255,0,0));
- mDefaultVgImage = static_cast<HgVgImage*>(createNativeImage());
- mDefaultVgImage->setImage(defaultImage);
- mDefaultVgImage->upload(true);
- }
- */
+
return mDefaultVgImage;
}
@@ -477,27 +231,23 @@
mDefaultVgImage->upload(true);
}
-HgImageFader* HgVgQuadRenderer::imageFader()
-{
- return mImageFader;
-}
-
-QList<HgQuad*> HgVgQuadRenderer::getVisibleQuads(const QRectF& rect) const
+QTransform HgVgQuadRenderer::qtToVgTransform(QPainter* painter, const QTransform& sceneTransform,
+ const QRectF& rect, Qt::Orientation orientation) const
{
- FUNC_LOG;
-
- // this implementation isn't 100% precise
- QList<HgQuad*> result;
- for (int i = 0; i < mSortedQuads.count(); i++) {
- QPolygonF poly;
- mSortedQuads[i]->getTransformedPoints(poly);
- QRectF bounds = poly.boundingRect();
- if (bounds.intersects(rect) || rect.contains(bounds)) {
- result.append(mSortedQuads[i]->mQuad);
- }
+ QTransform t;
+ if (orientation == Qt::Vertical)
+ {
+ t.translate(sceneTransform.dx(), painter->viewport().height() - sceneTransform.dy());
+ t.scale(1, -1);
}
-
- return result;
+ else
+ {
+ // TODO: this will need reviewing later :)
+ t.translate(rect.bottom(), 0);
+ t.scale(-1, 1);
+ t.translate(0, rect.right());
+ t.rotate(-90, Qt::ZAxis);
+ }
+
+ return t;
}
-
-