gpt4 book ai didi

c++ - 是否可以使用自定义图形引擎渲染 Qt QWidgets 和 QML?

转载 作者:太空狗 更新时间:2023-10-29 23:13:21 25 4
gpt4 key购买 nike

我有一些项目对使用 QML ui 很感兴趣。但是我们使用标准的 Qt 渲染系统是不够的,我必须尝试在每一帧重绘所有 ui 元素,而不仅仅是在 QCoreApplication::processEvents() 中。

它是 requered 因为它是 ui 背景中的一些 DirectX 渲染。

在这种情况下,我找到了只使用 QWidget::render() 函数来渲染小部件的方法,但是这种方法使用 CPU 而不是 GPU,所以它太慢而且根本不正确。

所以,我有:

  1. 我已将 QApplication 集成到我的应用程序循环中。Signals/Slots 系统工作正常并且处理事件被正确调用方法。
  2. 自己的 DirectX11 渲染系统,我用它来渲染其他 图形。

我需要重绘(更新)qt(QML)ui每一帧使用 DirectX,或者角度,但渲染的每一帧。

已有的代码示例:在此示例中,重新实现的小部件是应用程序的主窗口,并用作 DirectX 渲染的上下文。

标题:

#ifndef _QTD3DCONTEXTWIDGET_
#define _QTD3DCONTEXTWIDGET_

#include <QtWidgets/QWidget>
#include <QtQuick/QQuickView>
#include <QtQuickWidgets/QQuickWidget>
#include <QtQml/qqml.h>
#include <QtWidgets/QPushButton>

#include <QtGui/QPaintEngine>
#include <QtGui/QPaintDevice>

class QtGfxPaintEngine : public QPaintEngine
{
public:
QtGfxPaintEngine(PaintEngineFeatures caps = PaintEngineFeatures());

virtual bool begin(QPaintDevice *pdev);
virtual bool end();
//virtual void drawEllipse(const QRectF &rect);
//virtual void drawEllipse(const QRect &rect);
virtual void drawImage(const QRectF &rectangle,
const QImage &image,
const QRectF &sr,
Qt::ImageConversionFlags flags = Qt::AutoColor);

virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
virtual void drawPoints(const QPointF *points, int pointCount);
virtual void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
virtual void drawRects(const QRectF *rects, int rectCount);
virtual void drawTextItem(const QPointF &p, const QTextItem &textItem);
virtual void drawTiledPixmap(const QRectF &rect, const QPixmap &pixmap, const QPointF &p);
// default implementation used
//virtual void drawLines(const QLineF *lines, int lineCount); //not
//virtual void drawLines(const QLine *lines, int lineCount);
//virtual void drawPath(const QPainterPath &path);
//virtual void drawPoints(const QPoint *points, int pointCount);
//virtual void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode);
//virtual void drawRects(const QRect *rects, int rectCount);

virtual Type type() const;
virtual void updateState(const QPaintEngineState &newState);
private:
int getClosestPowOfTwo(QSize& size);
};

class QtD3DContextWidget : public QWidget
{
Q_OBJECT
public:
QtD3DContextWidget(QWidget* parent = nullptr);
virtual ~QtD3DContextWidget() = default;
virtual QPaintEngine* paintEngine() const;


virtual void paintEvent(QPaintEvent* event);

void mousePressEvent(QMouseEvent *event) override;

QQuickWidget* containerWidget;
QPushButton* widg;
QtGfxPaintEngine* mPaintEngine;
private:

};

#endif // !_QTD3DCONTEXTWIDGET_

cpp,没有绘制函数(它们是用 DirectX 实现的并且工作正常):

QtD3DContextWidget::QtD3DContextWidget(QWidget* parent /*= nullptr*/)
: QWidget(parent, Qt::MSWindowsOwnDC)
{
mPaintEngine = new QtGfxPaintEngine(QPaintEngine::AllFeatures);

QApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
setAttribute(Qt::WA_NativeWindow, true);
setAttribute(Qt::WA_TranslucentBackground, true);
setAttribute(Qt::WA_UpdatesDisabled, true);
setAttribute(Qt::WA_TransparentForMouseEvents);
setAttribute(Qt::WA_NoSystemBackground, true);
setAttribute(Qt::WA_OpaquePaintEvent, true);

containerWidget = new QQuickWidget(this);
containerWidget->setAttribute(Qt::WA_TranslucentBackground, true);
containerWidget->setAttribute(Qt::WA_OpaquePaintEvent, true);
containerWidget->setAttribute(Qt::WA_NoSystemBackground, true);
containerWidget->setClearColor(Qt::transparent);

QString sourceUi = QCoreApplication::applicationDirPath() + "/qtui/test.qml";
containerWidget->setSource(QUrl::fromLocalFile(sourceUi));
containerWidget->move(0, 0);

resize(1280, 720);

widg = new QPushButton("test", this);
//widg->setBackgroundRole(QPalette::WindowText);
widg->resize(50, 50);
widg->move(600, 300);
widg->show();
show();
setVisible(true);
//wrapper->show();

}

QPaintEngine* QtD3DContextWidget::paintEngine() const
{
return mPaintEngine;
}

void QtD3DContextWidget::paintEvent(QPaintEvent* event)
{

}


QtGfxPaintEngine::QtGfxPaintEngine(PaintEngineFeatures caps /*= PaintEngineFeatures()*/)
: QPaintEngine(caps)
{}

QPaintEngine::Type QtGfxPaintEngine::type() const
{
return QPaintEngine::Direct3D;
}

void QtGfxPaintEngine::updateState(const QPaintEngineState &newState)
{}

并在 render ui 方法中:

QPainter painter(w);
painter.setBrushOrigin(w->containerWidget->pos());
w->containerWidget->render(&painter);// , w->widg->pos());// , w->widg->rect());// , QWidget::DrawChildren);
painter.end();

这工作正常,但使用 CPU。

我尝试将其替换为

w->repaint();

所以整个小部件都被重新绘制,但不是每一帧,在这种情况下,ui 正在“闪烁”并且小部件尝试重新绘制它的背景,而不是透明的,而是白色。

或替换为

w->containerWidget->repaint();

什么都没有发生。

在 w->repaint() 之后尝试调用 QApplication::process 事件没有意义,正如我所见。

当然我已经评论了 setAttribute(Qt::WA_UpdatesDisabled, true);如果我尝试以这种方式刷新小部件。

PS:对不起我的英语)))

最佳答案

如果您想通过中央渲染器渲染所有 Qt 内容,那么您最好实现自己的 QPA(Qt 平台抽象)插件,基于或派生自普通 Windows QPA 插件。

然后你可以 (a) 从那里分发你的绘画设备实现,不需要任何应用程序端代码,并可能使用像 ANGLE 这样的东西来获得通过 Direct3D 渲染的 QtQuick 场景图

关于c++ - 是否可以使用自定义图形引擎渲染 Qt QWidgets 和 QML?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40044276/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com