Beispiel #1
0
void QGLPixmapConvolutionFilter::setUniforms(QGLShaderProgram *program)
{
    const qreal *kernel = convolutionKernel();
    int kernelWidth = columns();
    int kernelHeight = rows();
    int kernelSize = kernelWidth * kernelHeight;

    QVarLengthArray<GLfloat> matrix(kernelSize);
    QVarLengthArray<GLfloat> offset(kernelSize * 2);

    for(int i = 0; i < kernelSize; ++i)
        matrix[i] = kernel[i];

    for(int y = 0; y < kernelHeight; ++y) {
        for(int x = 0; x < kernelWidth; ++x) {
            offset[(y * kernelWidth + x) * 2] = x - (kernelWidth / 2);
            offset[(y * kernelWidth + x) * 2 + 1] = (kernelHeight / 2) - y;
        }
    }

    const qreal iw = 1.0 / m_srcSize.width();
    const qreal ih = 1.0 / m_srcSize.height();
    program->setUniformValue("inv_texture_size", iw, ih);
    program->setUniformValueArray("matrix", matrix.constData(), kernelSize, 1);
    program->setUniformValueArray("offset", offset.constData(), kernelSize, 2);
}
void QVGPixmapConvolutionFilter::draw
        (QPainter *painter, const QPointF &dest,
         const QPixmap &src, const QRectF &srcRect) const
{
    if (src.isNull())
        return;

    if (src.pixmapData()->classId() != QPixmapData::OpenVGClass) {
        // The pixmap data is not an instance of QVGPixmapData, so fall
        // back to the default convolution filter implementation.
        QPixmapConvolutionFilter::draw(painter, dest, src, srcRect);
        return;
    }

    QVGPixmapData *pd = static_cast<QVGPixmapData *>(src.pixmapData());

    VGImage srcImage = pd->toVGImage();
    if (srcImage == VG_INVALID_HANDLE)
        return;

    QSize size = pd->size();
    VGImage dstImage = QVGImagePool::instance()->createTemporaryImage
        (VG_sARGB_8888_PRE, size.width(), size.height(),
         VG_IMAGE_QUALITY_FASTER, pd);
    if (dstImage == VG_INVALID_HANDLE)
        return;

    int kernelWidth = rows();
    int kernelHeight = columns();
    const qreal *kern = convolutionKernel();
    QVarLengthArray<VGshort> kernel;
    for (int i = 0; i < kernelWidth; ++i) {
        for (int j = 0; j < kernelHeight; ++j) {
            kernel.append((VGshort)(kern[j * kernelWidth + i] * 1024.0f));
        }
    }

    VGfloat values[4];
    values[0] = 0.0f;
    values[1] = 0.0f;
    values[2] = 0.0f;
    values[3] = 0.0f;
    vgSetfv(VG_TILE_FILL_COLOR, 4, values);

    vgConvolve(dstImage, srcImage,
               kernelWidth, kernelHeight, 0, 0,
               kernel.constData(), 1.0f / 1024.0f, 0.0f,
               VG_TILE_FILL);

    VGImage child = VG_INVALID_HANDLE;

    if (srcRect.isNull() ||
        (srcRect.topLeft().isNull() && srcRect.size() == size)) {
        child = dstImage;
    } else {
        QRect src = srcRect.toRect();
        child = vgChildImage(dstImage, src.x(), src.y(), src.width(), src.height());
    }

    qt_vg_drawVGImage(painter, dest, child);

    if(child != dstImage)
        vgDestroyImage(child);
    QVGImagePool::instance()->releaseImage(0, dstImage);
}