Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Qt/C++;:高效绘图_C++_Qt_Graphics_Pixel_Qpainter - Fatal编程技术网

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)
    来绘制像素
  • 我对Qt编程还不熟悉,对图形一无所知,所以我能想到的就是这个。问题是它的速度“令人无法接受”太慢(每个画布的
    paintEvent
    大约需要0.15秒,而普通三角形则需要0.01秒)

    我运行了一个分析器试图了解发生了什么,我注意到在画布小部件的
    paintEvent

  • 58%的时间花在
    QPainter::drawPoint
  • 27%的时间花在
    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)