C++ Qt/C++;:高效绘图
我设计了一个程序,基本上,将一个几何形状切割成许多小三角形(在“左画布”中),对这组三角形应用一些简单的数学变换,并以新的配置重新绘制它们。请参阅下面的屏幕截图 为了绘制这些三角形,我使用C++ Qt/C++;:高效绘图,c++,qt,graphics,pixel,qpainter,C++,Qt,Graphics,Pixel,Qpainter,我设计了一个程序,基本上,将一个几何形状切割成许多小三角形(在“左画布”中),对这组三角形应用一些简单的数学变换,并以新的配置重新绘制它们。请参阅下面的屏幕截图 为了绘制这些三角形,我使用qPaint::drawPolygon。右边的每个三角形对应左边的一个三角形,所以我知道我想用什么颜色来画它 到目前为止还不错。即使我画了更多的三角形(当我使用更小的三角形来切割形状时),这也足够快了 我在程序中添加了一个功能:我可以绘制从图片中提取的三角形,而不是普通三角形:请参见下面的屏幕截图 问题是我
qPaint::drawPolygon
。右边的每个三角形对应左边的一个三角形,所以我知道我想用什么颜色来画它
到目前为止还不错。即使我画了更多的三角形(当我使用更小的三角形来切割形状时),这也足够快了
我在程序中添加了一个功能:我可以绘制从图片中提取的三角形,而不是普通三角形:请参见下面的屏幕截图
问题是我这样做太慢了。我是这样做的:
qpaint::setPen(QColor)
和qpaint::drawPoint(QPoint)
来绘制像素paintEvent
大约需要0.15秒,而普通三角形则需要0.01秒)
我运行了一个分析器试图了解发生了什么,我注意到在画布小部件的paintEvent
中
QPainter::drawPoint
QPainter::setPen
QPainter::drawPoint
太复杂太慢了:我只想让它打印一个给定颜色的像素,就是这样
我可能已经找到了解决问题的方法:存储一个QImage
(作为画布小部件的成员变量),它代表我希望画布显示的全部内容,并在我的paintEvent
逐像素中完全定义它,然后使用qPaint::drawImage
在我的paintEvent
结束时立即绘制它。我有一个暗示,这会快得多。但在我重新编写代码之前,我想知道这是否真的是我想要做的
我希望我没有让你厌烦去死!非常感谢您的见解。OpenGL将图像(纹理)坐标映射做得非常好。您可能想使用某种形式的OpenGL。Qt与OpenGL有一些绑定,可以帮助您解决问题。一种方法是使用从QGLWidget继承的类,而不是QGraphicscene/QGraphicsView组合。不幸的是,OpenGL的学习曲线开始时有点陡峭。然而,这将是非常快的,因为它将直接发生在为这种操作而优化的图形卡上。
您将加载图像
QGLWidget::bindTexture()
将图像中的点与三角形网格关联,并将它们全部发送到图形卡。在OpenGL的旧版本中(在我看来,它比较新的API更容易使用),它看起来像这样:
glEnable(GL_TEXTURE_2D);
glBegin(GL_TRIANGLES);
for (int ii=0;ii<triangle.size();++ii) {
for (int jj=0;jj<3;++jj) {
glTexCoord2d(triangle[ii].tex[jj][0],triangle[ii].tex[jj][1]);
glVertex2d(triangle[ii].point[jj[0],triangle[ii].point[jj][1]);
}
}
glEnd();
glEnable(GL_纹理_2D);
glBegin(GL_三角形);
对于(int ii=0;ii非OpenGl解决方案:
为目标图像使用RGB缓冲区。像以前一样完成前3个步骤。
一旦你找到了位置和像素颜色,你就在这个缓冲区上设置它
QImage::QImage ( uchar * data, int width, int height, Format format )
基于上一个缓冲区构造映像。它与您提供的解决方案非常接近
而且比你现在拥有的要快得多。除了OpenGL之外的另一个选择是使用OpenCL,这对你来说可能更容易。你只需要将输入/输出位图内存映射到图形卡,用C编写一个处理一个三角形的小内核,然后为每个三角形排队内核执行。这将尽可能多地工作100倍于CPU上单个内核的速度
这里有一个OpenCL主机api的Qt包装器:
另一种方法是利用光栅绘制引擎中已经有效实现的剪裁和变换。只要两个三角形之间的变换可以使用3x3增强变换矩阵表示,您只需在目标绘制器上设置它,然后绘制整个源图像n目标。它将被剪裁和变换以填充目标三角形。如果分析显示其优势,您也可以仅绘制源三角形的边界矩形,而不是整个图像
这可以被并行化,这样你就可以像处理CPU核心一样并行处理尽可能多的三角形。+1同意,OP似乎正在创建一个UV映射应用程序,OpenGL是实现这一点的完美工具。谢谢你的回答!我肯定有一天会研究这个问题。问题是我对OpenGL一无所知。你正在逐像素绘制???(zomg!!)非常感谢您的回答!这非常有趣。“不幸的是,OpenGL的学习曲线开始时有点陡峭”。我想这是我的问题!但我可能需要在某个时候了解它。这使用了不推荐使用的代码。你真的想使用着色器和纹理采样器。@doron不推荐使用它。但是如果固定管道功能可以完成这项工作,那么这样做会容易得多。GLSL只会增加学习3d编程的难度。它提供了更多的灵活性,但汇编代码也是如此。尽管如此,我们大多数人在汇编中没有编写太多程序是有原因的。非常感谢!我可能会使用它(直到有一天我了解了OpenGL)。我确认,这对我所做的一切都是好的!(paintEvent in max 0.04s)