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

📄 qpaintengine_opengl.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
public:    QGLOffscreen()        : QObject(),          offscreen(0),          ctx(0),          mask_dim(0),          activated(false),          bound(false)    {        connect(QGLProxy::signalProxy(),                SIGNAL(aboutToDestroyContext(const QGLContext *)),                SLOT(cleanupGLContextRefs(const QGLContext *)));    }    inline void setDevice(QPaintDevice *pdev);    void begin();    void end();    inline void bind();    inline void release();    inline bool isBound() const;    inline QSize drawableSize() const;    inline QSize offscreenSize() const;    inline GLuint offscreenTexture() const;    QGLContext *context() const;    static bool isSupported();    inline void initialize();    inline bool isValid() const;public Q_SLOTS:    void cleanupGLContextRefs(const QGLContext *context) {        if (context == ctx)            ctx = 0;    }private:    QGLDrawable drawable;    QGLFramebufferObject *offscreen;    QGLContext *ctx;    // dimensions of mask texture (square)    int mask_dim;    QSize last_failed_size;    bool drawable_fbo;    bool activated;    bool initialized;    bool bound;};inline void QGLOffscreen::setDevice(QPaintDevice *pdev){    drawable.setDevice(pdev);    drawable_fbo = (pdev->devType() == QInternal::FramebufferObject);}void QGLOffscreen::begin(){#ifndef Q_WS_QWS    initialized = false;    if (activated)        initialize();#endif}void QGLOffscreen::initialize(){#ifndef Q_WS_QWS    if (initialized)        return;    activated = true;    initialized = true;    int dim = qMax(2048, static_cast<int>(qt_next_power_of_two(qMax(drawable.size().width(), drawable.size().height()))));    bool shared_context = qgl_share_reg()->checkSharing(drawable.context(), ctx);    bool would_fail = last_failed_size.isValid() &&                      (drawable.size().width() >= last_failed_size.width() ||                       drawable.size().height() >= last_failed_size.height());    bool needs_refresh = dim > mask_dim || !shared_context;    if (needs_refresh && !would_fail) {        DEBUG_ONCE qDebug() << "QGLOffscreen::initialize(): creating offscreen of size" << dim;        delete offscreen;        offscreen = new QGLFramebufferObject(dim, dim);        mask_dim = dim;        if (!offscreen->isValid()) {            qWarning("QGLOffscreen: Invalid offscreen fbo (size %dx%d)", mask_dim, mask_dim);            delete offscreen;            offscreen = 0;            mask_dim = 0;            last_failed_size = drawable.size();        }    }    qt_mask_texture_cache()->setOffscreenSize(offscreenSize());    qt_mask_texture_cache()->setDrawableSize(drawable.size());    ctx = drawable.context();#endif}inline bool QGLOffscreen::isValid() const{    return offscreen;}void QGLOffscreen::end(){    if (bound)        release();#ifdef DEBUG_DISPLAY_MASK_TEXTURE    glDisable(GL_FRAGMENT_PROGRAM_ARB);    glReadBuffer(GL_BACK);    glDrawBuffer(GL_BACK);    glMatrixMode(GL_MODELVIEW);    glLoadIdentity();    glColor4f(1, 1, 1, 1);    glDisable(GL_DEPTH_TEST);    glBlendFunc(GL_ONE, GL_ZERO);    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);    glEnable(GL_TEXTURE_2D);    glBindTexture(GL_TEXTURE_2D, offscreen->texture());    glBegin(GL_QUADS);    glTexCoord2f(0.0, 1.0); glVertex2f(0.0, 0.0);    glTexCoord2f(1.0, 1.0); glVertex2f(drawable.size().width(), 0.0);    glTexCoord2f(1.0, 0.0); glVertex2f(drawable.size().width(), drawable.size().height());    glTexCoord2f(0.0, 0.0); glVertex2f(0.0, drawable.size().height());    glEnd();    glBindTexture(GL_TEXTURE_2D, 0);    glDisable(GL_TEXTURE_2D);#endif}inline void QGLOffscreen::bind(){#ifndef Q_WS_QWS    Q_ASSERT(initialized);    if (!offscreen || bound)        return;    DEBUG_ONCE qDebug() << "QGLOffscreen: binding offscreen";    offscreen->bind();    bound = true;    glViewport(0, 0, offscreenSize().width(), offscreenSize().height());    glMatrixMode(GL_PROJECTION);    glLoadIdentity();    glOrtho(0, offscreenSize().width(), offscreenSize().height(), 0, -999999, 999999);    glMatrixMode(GL_MODELVIEW);#endif}inline void QGLOffscreen::release(){#ifndef Q_WS_QWS    if (!offscreen || !bound)        return;#ifdef Q_WS_X11    // workaround for bug in nvidia driver versions 9x.xx    if (QGLExtensions::nvidiaFboNeedsFinish)        glFinish();#endif    DEBUG_ONCE_STR("QGLOffscreen: releasing offscreen");    if (drawable_fbo)        drawable.makeCurrent();    else        offscreen->release();    QSize sz(drawable.size());    glViewport(0, 0, sz.width(), sz.height());    glMatrixMode(GL_PROJECTION);    glLoadIdentity();    glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999);    glMatrixMode(GL_MODELVIEW);    bound = false;#endif}inline bool QGLOffscreen::isBound() const{    return bound;}inline QSize QGLOffscreen::drawableSize() const{    return drawable.size();}inline QSize QGLOffscreen::offscreenSize() const{    return QSize(mask_dim, mask_dim);}inline GLuint QGLOffscreen::offscreenTexture() const{    return offscreen ? offscreen->texture() : 0;}inline QGLContext *QGLOffscreen::context() const{    return ctx;}bool QGLOffscreen::isSupported(){    return (QGLExtensions::glExtensions & QGLExtensions::FramebufferObject) // for fbo        && (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0); // non-power-of-two textures}struct QDrawQueueItem{    QDrawQueueItem(qreal _opacity,                   QBrush _brush,                   const QPointF &_brush_origion,                   QPainter::CompositionMode _composition_mode,                   const QTransform &_matrix,                   QGLMaskTextureCache::CacheLocation _location)        : opacity(_opacity),          brush(_brush),          brush_origin(_brush_origion),          composition_mode(_composition_mode),          matrix(_matrix),          location(_location) {}    qreal opacity;    QBrush brush;    QPointF brush_origin;    QPainter::CompositionMode composition_mode;    QTransform matrix;    QGLMaskTextureCache::CacheLocation location;};class QOpenGLPaintEnginePrivate;class QGLPrivateCleanup : public QObject{    Q_OBJECTpublic:    QGLPrivateCleanup(QOpenGLPaintEnginePrivate *priv)        : p(priv)    {        connect(QGLProxy::signalProxy(),                SIGNAL(aboutToDestroyContext(const QGLContext *)),                SLOT(cleanupGLContextRefs(const QGLContext *)));    }public Q_SLOTS:    void cleanupGLContextRefs(const QGLContext *context);private:    QOpenGLPaintEnginePrivate *p;};class QOpenGLPaintEnginePrivate : public QPaintEnginePrivate{    Q_DECLARE_PUBLIC(QOpenGLPaintEngine)public:    QOpenGLPaintEnginePrivate()        : opacity(1)        , composition_mode(QPainter::CompositionMode_SourceOver)        , has_fast_pen(false)        , txop(QTransform::TxNone)        , inverseScale(1)        , moveToCount(0)        , shader_ctx(0)        , grad_palette(0)        , use_stencil_method(false)        , has_stencil_face_ext(false)        , use_fragment_programs(false)        , high_quality_antialiasing(false)        , drawable_texture(0)        , ref_cleaner(this)        {}    inline void setGLPen(const QColor &c) {        uint alpha = qRound(c.alpha() * opacity);        pen_color[0] = (c.red() * alpha + 128) >> 8;        pen_color[1] = (c.green() * alpha + 128) >> 8;        pen_color[2] = (c.blue() * alpha + 128) >> 8;        pen_color[3] = alpha;    }    inline void setGLBrush(const QColor &c) {        uint alpha = qRound(c.alpha() * opacity);        brush_color[0] = (c.red() * alpha + 128) >> 8;        brush_color[1] = (c.green() * alpha + 128) >> 8;        brush_color[2] = (c.blue() * alpha + 128) >> 8;        brush_color[3] = alpha;    }    inline void setGradientOps(const QBrush &brush, const QRectF &bounds);    void createGradientPaletteTexture(const QGradient& g);    void updateGradient(const QBrush &brush, const QRectF &bounds);    inline void lineToStencil(qreal x, qreal y);    inline void curveToStencil(const QPointF &cp1, const QPointF &cp2, const QPointF &ep);    void pathToVertexArrays(const QPainterPath &path);    void fillVertexArray(Qt::FillRule fillRule);    void drawVertexArrays();    void fillPath(const QPainterPath &path);    void fillPolygon_dev(const QPointF *polygonPoints, int pointCount,                         Qt::FillRule fill);    void drawFastRect(const QRectF &rect);    void strokePath(const QPainterPath &path, bool use_cache);    void strokePathFastPen(const QPainterPath &path, bool needsResolving);    void strokeLines(const QPainterPath &path);    void cleanupGLContextRefs(const QGLContext *context) {        if (context == shader_ctx)            shader_ctx = 0;    }    QPen cpen;    QBrush cbrush;    QRegion crgn;    Qt::BrushStyle brush_style;    QPointF brush_origin;    Qt::BrushStyle pen_brush_style;    qreal opacity;    QPainter::CompositionMode composition_mode;    Qt::BrushStyle current_style;    uint has_clipping : 1;    uint has_pen : 1;    uint has_brush : 1;    uint has_fast_pen : 1;    QTransform matrix;    GLubyte pen_color[4];    GLubyte brush_color[4];    QTransform::TransformationType txop;    QGLDrawable drawable;    QGLOffscreen offscreen;    qreal inverseScale;    int moveToCount;    QPointF path_start;    bool isFastRect(const QRectF &r);    void drawImageAsPath(const QRectF &r, const QImage &img, const QRectF &sr);    void drawTiledImageAsPath(const QRectF &r, const QImage &img);    void drawOffscreenPath(const QPainterPath &path);    void composite(const QRectF &rect, const QPoint &maskOffset = QPoint());    void composite(GLuint primitive, const float *vertexArray, int vertexCount, const QPoint &maskOffset = QPoint());    bool createFragmentPrograms();    void deleteFragmentPrograms();    void updateFragmentProgramData(int locations[]);    void cacheItemErased(int channel, const QRect &rect);    void addItem(const QGLMaskTextureCache::CacheLocation &location);    void drawItem(const QDrawQueueItem &item);    void flushDrawQueue();    void copyDrawable(const QRectF &rect);    QGLContext *shader_ctx;    GLuint grad_palette;    GLuint painter_fragment_programs[num_fragment_brushes][num_fragment_composition_modes];    GLuint mask_fragment_programs[num_fragment_masks];    bool use_stencil_method;    bool has_stencil_face_ext;    bool use_fragment_programs;    bool high_quality_antialiasing;    float inv_matrix_data[3][4];    float fmp_data[4];    float fmp2_m_radius2_data[4];    float angle_data[4];    float linear_data[4];    float porterduff_ab_data[4];    float porterduff_xyz_data[4];    float mask_offset_data[4];    float mask_channel_data[4];    FragmentBrushType fragment_brush;    FragmentCompositionModeType fragment_composition_mode;    bool has_fast_composition_mode;    void setPorterDuffData(float a, float b, float x, float y, float z);    void setInvMatrixData(const QTransform &inv_matrix);    qreal max_x;    qreal max_y;    qreal min_x;

⌨️ 快捷键说明

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