diff -r e48454f237ca -r 49c70dcc3f17 ganeswidgets/src/hgvgquadrenderer.cpp --- 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 -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::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(createNativeImage()); - mDefaultVgImage->setImage(defaultImage); - mDefaultVgImage->upload(true); - } - */ + return mDefaultVgImage; } @@ -477,27 +231,23 @@ mDefaultVgImage->upload(true); } -HgImageFader* HgVgQuadRenderer::imageFader() -{ - return mImageFader; -} - -QList 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 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; } - -