Commit eb8dc0938cc7928869bdba20121664861469b18a
- Diff rendering mode:
- inline
- side by side
threed/painting/qglpainter.cpp
(181 / 15)
|   | |||
| 571 | 571 | Returns the viewport for the active GL context. The origin for | |
| 572 | 572 | the returned rectangle is the top-left of the drawing surface. | |
| 573 | 573 | ||
| 574 | \sa setViewport() | ||
| 574 | \sa setViewport(), resetViewport() | ||
| 575 | 575 | */ | |
| 576 | 576 | QRect QGLPainter::viewport() const | |
| 577 | 577 | { | |
| 578 | 578 | Q_D(QGLPainter); | |
| 579 | 579 | QGLPAINTER_CHECK_PRIVATE_RETURN(QRect()); | |
| 580 | QPaintDevice *device = d->context->device(); | ||
| 581 | if (device) { | ||
| 580 | if (d->viewport.isNull()) { | ||
| 582 | 581 | GLint view[4]; | |
| 583 | 582 | glGetIntegerv(GL_VIEWPORT, view); | |
| 584 | return QRect(view[0], device->height() - (view[1] + view[3]), | ||
| 585 | view[1], view[3]); | ||
| 586 | } else { | ||
| 587 | return QRect(); | ||
| 583 | d->viewport = QRect(view[0], view[1], view[2], view[3]); | ||
| 588 | 584 | } | |
| 585 | // Convert the GL viewport into standard Qt co-ordinates. | ||
| 586 | return QRect(d->viewport.x(), | ||
| 587 | d->context->device()->height() - | ||
| 588 | (d->viewport.y() + d->viewport.height()), | ||
| 589 | d->viewport.width(), d->viewport.height()); | ||
| 589 | 590 | } | |
| 590 | 591 | ||
| 591 | 592 | /*! | |
| 592 | 593 | Sets the viewport for the active GL context to \a rect. | |
| 593 | 594 | The origin for \a rect is the top-left of the drawing surface. | |
| 594 | 595 | ||
| 595 | \sa viewport() | ||
| 596 | \sa viewport(), resetViewport() | ||
| 596 | 597 | */ | |
| 597 | 598 | void QGLPainter::setViewport(const QRect& rect) | |
| 598 | 599 | { | |
| 599 | 600 | Q_D(QGLPainter); | |
| 600 | 601 | QGLPAINTER_CHECK_PRIVATE(); | |
| 601 | QPaintDevice *device = d->context->device(); | ||
| 602 | if (device) { | ||
| 603 | int y = device->height() - (rect.y() + rect.height()); | ||
| 604 | glViewport(rect.x(), y, rect.width(), rect.height()); | ||
| 605 | } | ||
| 602 | int y = d->context->device()->height() - (rect.y() + rect.height()); | ||
| 603 | glViewport(rect.x(), y, rect.width(), rect.height()); | ||
| 604 | d->viewport = QRect(rect.x(), y, rect.width(), rect.height()); | ||
| 606 | 605 | } | |
| 607 | 606 | ||
| 608 | 607 | /*! | |
| 609 | 608 | Sets the viewport for the active GL context to start at the | |
| 610 | 609 | origin and extend for \a size. | |
| 611 | 610 | ||
| 612 | \sa viewport() | ||
| 611 | \sa viewport(), resetViewport() | ||
| 613 | 612 | */ | |
| 614 | 613 | void QGLPainter::setViewport(const QSize& size) | |
| 615 | 614 | { | |
| 615 | Q_D(QGLPainter); | ||
| 616 | QGLPAINTER_CHECK_PRIVATE(); | ||
| 616 | 617 | glViewport(0, 0, size.width(), size.height()); | |
| 618 | d->viewport = QRect(0, 0, size.width(), size.height()); | ||
| 617 | 619 | } | |
| 618 | 620 | ||
| 619 | 621 | /*! | |
| 620 | 622 | Sets the viewport for the active GL context to start at the | |
| 621 | 623 | origin and extend for \a width and \a height. | |
| 622 | 624 | ||
| 623 | \sa viewport() | ||
| 625 | \sa viewport(), resetViewport() | ||
| 624 | 626 | */ | |
| 625 | 627 | void QGLPainter::setViewport(int width, int height) | |
| 626 | 628 | { | |
| 629 | Q_D(QGLPainter); | ||
| 630 | QGLPAINTER_CHECK_PRIVATE(); | ||
| 627 | 631 | glViewport(0, 0, width, height); | |
| 632 | d->viewport = QRect(0, 0, width, height); | ||
| 628 | 633 | } | |
| 629 | 634 | ||
| 630 | 635 | /*! | |
| 636 | Resets this painter's notion of what the current viewport() | ||
| 637 | is set to. The next time viewport() is called, the actual | ||
| 638 | viewport rectangle will be fetched from the GL server. | ||
| 639 | |||
| 640 | This function is used to synchronize the state of the application | ||
| 641 | with the GL server after the execution of raw GL commands that may | ||
| 642 | have altered the viewport settings. | ||
| 643 | |||
| 644 | \sa viewport(), setViewport() | ||
| 645 | */ | ||
| 646 | void QGLPainter::resetViewport() | ||
| 647 | { | ||
| 648 | Q_D(QGLPainter); | ||
| 649 | QGLPAINTER_CHECK_PRIVATE(); | ||
| 650 | d->viewport = QRect(); | ||
| 651 | } | ||
| 652 | |||
| 653 | /*! | ||
| 631 | 654 | Returns the currently active scissor rectangle; or a null rectangle | |
| 632 | 655 | if scissoring is disabled. | |
| 633 | 656 | ||
| … | … | ||
| 884 | 884 | QBox3D projected = box.transformed | |
| 885 | 885 | (d->projectionMatrix * d->modelViewMatrix); | |
| 886 | 886 | return d->viewingCube.intersects(projected); | |
| 887 | } | ||
| 888 | |||
| 889 | /*! | ||
| 890 | Projects a \a point in object model space to window co-ordinates | ||
| 891 | using the current modelViewMatrix(), projectionMatrix(), and viewport(). | ||
| 892 | Returns the window co-ordinates. | ||
| 893 | |||
| 894 | If \a ok is not null, then it will be set if true if the projection | ||
| 895 | was possible, or false if \a point cannot be projected. | ||
| 896 | |||
| 897 | \sa unproject() | ||
| 898 | */ | ||
| 899 | QVector3D QGLPainter::project(const QVector3D& point, bool *ok) const | ||
| 900 | { | ||
| 901 | Q_D(const QGLPainter); | ||
| 902 | QGLPAINTER_CHECK_PRIVATE_RETURN(QVector3D()); | ||
| 903 | |||
| 904 | // Map the point using the modelview and projection matrices. | ||
| 905 | QVector4D v = d->modelViewMatrix.top() * QVector4D(point, 1.0f); | ||
| 906 | v = d->projectionMatrix.top() * v; | ||
| 907 | if (qFuzzyCompare(v.w(), qreal(0.0f))) { | ||
| 908 | if (ok) | ||
| 909 | *ok = false; | ||
| 910 | return QVector3D(); | ||
| 911 | } | ||
| 912 | |||
| 913 | // Map the co-ordinates to the range 0-1. | ||
| 914 | qreal x = (v.x() / v.w()) * 0.5f + 0.5f; | ||
| 915 | qreal y = (v.y() / v.w()) * 0.5f + 0.5f; | ||
| 916 | qreal z = (v.z() / v.w()) * 0.5f + 0.5f; | ||
| 917 | |||
| 918 | // Map x and y to the viewport dimensions. | ||
| 919 | if (d->viewport.isNull()) { | ||
| 920 | GLint view[4]; | ||
| 921 | glGetIntegerv(GL_VIEWPORT, view); | ||
| 922 | const_cast<QGLPainterPrivate *>(d)->viewport | ||
| 923 | = QRect(view[0], view[1], view[2], view[3]); | ||
| 924 | } | ||
| 925 | x = x * d->viewport.width() + d->viewport.x(); | ||
| 926 | y = y * d->viewport.height() + d->viewport.y(); | ||
| 927 | if (ok) | ||
| 928 | *ok = true; | ||
| 929 | return QVector3D(x, y, z); | ||
| 930 | } | ||
| 931 | |||
| 932 | /*! | ||
| 933 | Projects a \a point in window co-ordinates back to object model space | ||
| 934 | using the current modelViewMatrix(), projectionMatrix(), and viewport(). | ||
| 935 | Returns the object model co-ordinates. | ||
| 936 | |||
| 937 | If \a ok is not null, then it will be set if true if the projection | ||
| 938 | was possible, or false if \a point cannot be projected. | ||
| 939 | |||
| 940 | \sa project() | ||
| 941 | */ | ||
| 942 | QVector3D QGLPainter::unproject(const QVector3D& point, bool *ok) const | ||
| 943 | { | ||
| 944 | Q_D(const QGLPainter); | ||
| 945 | QGLPAINTER_CHECK_PRIVATE_RETURN(QVector3D()); | ||
| 946 | |||
| 947 | // Invert the combined modelview/projection matrix. | ||
| 948 | bool invertible; | ||
| 949 | QMatrix4x4 m = combinedMatrix().inverted(&invertible); | ||
| 950 | if (!invertible) { | ||
| 951 | if (ok) | ||
| 952 | *ok = false; | ||
| 953 | return QVector3D(); | ||
| 954 | } | ||
| 955 | |||
| 956 | // Map from window co-ordinates to the (-1, -1) - (1, 1) viewport. | ||
| 957 | if (d->viewport.isNull()) { | ||
| 958 | GLint view[4]; | ||
| 959 | glGetIntegerv(GL_VIEWPORT, view); | ||
| 960 | const_cast<QGLPainterPrivate *>(d)->viewport | ||
| 961 | = QRect(view[0], view[1], view[2], view[3]); | ||
| 962 | } | ||
| 963 | qreal x = ((point.x() - d->viewport.x()) / d->viewport.width()) * 2 - 1; | ||
| 964 | qreal y = ((point.y() - d->viewport.y()) / d->viewport.height()) * 2 - 1; | ||
| 965 | qreal z = point.z() * 2 - 1; | ||
| 966 | |||
| 967 | // Map the point back through the inverse of the projection. | ||
| 968 | QVector4D v = m * QVector4D(x, y, z, 1.0f); | ||
| 969 | if (qFuzzyCompare(v.w(), qreal(0.0f))) { | ||
| 970 | if (ok) | ||
| 971 | *ok = false; | ||
| 972 | return QVector3D(); | ||
| 973 | } | ||
| 974 | if (ok) | ||
| 975 | *ok = true; | ||
| 976 | return QVector3D(v.x() / v.w(), v.y() / v.w(), v.z() / v.w()); | ||
| 977 | } | ||
| 978 | |||
| 979 | /*! | ||
| 980 | \overload | ||
| 981 | |||
| 982 | Projects a 4D \a point in window co-ordinates back to object model space | ||
| 983 | using the current modelViewMatrix(), projectionMatrix(), and viewport(). | ||
| 984 | Returns the object model co-ordinates, including the w co-ordinate. | ||
| 985 | |||
| 986 | The \a nearPlane and \a farPlane parameters are used to specify the | ||
| 987 | near and far clipping planes in the z direction. | ||
| 988 | |||
| 989 | If \a ok is not null, then it will be set if true if the projection | ||
| 990 | was possible, or false if \a point cannot be projected. | ||
| 991 | |||
| 992 | \sa project() | ||
| 993 | */ | ||
| 994 | QVector4D QGLPainter::unproject | ||
| 995 | (const QVector4D& point, qreal nearPlane, qreal farPlane, bool *ok) const | ||
| 996 | { | ||
| 997 | Q_D(const QGLPainter); | ||
| 998 | QGLPAINTER_CHECK_PRIVATE_RETURN(QVector4D()); | ||
| 999 | |||
| 1000 | // Invert the combined modelview/projection matrix. | ||
| 1001 | bool invertible; | ||
| 1002 | QMatrix4x4 m = combinedMatrix().inverted(&invertible); | ||
| 1003 | if (!invertible) { | ||
| 1004 | if (ok) | ||
| 1005 | *ok = false; | ||
| 1006 | return QVector4D(); | ||
| 1007 | } | ||
| 1008 | |||
| 1009 | // Map from window co-ordinates to the (-1, -1) - (1, 1) viewport. | ||
| 1010 | if (d->viewport.isNull()) { | ||
| 1011 | GLint view[4]; | ||
| 1012 | glGetIntegerv(GL_VIEWPORT, view); | ||
| 1013 | const_cast<QGLPainterPrivate *>(d)->viewport | ||
| 1014 | = QRect(view[0], view[1], view[2], view[3]); | ||
| 1015 | } | ||
| 1016 | qreal x = ((point.x() - d->viewport.x()) / d->viewport.width()) * 2 - 1; | ||
| 1017 | qreal y = ((point.y() - d->viewport.y()) / d->viewport.height()) * 2 - 1; | ||
| 1018 | qreal z = ((point.z() - nearPlane) / (farPlane - nearPlane)) * 2 - 1; | ||
| 1019 | |||
| 1020 | // Map the point back through the inverse of the projection. | ||
| 1021 | QVector4D v = m * QVector4D(x, y, z, point.w()); | ||
| 1022 | if (qFuzzyCompare(v.w(), qreal(0.0f))) { | ||
| 1023 | if (ok) | ||
| 1024 | *ok = false; | ||
| 1025 | return QVector4D(); | ||
| 1026 | } | ||
| 1027 | if (ok) | ||
| 1028 | *ok = true; | ||
| 1029 | return v; | ||
| 887 | 1030 | } | |
| 888 | 1031 | ||
| 889 | 1032 | /*! |
threed/painting/qglpainter.h
(6 / 0)
|   | |||
| 115 | 115 | void setViewport(const QRect& rect); | |
| 116 | 116 | void setViewport(const QSize& size); | |
| 117 | 117 | void setViewport(int width, int height); | |
| 118 | void resetViewport(); | ||
| 118 | 119 | ||
| 119 | 120 | QRect scissor() const; | |
| 120 | 121 | void setScissor(const QRect& rect); | |
| … | … | ||
| 129 | 129 | ||
| 130 | 130 | bool isVisible(const QVector3D& point) const; | |
| 131 | 131 | bool isVisible(const QBox3D& box) const; | |
| 132 | |||
| 133 | QVector3D project(const QVector3D& point, bool *ok = 0) const; | ||
| 134 | QVector3D unproject(const QVector3D& point, bool *ok = 0) const; | ||
| 135 | QVector4D unproject(const QVector4D& point, qreal nearPlane, | ||
| 136 | qreal farPlane, bool *ok = 0) const; | ||
| 132 | 137 | ||
| 133 | 138 | qreal aspectRatio() const; | |
| 134 | 139 | qreal aspectRatio(const QSize& viewportSize) const; |
|   | |||
| 233 | 233 | QGLMaterial *backColorMaterial; | |
| 234 | 234 | const QGLFogParameters *fogParameters; | |
| 235 | 235 | QBox3D viewingCube; | |
| 236 | QRect scissor; | ||
| 236 | QRect viewport; // GL co-ordinates - origin bottom-left. | ||
| 237 | QRect scissor; // Qt co-ordinates - origin top-left. | ||
| 237 | 238 | QColor color; | |
| 238 | 239 | QGLPainter::Updates updates; | |
| 239 | 240 | GLuint currentBufferId; |

