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); }