⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qpaintengine_opengl.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    QSize sz(d->drawable.size());    glViewport(0, 0, sz.width(), sz.height()); // XXX (Embedded): We need a solution for GLWidgets that draw in a part or a bigger surface...    glMatrixMode(GL_PROJECTION);    glLoadIdentity();#ifdef Q_WS_QWS    glOrthof(0, sz.width(), sz.height(), 0, -999999, 999999);#else    glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999);#endif    glMatrixMode(GL_MODELVIEW);    glLoadIdentity();    glEnable(GL_BLEND);    d->composition_mode = QPainter::CompositionMode_SourceOver;#ifndef Q_WS_QWS    bool shared_ctx = qgl_share_reg()->checkSharing(d->drawable.context(), d->shader_ctx);    if (!shared_ctx) {        if (d->shader_ctx) {            d->shader_ctx->makeCurrent();            glBindTexture(GL_TEXTURE_1D, 0);            glDeleteTextures(1, &d->grad_palette);            if (has_frag_program && d->use_fragment_programs) {                glDeleteTextures(1, &d->drawable_texture);                d->deleteFragmentPrograms();            }            d->drawable.context()->makeCurrent();        }        d->shader_ctx = d->drawable.context();        glGenTextures(1, &d->grad_palette);        qt_mask_texture_cache()->clearCache();        if (has_frag_program) {            d->use_fragment_programs = d->createFragmentPrograms();            if (!d->use_fragment_programs) {                d->deleteFragmentPrograms();                qWarning() << "QOpenGLPaintEngine: Failed to create fragment programs.";            }        }        gccaps &= ~(RadialGradientFill | ConicalGradientFill | LinearGradientFill | PatternBrush | BlendModes);        if (d->use_fragment_programs)            gccaps |= (RadialGradientFill | ConicalGradientFill | LinearGradientFill | PatternBrush | BlendModes);        else if (QGLExtensions::glExtensions & QGLExtensions::MirroredRepeat)            gccaps |= LinearGradientFill;    }    if (d->use_fragment_programs && (!shared_ctx || sz.width() > d->drawable_texture_size.width()                                                 || sz.height() > d->drawable_texture_size.height()))    {        // delete old texture if size has increased, otherwise it was deleted earlier        if (shared_ctx)            glDeleteTextures(1, &d->drawable_texture);        glGenTextures(1, &d->drawable_texture);        glBindTexture(GL_TEXTURE_2D, d->drawable_texture);        QSize adjusted_size(qt_next_power_of_two(sz.width()),                            qt_next_power_of_two(sz.height()));        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,                     adjusted_size.width(),                     adjusted_size.height(), 0,                     GL_RGBA, GL_UNSIGNED_BYTE, NULL);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);        d->drawable_texture_size = adjusted_size;    }#endif    setDirty(QPaintEngine::DirtyPen);    setDirty(QPaintEngine::DirtyBrush);    setDirty(QPaintEngine::DirtyCompositionMode);#ifdef Q_WS_QWS    // XXX: needed only if painting on a widget?    updateClipRegion(QRegion(), Qt::NoClip);#endif    return true;}bool QOpenGLPaintEngine::end(){    Q_D(QOpenGLPaintEngine);    d->flushDrawQueue();    d->offscreen.end();    glMatrixMode(GL_TEXTURE);    glPopMatrix();    glMatrixMode(GL_MODELVIEW);    glPopMatrix();#ifndef Q_WS_QWS    glMatrixMode(GL_PROJECTION);    glLoadMatrixd(&d->projection_matrix[0][0]);    glPopAttrib();    glPopClientAttrib();#endif#ifndef Q_WS_QWS    d->drawable.swapBuffers();#endif    d->drawable.doneCurrent();    qt_mask_texture_cache()->maintainCache();    return true;}void QOpenGLPaintEngine::updateState(const QPaintEngineState &state){    Q_D(QOpenGLPaintEngine);    QPaintEngine::DirtyFlags flags = state.state();    bool update_fast_pen = false;    if (flags & DirtyOpacity) {        update_fast_pen = true;        d->opacity = state.opacity();        if (d->opacity > 1.0f)            d->opacity = 1.0f;        if (d->opacity < 0.f)            d->opacity = 0.f;        // force update        flags |= DirtyPen;        flags |= DirtyBrush;    }    if (flags & DirtyTransform) {        update_fast_pen = true;        updateMatrix(state.transform());        // brush setup depends on transform state        if (state.brush().style() != Qt::NoBrush)            flags |= DirtyBrush;    }    if (flags & DirtyPen) {        update_fast_pen = true;        updatePen(state.pen());    }    if (flags & (DirtyBrush | DirtyBrushOrigin)) {        updateBrush(state.brush(), state.brushOrigin());    }    if (flags & DirtyFont) {        updateFont(state.font());    }    if (state.state() & DirtyClipEnabled) {        if (state.isClipEnabled())            updateClipRegion(painter()->clipRegion(), Qt::ReplaceClip);        else            updateClipRegion(QRegion(), Qt::NoClip);    }    if (flags & DirtyClipPath) {        updateClipRegion(QRegion(state.clipPath().toFillPolygon().toPolygon(),                                 state.clipPath().fillRule()),                         state.clipOperation());    }    if (flags & DirtyClipRegion) {        updateClipRegion(state.clipRegion(), state.clipOperation());    }    if (flags & DirtyHints) {        updateRenderHints(state.renderHints());    }    if (flags & DirtyCompositionMode) {        updateCompositionMode(state.compositionMode());    }    if (update_fast_pen) {        Q_D(QOpenGLPaintEngine);        qreal pen_width = d->cpen.widthF();        d->has_fast_pen =            ((pen_width == 0 || (pen_width <= 1 && d->txop <= QTransform::TxTranslate))             || d->cpen.isCosmetic())            && d->cpen.style() == Qt::SolidLine            && d->cpen.isSolid();    }}void QOpenGLPaintEnginePrivate::setInvMatrixData(const QTransform &inv_matrix){    inv_matrix_data[0][0] = inv_matrix.m11();    inv_matrix_data[1][0] = inv_matrix.m21();    inv_matrix_data[2][0] = inv_matrix.m31();    inv_matrix_data[0][1] = inv_matrix.m12();    inv_matrix_data[1][1] = inv_matrix.m22();    inv_matrix_data[2][1] = inv_matrix.m32();    inv_matrix_data[0][2] = inv_matrix.m13();    inv_matrix_data[1][2] = inv_matrix.m23();    inv_matrix_data[2][2] = inv_matrix.m33();}void QOpenGLPaintEnginePrivate::updateGradient(const QBrush &brush, const QRectF &bounds){#ifdef Q_WS_QWS    Q_UNUSED(brush);    Q_UNUSED(bounds);#else    bool has_mirrored_repeat = QGLExtensions::glExtensions & QGLExtensions::MirroredRepeat;    Qt::BrushStyle style = brush.style();    if (has_mirrored_repeat && style == Qt::LinearGradientPattern) {        const QLinearGradient *g = static_cast<const QLinearGradient *>(brush.gradient());        QTransform m = brush.transform();        QPointF realStart = g->start();        QPointF realFinal = g->finalStop();        if (g->coordinateMode() == QGradient::ObjectBoundingMode) {            qreal sx = bounds.x() + realStart.x() * bounds.width();            qreal sy = bounds.y() + realStart.y() * bounds.height();            qreal fx = bounds.x() + realFinal.x() * bounds.width();            qreal fy = bounds.y() + realFinal.y() * bounds.height();            realStart = QPointF(sx, sy);            realFinal = QPointF(fx, fy);        }        QPointF start = m.map(realStart);        QPointF stop;        if (qFuzzyCompare(m.m11(), m.m22()) && m.m12() == 0.0 && m.m21() == 0.0) {            // It is a simple uniform scale and/or translation            stop = m.map(realFinal);        } else {            // It is not enough to just transform the endpoints.            // We have to make sure the _pattern_ is transformed correctly.            qreal odx = realFinal.x() - realStart.x();            qreal ody = realFinal.y() - realStart.y();            // nx, ny and dx, dy are normal and gradient direction after transform:            qreal nx = m.m11()*ody - m.m21()*odx;            qreal ny = m.m12()*ody - m.m22()*odx;            qreal dx = m.m11()*odx + m.m21()*ody;            qreal dy = m.m12()*odx + m.m22()*ody;            qreal lx = 1.0/(dx - dy*nx/ny);            qreal ly = 1.0/(dy - dx*ny/nx);            qreal l = 1.0/sqrt(lx*lx+ly*ly);            stop = start + QPointF(-ny, nx) * l/sqrt(nx*nx+ny*ny);        }        float tr[4], f;        tr[0] = stop.x() - start.x();        tr[1] = stop.y() - start.y();        f = 1.0 / (tr[0]*tr[0] + tr[1]*tr[1]);        tr[0] *= f;        tr[1] *= f;        tr[2] = 0;        tr[3] = -(start.x()*tr[0] + start.y()*tr[1]);        setGLBrush(Qt::white);        qt_glColor4ubv(brush_color);        glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);        glTexGenfv(GL_S, GL_OBJECT_PLANE, tr);    }    if (use_fragment_programs) {        if (style == Qt::RadialGradientPattern) {            const QRadialGradient *g = static_cast<const QRadialGradient *>(brush.gradient());            QPointF realCenter = g->center();            QPointF realFocal  = g->focalPoint();            qreal   realRadius = g->radius();            if (g->coordinateMode() == QGradient::ObjectBoundingMode) {                qreal x = bounds.x() + realCenter.x() * bounds.width();                qreal y = bounds.y() + realCenter.y() * bounds.height();                realCenter = QPointF(x, y);                x = bounds.x() + realFocal.x() * bounds.width();                y = bounds.y() + realFocal.y() * bounds.height();                realFocal = QPointF(x, y);                realRadius = qMin(bounds.x() + bounds.width() * realRadius,                                  bounds.y() + bounds.height() * realRadius);            }            QTransform translate(1, 0, 0, 1, -realFocal.x(), -realFocal.y());            QTransform gl_to_qt(1, 0, 0, -1, 0, pdev->height());            QTransform inv_matrix = gl_to_qt * matrix.inverted() * brush.transform().inverted() * translate;            setInvMatrixData(inv_matrix);            fmp_data[0] = realCenter.x() - realFocal.x();            fmp_data[1] = realCenter.y() - realFocal.y();            fmp2_m_radius2_data[0] = -fmp_data[0] * fmp_data[0] - fmp_data[1] * fmp_data[1] + realRadius * realRadius;        } else if (style == Qt::ConicalGradientPattern) {            const QConicalGradient *g = static_cast<const QConicalGradient *>(brush.gradient());            QPointF realCenter = g->center();            if (g->coordinateMode() == QGradient::ObjectBoundingMode) {                qreal x = bounds.x() + bounds.width() * realCenter.x();                qreal y = bounds.y() + bounds.height() * realCenter.y();                realCenter = QPointF(x, y);            }            QTransform translate(1, 0, 0, 1, -realCenter.x(), -realCenter.y());            QTransform gl_to_qt(1, 0, 0, -1, 0, pdev->height());            QTransform inv_matrix = gl_to_qt * matrix.inverted() * brush.transform().inverted() * translate;            setInvMatrixData(inv_matrix);            angle_data[0] = -(g->angle() * 2 * Q_PI) / 360.0;        } else if (style == Qt::LinearGradientPattern) {            const QLinearGradient *g = static_cast<const QLinearGradient *>(brush.gradient());            QPointF realStart = g->start();            QPointF realFinal = g->finalStop();            if (g->coordinateMode() == QGradient::ObjectBoundingMode) {                qreal sx = bounds.x() + realStart.x() * bounds.width();                qreal sy = bounds.y() + realStart.y() * bounds.height();                qreal fx = bounds.x() + realFinal.x() * bounds.width();                qreal fy = bounds.y() + realFinal.y() * bounds.height();                realStart = QPointF(sx, sy);                realFinal = QPointF(fx, fy);            }            QTransform translate(1, 0, 0, 1, -realStart.x(), -realStart.y());            QTransform gl_to_qt(1, 0, 0, -1, 0, pdev->height());            QTransform inv_matrix = gl_to_qt * matrix.inverted() * brush.transform().inverted() * translate;            setInvMatrixData(inv_matrix);            QPointF l = realFinal - realStart;            linear_data[0] = l.x();            linear_data[1] = l.y();            linear_data[2] = 1.0f / (l.x() * l.x() + l.y() * l.y());        } else if (style != Qt::SolidPattern) {            QTransform translate(1, 0, 0, 1, brush_origin.x(), brush_origin.y());            QTransform gl_to_qt(1, 0, 0, -1, 0, pdev->height());            QTransform inv_matrix = gl_to_qt * matrix.inverted() * brush.transform().inverted() * translate;            setInvMatrixData(inv_matrix);        }    }    if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern) {        createGradientPaletteTexture(*brush.gradient());    }#endif}class QOpenGLTessellator : public QTessellator{public:    QOpenGLTessellator() {}    ~QOpenGLTessellator() { }    QGLTrapezoid toGLTrapezoid(const Trapezoid &trap);};QGLTrapezoid QOpenGLTessellator::toGLTrapezoid(const Trapezoid &trap){    QGLTrapezoid t;    t.top = Q27Dot5ToDouble(trap.top);    t.bottom = Q27Dot5ToDouble(trap.bottom);    Q27Dot5 y = trap.topLeft->y - trap.bottomLeft->y;    qreal topLeftY = Q27Dot5ToDouble(trap.topLeft->y);    qreal tx = Q27Dot5ToDouble(trap.topLeft->x);    qreal m = (-tx + Q27Dot5ToDouble(trap.bottomLeft->x)) / Q27Dot5ToDouble(y);    t.topLeftX = tx + m * (topLeftY - t.top);    t.bottomLeftX = tx + m * (topLeftY - t.bottom);    y = trap.topRight->y - trap.bottomRight->y;    qreal topRightY = Q27Dot5ToDouble(trap.topRight->y);    tx = Q27Dot5ToDouble(trap.topRight->x);    m = (-tx + Q27Dot5ToDouble(trap.bottomRight->x)) / Q27Dot5ToDouble(y);    t.topRightX = tx + m * (topRightY - Q27Dot5ToDouble(trap.top));    t.bottomRightX = tx + m * (topRightY - Q27Dot5ToDouble(trap.bottom));    return t;}class QOpenGLImmediateModeTessellator : public QOpenGLTessellator{public:    void addTrap(const Trapezoid &trap);    void tessellate(const QPointF *points, int nPoints, bool winding) {        trapezoids.reserve(trapezoids.size() + nPoints);        setWinding(winding);        QTessellator::tessellate(points, nPoints);    }    QVector<QGLTrapezoid> trapezoids;};void QOpenGLImmediateModeTessellator::addTrap(const Trapezoid &trap){    trapezoids.append(toGLTrapezoid(trap));}#ifndef Q_WS_QWSstatic void drawTrapezoid(const QGLTrapezoid &trap, const qreal offscreenHeight, QGLContext *ctx){    qreal minX = qMin(trap.topLeftX, trap.bottomLeftX);    qreal maxX = qMax(trap.topRightX, trap.bottomRightX);    if (qFuzzyCompare(trap.top, trap.bottom) || qFuzzyCompare(minX, maxX) ||        qFuzzyCompare(trap.topLeftX, trap.topRightX) && qFuzzyCompare(trap.bottomLeftX, trap.bottomRightX))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -