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

📄 qpaintengine_opengl.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        return;    const qreal xpadding = 1.0;    const qreal ypadding = 1.0;    qreal topDist = offscreenHeight - trap.top;    qreal bottomDist = offscreenHeight - trap.bottom;    qreal reciprocal = bottomDist / (bottomDist - topDist);    qreal leftB = trap.bottomLeftX + (trap.topLeftX - trap.bottomLeftX) * reciprocal;    qreal rightB = trap.bottomRightX + (trap.topRightX - trap.bottomRightX) * reciprocal;    const bool topZero = qFuzzyCompare(topDist, 0);    reciprocal = topZero ? 1.0 / bottomDist : 1.0 / topDist;    qreal leftA = topZero ? (trap.bottomLeftX - leftB) * reciprocal : (trap.topLeftX - leftB) * reciprocal;    qreal rightA = topZero ? (trap.bottomRightX - rightB) * reciprocal : (trap.topRightX - rightB) * reciprocal;    qreal invLeftA = qFuzzyCompare(leftA, qreal(0.0)) ? 0.0 : 1.0 / leftA;    qreal invRightA = qFuzzyCompare(rightA, qreal(0.0)) ? 0.0 : 1.0 / rightA;    // fragment program needs the negative of invRightA as it mirrors the line    glTexCoord4f(topDist, bottomDist, invLeftA, -invRightA);    glMultiTexCoord4f(GL_TEXTURE1, leftA, leftB, rightA, rightB);    qreal topY = trap.top - ypadding;    qreal bottomY = trap.bottom + ypadding;    qreal bounds_bottomLeftX = leftA * (offscreenHeight - bottomY) + leftB;    qreal bounds_bottomRightX = rightA * (offscreenHeight - bottomY) + rightB;    qreal bounds_topLeftX = leftA * (offscreenHeight - topY) + leftB;    qreal bounds_topRightX = rightA * (offscreenHeight - topY) + rightB;    QPointF leftNormal(1, -leftA);    leftNormal /= sqrt(leftNormal.x() * leftNormal.x() + leftNormal.y() * leftNormal.y());    QPointF rightNormal(1, -rightA);    rightNormal /= sqrt(rightNormal.x() * rightNormal.x() + rightNormal.y() * rightNormal.y());    qreal left_padding = xpadding / qAbs(leftNormal.x());    qreal right_padding = xpadding / qAbs(rightNormal.x());    glVertex2d(bounds_topLeftX - left_padding, topY);    glVertex2d(bounds_topRightX + right_padding, topY);    glVertex2d(bounds_bottomRightX + right_padding, bottomY);    glVertex2d(bounds_bottomLeftX - left_padding, bottomY);    glTexCoord4f(0.0f, 0.0f, 0.0f, 1.0f);}#endif // !Q_WS_QWSclass QOpenGLTrapezoidToArrayTessellator : public QOpenGLTessellator{public:    QOpenGLTrapezoidToArrayTessellator() : vertices(0), allocated(0), size(0) {}    ~QOpenGLTrapezoidToArrayTessellator() { free(vertices); }    float *vertices;    int allocated;    int size;    QRectF bounds;    void addTrap(const Trapezoid &trap);    void tessellate(const QPointF *points, int nPoints, bool winding) {        size = 0;        setWinding(winding);        bounds = QTessellator::tessellate(points, nPoints);    }};void QOpenGLTrapezoidToArrayTessellator::addTrap(const Trapezoid &trap){#ifndef Q_WS_QWS    if (size > allocated - 8) {#else    if (size > allocated - 12) {#endif        allocated = qMax(2*allocated, 512);        vertices = (float *)realloc(vertices, allocated * sizeof(float));    }    QGLTrapezoid t = toGLTrapezoid(trap);#ifndef Q_WS_QWS    vertices[size++] = t.topLeftX;    vertices[size++] = t.top;    vertices[size++] = t.topRightX;    vertices[size++] = t.top;    vertices[size++] = t.bottomRightX;    vertices[size++] = t.bottom;    vertices[size++] = t.bottomLeftX;    vertices[size++] = t.bottom;#else    vertices[size++] = t.topLeftX;    vertices[size++] = t.top;    vertices[size++] = t.topRightX;    vertices[size++] = t.top;    vertices[size++] = t.bottomRightX;    vertices[size++] = t.bottom;    vertices[size++] = t.bottomLeftX;    vertices[size++] = t.bottom;    vertices[size++] = t.topLeftX;    vertices[size++] = t.top;    vertices[size++] = t.bottomRightX;    vertices[size++] = t.bottom;#endif}void QOpenGLPaintEnginePrivate::fillPolygon_dev(const QPointF *polygonPoints, int pointCount,                                                Qt::FillRule fill){    QOpenGLTrapezoidToArrayTessellator tessellator;    tessellator.tessellate(polygonPoints, pointCount, fill == Qt::WindingFill);    DEBUG_ONCE qDebug() << "QOpenGLPaintEnginePrivate: Drawing polygon with" << pointCount << "points using fillPolygon_dev";    setGradientOps(cbrush, tessellator.bounds);    bool fast_style = current_style == Qt::LinearGradientPattern                      || current_style == Qt::SolidPattern;#ifndef Q_WS_QWS    GLenum geometry_mode = GL_QUADS;#else    GLenum geometry_mode = GL_TRIANGLES;#endif    if (use_fragment_programs && !(fast_style && has_fast_composition_mode)) {        composite(geometry_mode, tessellator.vertices, tessellator.size / 2);    } else {        glVertexPointer(2, GL_FLOAT, 0, tessellator.vertices);        glEnableClientState(GL_VERTEX_ARRAY);        glDrawArrays(geometry_mode, 0, tessellator.size/2);        glDisableClientState(GL_VERTEX_ARRAY);    }}inline void QOpenGLPaintEnginePrivate::lineToStencil(qreal x, qreal y){    tess_points.add(QPointF(x, y));    if (x > max_x)        max_x = x;    else if (x < min_x)        min_x = x;    if (y > max_y)        max_y = y;    else if (y < min_y)        min_y = y;}inline void QOpenGLPaintEnginePrivate::curveToStencil(const QPointF &cp1, const QPointF &cp2, const QPointF &ep){    qreal inverseScaleHalf = inverseScale / 2;    QBezier beziers[32];    beziers[0] = QBezier::fromPoints(tess_points.last(), cp1, cp2, ep);    QBezier *b = beziers;    while (b >= beziers) {        // check if we can pop the top bezier curve from the stack        qreal l = qAbs(b->x4 - b->x1) + qAbs(b->y4 - b->y1);        qreal d;        if (l > inverseScale) {            d = qAbs( (b->x4 - b->x1)*(b->y1 - b->y2) - (b->y4 - b->y1)*(b->x1 - b->x2) )                + qAbs( (b->x4 - b->x1)*(b->y1 - b->y3) - (b->y4 - b->y1)*(b->x1 - b->x3) );            d /= l;        } else {            d = qAbs(b->x1 - b->x2) + qAbs(b->y1 - b->y2) +                qAbs(b->x1 - b->x3) + qAbs(b->y1 - b->y3);        }        if (d < inverseScaleHalf || b == beziers + 31) {            // good enough, we pop it off and add the endpoint            lineToStencil(b->x4, b->y4);            --b;        } else {            // split, second half of the polygon goes lower into the stack            b->split(b+1, b);           ++b;        }    }}void QOpenGLPaintEnginePrivate::pathToVertexArrays(const QPainterPath &path){    const QPainterPath::Element &first = path.elementAt(0);    min_x = max_x = first.x;    min_y = max_y = first.y;    tess_points.reset();    tess_points_stops.clear();    lineToStencil(first.x, first.y);    for (int i=1; i<path.elementCount(); ++i) {        const QPainterPath::Element &e = path.elementAt(i);        switch (e.type) {        case QPainterPath::MoveToElement:            tess_points_stops.append(tess_points.size());            lineToStencil(e.x, e.y);            break;        case QPainterPath::LineToElement:            lineToStencil(e.x, e.y);            break;        case QPainterPath::CurveToElement:            curveToStencil(e, path.elementAt(i+1), path.elementAt(i+2));            i+=2;            break;        default:            break;        }    }    lineToStencil(first.x, first.y);    tess_points_stops.append(tess_points.size());}void QOpenGLPaintEnginePrivate::drawVertexArrays(){    glEnableClientState(GL_VERTEX_ARRAY);    glVertexPointer(2, GL_DOUBLE, 0, tess_points.data());    int previous_stop = 0;    foreach(int stop, tess_points_stops) {        glDrawArrays(GL_TRIANGLE_FAN, previous_stop, stop-previous_stop);        previous_stop = stop;    }    glDisableClientState(GL_VERTEX_ARRAY);}void QOpenGLPaintEnginePrivate::fillVertexArray(Qt::FillRule fillRule){    glStencilMask(~0);    // Enable stencil.    glEnable(GL_STENCIL_TEST);    // Disable color writes.    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);    GLuint stencilMask = 0;    if (fillRule == Qt::OddEvenFill) {        stencilMask = 1;        // Enable stencil writes.        glStencilMask(stencilMask);        // Set stencil xor mode.        glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT);        // Disable stencil func.        glStencilFunc(GL_ALWAYS, 0, ~0);        drawVertexArrays();    } else if (fillRule == Qt::WindingFill) {        stencilMask = ~0;        if (has_stencil_face_ext) {            QGL_FUNC_CONTEXT;            glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);            glActiveStencilFaceEXT(GL_BACK);            glStencilOp(GL_KEEP, GL_KEEP, GL_DECR_WRAP_EXT);            glStencilFunc(GL_ALWAYS, 0, ~0);            glActiveStencilFaceEXT(GL_FRONT);            glStencilOp(GL_KEEP, GL_KEEP, GL_INCR_WRAP_EXT);            glStencilFunc(GL_ALWAYS, 0, ~0);            drawVertexArrays();            glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);        } else {            glStencilFunc(GL_ALWAYS, 0, ~0);            glEnable(GL_CULL_FACE);            glCullFace(GL_BACK);            glStencilOp(GL_KEEP, GL_KEEP, GL_INCR_WRAP_EXT);            drawVertexArrays();            glCullFace(GL_FRONT);            glStencilOp(GL_KEEP, GL_KEEP, GL_DECR_WRAP_EXT);            drawVertexArrays();            glDisable(GL_CULL_FACE);        }    }    // Enable color writes.    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);    glStencilMask(0);    setGradientOps(cbrush, QRectF(QPointF(min_x, min_y), QSizeF(max_x - min_x, max_y - min_y)));    bool fast_fill = has_fast_composition_mode && (current_style == Qt::LinearGradientPattern || current_style == Qt::SolidPattern);    if (use_fragment_programs && !fast_fill) {        DEBUG_ONCE qDebug() << "QOpenGLPaintEnginePrivate: Drawing polygon using stencil method (fragment programs)";        QRectF rect(QPointF(min_x, min_y), QSizeF(max_x - min_x, max_y - min_y));        // Enable stencil func.        glStencilFunc(GL_NOTEQUAL, 0, stencilMask);        composite(rect);    } else {        DEBUG_ONCE qDebug() << "QOpenGLPaintEnginePrivate: Drawing polygon using stencil method (no fragment programs)";        // Enable stencil func.        glStencilFunc(GL_NOTEQUAL, 0, stencilMask);#ifndef Q_WS_QWS        glBegin(GL_QUADS);        glVertex2f(min_x, min_y);        glVertex2f(max_x, min_y);        glVertex2f(max_x, max_y);        glVertex2f(min_x, max_y);        glEnd();#endif    }    glStencilMask(~0);    glStencilFunc(GL_ALWAYS, 0, 0);    glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);    // clear all stencil values to 0    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);#ifndef Q_WS_QWS    glBegin(GL_QUADS);    glVertex2f(min_x, min_y);    glVertex2f(max_x, min_y);    glVertex2f(max_x, max_y);    glVertex2f(min_x, max_y);    glEnd();#endif    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);    // Disable stencil writes.    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);    glStencilMask(0);    glDisable(GL_STENCIL_TEST);}void QOpenGLPaintEnginePrivate::fillPath(const QPainterPath &path){    if (path.isEmpty())        return;    if (use_stencil_method && !high_quality_antialiasing) {        pathToVertexArrays(path);        fillVertexArray(path.fillRule());        return;    }    glMatrixMode(GL_MODELVIEW);    glLoadIdentity();    if (high_quality_antialiasing)        drawOffscreenPath(path);    else {        QPolygonF poly = path.toFillPolygon(matrix);        fillPolygon_dev(poly.data(), poly.count(),                        path.fillRule());    }    glMatrixMode(GL_MODELVIEW);#ifndef Q_WS_QWS    GLdouble mat[4][4];#else    GLfloat mat[4][4];#endif    QTransform mtx = matrix;    mat[0][0] = mtx.m11();    mat[0][1] = mtx.m12();    mat[0][2] = 0;    mat[0][3] = mtx.m13();    mat[1][0] = mtx.m21();    mat[1][1] = mtx.m22();    mat[1][2] = 0;    mat[1][3] = mtx.m23();    mat[2][0] = 0;    mat[2][1] = 0;    mat[2][2] = 1;    mat[2][3] = 0;    mat[3][0] = mtx.dx();    mat[3][1] = mtx.dy();    mat[3][2] = 0;    mat[3][3] = 1;#ifndef Q_WS_QWS    glLoadMatrixd(&mat[0][0]);#else    glLoadMatrixf(&mat[0][0]);#endif}void QOpenGLPaintEngine::updatePen(const QPen &pen){    Q_D(QOpenGLPaintEngine);    Qt::PenStyle pen_style = pen.style();    d->pen_brush_style = pen.brush().style();    d->cpen = pen;    d->has_pen = (pen_style != Qt::NoPen);    if (pen.isCosmetic()) {        GLfloat width = pen.widthF() == 0.0f ? 1.0f : pen.widthF();        glLineWidth(width);        glPointSize(width);    }    if (d->pen_brush_style >= Qt::LinearGradientPattern        && d->pen_brush_style <= Qt::ConicalGradientPattern)    {        d->setGLPen(Qt::white);    } else {  

⌨️ 快捷键说明

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