我正在尝试将Skia与QML结合使用。我从QQuickPaintedItem
继承。我已经修改了示例http://doc.qt.io/qt-5/qtquick-customitems-painteditem-example.html,以将QQuickPaintedItem::FramebufferObject
用作renderTarget
。我正在尝试根据SkSurface
的现有纹理创建QQuickPaintedItem
。我总是空着。请让我知道是否可以使用QML项目中的现有纹理并将其用于Skia渲染。
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "textballoon.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
qmlRegisterType<TextBalloon>("com.sanjay.check", 1, 0, "TextBalloon");
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
project.pro文件
QT += quick
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
textballoon.cpp
RESOURCES += qml.qrc
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =
# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
HEADERS += \
textballoon.h
INCLUDEPATH +=\
/home/sanju/skia/include/core \
/home/sanju/skia/src/core \
/home/sanju/skia/include/private \
/home/sanju/skia/include/config \
#/home/sanju/skia/tools/ \
/home/sanju/skia/include/gpu \
/home/sanju/skia/src/gpu \
/home/sanju/skia/src/gpu/gl \
#/home/sanju/skia/include/effects \
/home/sanju/skia/include/encode \
/home/sanju/skia/include/utils \
unix:!macx: LIBS += -L$$PWD/../../skia/out/Release/ -lskia
INCLUDEPATH += $$PWD/../../skia/out/Release
DEPENDPATH += $$PWD/../../skia/out/Release
这是我修改后的textballoon.cpp文件
#include "GrContext.h"
#include "gl/GrGLTypes.h"
//#include "GrGLTexture.h"
#include "textballoon.h"
#include "gl/GrGLInterface.h"
#include "SkData.h"
#include "SkImage.h"
#include "SkStream.h"
#include "SkSurface.h"
//#include "GrGpu.h"
#include "GrBackendSurface.h"
//#include "GrContextPriv.h"
//#include "GrGpu.h"
#include <QtDebug>
//! [0]
TextBalloon::TextBalloon(QQuickItem *parent)
: QQuickPaintedItem(parent)
, rightAligned(false)
{
setRenderTarget(QQuickPaintedItem::FramebufferObject);
setRightAligned(true);
QObject::connect(this, &QQuickPaintedItem::widthChanged, this, [this]() {
// qDebug() << "textureChanged";
this->dirty = true;
});
}
//! [0]
//! [1]
void TextBalloon::paint(QPainter *painter)
{
QBrush brush(QColor("#007430"));
painter->setBrush(brush);
painter->setPen(Qt::NoPen);
painter->setRenderHint(QPainter::Antialiasing);
QSizeF itemSize = size();
painter->drawRoundedRect(0, 0, itemSize.width(), itemSize.height() - 10, 10, 10);
if (rightAligned)
{
const QPointF points[3] = {
QPointF(itemSize.width() - 10.0, itemSize.height() - 10.0),
QPointF(itemSize.width() - 20.0, itemSize.height()),
QPointF(itemSize.width() - 30.0, itemSize.height() - 10.0),
};
painter->drawConvexPolygon(points, 3);
}
else
{
const QPointF points[3] = {
QPointF(10.0, itemSize.height() - 10.0),
QPointF(20.0, itemSize.height()),
QPointF(30.0, itemSize.height() - 10.0),
};
painter->drawConvexPolygon(points, 3);
}
if(textureProvider())
{
sk_sp<const GrGLInterface> interface = nullptr;
// Leaving interface as null makes Skia extract pointers to OpenGL functions for the current
// context in a platform-specific way. Alternatively, you may create your own GrGLInterface and
// initialize it however you like to attach to an alternate OpenGL implementation or intercept
// Skia's OpenGL calls.
sk_sp<GrContext> context = GrContext::MakeGL(interface);
if (!context) {
SkDebugf("GrContext::MakeGL returned null\n");
}
// GrGpu* gpu = context->contextPriv().getGpu();
QSGTexture* texture = textureProvider()->texture();
if(texture)
{
qDebug() << "Texture exist";
QSurfaceFormat format = QSurfaceFormat::defaultFormat();
QSize size = texture->textureSize();
qDebug() << size;
qDebug() << "Texture id " << texture->textureId() << " alpha channel " << texture->hasAlphaChannel()
<< "FORMAT RGB" << format.depthBufferSize() << " sample size " << format.samples();
GrGLTextureInfo info;
info.fID = texture->textureId();
info.fFormat = SkColorType::kUnknown_SkColorType;
GrBackendTexture grTexture(size.width(),
size.height(),
texture->hasMipmaps()? GrMipMapped::kYes : GrMipMapped::kNo,
info);
GrGLFramebufferInfo fboInfo;
fboInfo.fFBOID = texture->textureId();
auto surface = SkSurface::MakeFromBackendTexture(context.get(),
grTexture,
GrSurfaceOrigin::kTopLeft_GrSurfaceOrigin,
0,
SkColorType::kUnknown_SkColorType,
nullptr,
nullptr);
// GrGLFramebufferInfo fboInfo;
// fboInfo.fFBOID = texture->textureId();
// GrBackendRenderTarget backendTarget(size.width(),
// size.height(),
// 0,
// 0,
// fboInfo);
// auto surface = SkSurface::MakeFromBackendRenderTarget(context.get(),
// backendTarget,
// GrSurfaceOrigin::kTopLeft_GrSurfaceOrigin,
// SkColorType::kUnknown_SkColorType,
// nullptr,
// nullptr);
if(surface)
{
qDebug() << "Surface created";
}
}
}
}
//! [1]
bool TextBalloon::isRightAligned()
{
return this->rightAligned;
}
void TextBalloon::setRightAligned(bool rightAligned)
{
this->rightAligned = rightAligned;
}