要在屏幕上绘制一些小图块,我应该使用 QQuickItem 还是 QQuickPaintedItem?
Posted
技术标签:
【中文标题】要在屏幕上绘制一些小图块,我应该使用 QQuickItem 还是 QQuickPaintedItem?【英文标题】:To paint some small tiles on the screen, should I use QQuickItem or QQuickPaintedItem? 【发布时间】:2020-01-30 10:21:45 【问题描述】:基本上我需要在内存中加载一个大小正好为 16K 的 4 色 tilemap,以每秒 3 次的速度对其中 2 个图块进行动画处理,然后将一些图块渲染到一个相当小的盒子中,我会说也许在 QML/Qt Quick 中显示大约 100 像素宽和 80 像素高(非常粗略地来自内存),我可能会使用 scale
属性在 QML 中将其放大
无论如何,我对如何做到这一点有点不知所措,但我认为 C++ 是最好的选择,这对我来说很好,在研究之后我发现有 2 个主要选项,QQuickItem 和 QQuickPaintedItem .
现在我知道 QQuickPaintedItem 更旧且更慢,因为它首先在 CPU 中绘制,然后再复制到视频卡,因此它不是最佳解决方案。最推荐的选项是 QQuickItem,它使用 OpenGL 在图形卡上呈现。
但我不需要过分的东西,我的意思是我在这里处理 ~100 x 80 像素,没有线条或形状操作,没有着色器,没有这些。这只是一堆像素,所以我想知道使用 QQuickPaintedItem 是否会更好。
但是对于所有这些我不知道可能有另一种解决方案,在这种情况下我很乐意听到它,也许有一个更简单的方法来解决所有这些问题。
任何帮助解决这个问题都会很棒,在此先感谢。
【问题讨论】:
您的意思是QSGNode
而不是QQuickItem
,因为QQuickPaintedItem
继承自QQuickItem
。或许this post可以帮到你一点?
我认为您应该先尝试使用QQuickPaintedItem
,然后使用setRenderTarget(FramebufferObject)
。这对于您的用例应该足够了。
其实我现在正在研究 QPixmap 或 QImage。我的意思是一旦我将它渲染到内存中它就不会改变,这是我认为 OpenGL 可能有点矫枉过正的另一个原因。问题是我不知道我是否可以使用 QPixmap 为这两个图块设置动画,或者我是否能够轻松提取图块。 -- 我真正需要的是内存中的图块(很少更改),我从这些图块构建第二个非常小的图像并将其发送到 Qt Quick。所以无论如何我可以这样做,但 Qt Quick 只会接收完成的图像(C++ 处理其余的并让它们都在内存中处于活动状态)
【参考方案1】:
像往常一样,我正在寻找适合我需要的最简单的解决方案,并且我找到了。
我创建了一个 TilesetEngine 类,它在 QImages 中加载图块(因为它非常简单),处理它们,然后将它们转换为 QPixmaps,在那里它们被分解成单独的图块并缓存在内存中以提高速度(微小的好处简单的 8x8 磁贴,没有内存占用)。该引擎允许您直接请求帧号,它会使用与请求的帧号匹配的动画图块来渲染静态图像。
那是困难的部分,因为有相当多的处理和后处理,但是我创建了一个 QQuickImageProvider 作为一种松散的桥梁,并允许在“id”中提供额外的选项" 例如在 id 中指定比例大小,因为 Qt Quick 没有调用 const QSize& requestedSize
。这很容易做到。
注册到 QML 后,我只需放入一个 id 字符串,id 字符串指定我希望引擎如何从动画帧渲染图块集的所有选项、某些叠加层、哪个图块集等……以及id 字符串还告诉提供者我是想要缩放它还是想要整个tileset 图像还是只想要一个tile id。这也超级简单有趣。
然后为了更有趣,我在 QML 中加入了一个计时器,并一一请求动画中的所有帧并让它循环播放。在这里,我可以观看动画和图块集,或者图块变得栩栩如生。
整个过程非常简单、简单且充满乐趣。唯一困难的部分是引擎,它在像素处理方面非常坚韧,但 QImage、QPaint、QPixelmap 和 QColor 完成了大部分工作,所以如果不是 Qt 的便利类,它可能会更加困难。
我很高兴我从来没有破坏过任何 OpenGL 的东西或我最初的计划,QQuickItem 或 QQuickPainted Item。这个解决方案完美而简单,适合我需要做的所有事情,
【讨论】:
以上是关于要在屏幕上绘制一些小图块,我应该使用 QQuickItem 还是 QQuickPaintedItem?的主要内容,如果未能解决你的问题,请参考以下文章