- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在编写一个粒子引擎并注意到它比它应该的慢得多(我已经编写了高度未优化的 3D C++ 粒子引擎,可以以 60 fps 渲染 50k 粒子,这个下降到 32 fps 大约1.2k ..),我对代码进行了一些分析,假设粒子渲染或旋转是 CPU 最密集的操作,但我发现实际上图形对象的这两个小属性实际上占用了 70% 以上我的表现....
public void RotateParticle(Graphics g, RectangleF r,
RectangleF rShadow, float angle,
Pen particleColor, Pen particleShadow)
{
//Create a matrix
Matrix m = new Matrix();
PointF shadowPoint = new PointF(rShadow.Left + (rShadow.Width / 1),
rShadow.Top + (rShadow.Height / 1));
PointF particlePoint = new PointF(r.Left + (r.Width / 1),
r.Top + (r.Height / 2));
//Angle of the shadow gets set to the angle of the particle,
//that way we can rotate them at the same rate
float shadowAngle = angle;
m.RotateAt(shadowAngle, shadowPoint);
g.Transform = m;
//rotate and draw the shadow of the Particle
g.DrawRectangle(particleShadow, rShadow.X, rShadow.Y, rShadow.Width, rShadow.Height);
//Reset the matrix for the next draw and dispose of the first matrix
//NOTE: Using one matrix for both the shadow and the partice causes one
//to rotate at half the speed of the other.
g.ResetTransform();
m.Dispose();
//Same stuff as before but for the actual particle
Matrix m2 = new Matrix();
m2.RotateAt(angle, particlePoint);
//Set the current draw location to the rotated matrix point
//and draw the Particle
g.Transform = m2;
g.DrawRectangle(particleColor, r.X, r.Y, r.Width, r.Height);
m2.Dispose();
}
阻碍我表现的特别是这些行:
g.Transform = m;
g.Transform = m2;
一点背景知识,图形对象是从 painteventargs 中获取的,然后在渲染粒子方法中将粒子渲染到屏幕上,该方法调用此方法进行任何旋转,多线程不是解决方案,因为图形对象不能在多个线程之间共享。这是我运行的代码分析的链接,您也可以看到发生了什么:
https://gyazo.com/229cfad93b5b0e95891eccfbfd056020
我有点认为这是无能为力的事情,因为看起来属性本身正在破坏性能,而不是我实际做过的任何事情(尽管我确信还有改进的余地),尤其是因为类调用的 dll 使用最多的 cpu 能力。无论如何,在尝试优化此方面的任何帮助将不胜感激...也许我会启用/禁用旋转以提高性能,我们会看到...
最佳答案
好吧,您应该为看到的配置文件结果挠头一会儿。当您分配 Transform 属性时,else 发生了一些事情。您可以通过注意到 ResetTransform() 不花费任何费用来推断出一些事情。当然没有意义,该方法还会更改 Transform 属性。
请注意,DrawRectangle() 应该是最昂贵的方法,因为这是实际将踏板踩到金属上并生成真实绘图命令的方法。我们无法从您的屏幕截图中看到它的成本,不能超过 30%。这还远远不够。
我认为您在这里看到的是 GDI/plus 的一个不起眼的功能,它批处理 绘图命令。换句话说,它在内部生成一个绘图命令列表,并且在必要时才将它们传递给视频驱动程序。 native winapi 具有明确强制刷新该列表的函数,它是 GdiFlush() .然而,.NET Graphics 类并没有公开它,它是自动完成的。
一个非常有吸引力的理论是,当您分配 Transform 属性时,GDI+ 在内部调用 GdiFlush()。因此,您看到的成本实际上是之前 DrawRectangle() 调用的成本。
您需要通过为其提供更多批处理机会来取得成功。非常喜欢让您绘制大量项目的 Graphics 类方法。换句话说,不要绘制每个单独的粒子,而是绘制许多粒子。您会喜欢 DrawRectangles()、DrawLines()、DrawPath()。不幸的是,没有 DrawPolygons(),您真正喜欢的那个,从技术上讲,您可以调用 PolyPolygon(),但这很难开始。
如果我的理论不正确,请注意您不需要 Graphics.Transform。您还可以使用 Matrix.TransformPoints() 和 Graphics.DrawPolygon()。能否真正领先还有些疑问,Graphics 类不直接使用 GPU 加速,因此它永远无法与 DirectX 竞争。
关于c# - Graphics.Transform 效率极低,我该怎么办?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34430786/
我有一段这样的代码。我发现 myResults = writer.getBuffer().toString(); 对某些用例返回 EMPTY STRING,但对其他用例则不返回。 我查看了服务器,但在
如何使用 javascript 通过 id 更改元素中的 -webkit-transform 、-moz-transform 、-o-transform 和 -ms-transform css? 这段
我正在使用 javax.xml.transform.Transformer.transform() 通过 xsl 样式表将一个 xml 转换为另一个 xml。我想以编程方式设置第一级 child 的排
为了使 seaborn.pairplot() 正常工作,在 jupyter notebook 中执行了以下步骤。 /usr/local/lib/python2.7/site-packages/matp
假设这个输入 XML 编写这些代码行: StreamSource source = new StreamSource(new StringReader(/* the above XML*/));
如何在 spring 框架中配置 java.xml.transform.Transformer ?我需要转换器的实例来通过 xslt 将 xml 转换为文本。因此,配置的转换器应该了解 xslt 样式
我一直在核心数据中使用可转换属性,将图像和颜色等复杂对象转换为原始数据。我拿了this ... The idea behind transformable attributes is that you
我正在尝试打开 XML 文件,添加一些更改,然后保存到其他 XML 文件结果。我正在使用标准 javax.xml.parsers.* 和 javax.xml.transform* 类。 但在保存的文档
Transformer(变换方法)对输入源的大小有限制吗? 我正在尝试转换一个相当长的 (18M) XML,但收到一个奇怪的错误 "The element type "HR" must be term
我正在尝试解析一个非常简单的示例: 100 我使用的样式表如下: 这在 libxs
来自文档 for from_pretrained ,我知道我不必每次都下载预训练的向量,我可以使用以下语法保存它们并从磁盘加载: - a path to a `directory` contain
默认缓存目录磁盘容量不足,我需要更改默认缓存目录的配置。 最佳答案 您可以在每次加载模型时指定缓存目录 .from_pretrained通过设置参数cache_dir .您可以通过导出环境变量 TRA
有一个函数,例如: CATransform3DGetAffineTransform Returns the affine transform represented by 't'. If 't' ca
我有一个包含 WCF 设置的配置文件: “add”元素只有一个 baseAddress 属性,所以我不能使用 Match 定位器。一种方法如何像我的示例中那样转换多个元素? 最
在收到下面链接中描述的错误后,我已将实体属性的 Transfomer 设置为 NSSecureUnarchiveFromData(之前为 nil)。 CoreData crash error Xcod
当我写Document时使用 Transformer 的 transform() 方法转换为 XML,生成的 XML 文档的格式很好 - 所有元素都写在单独的行上并缩进。除了第一个元素与定义写在同一行
我不明白 StreamResult 实例会发生什么。我看到 Transformer 对象接收 source 和 streamResult: transformer.transform(sour
从下面的代码片段我应该得出结论,std::transform 比 boost::transform 更受欢迎,因为前者使用更少的初始化和析构函数可能更有效比后者? #include #include
transform() 可以将函数应用到序列的元素上,并将这个函数返回的值保存到另一个序列中,它返回的迭代器指向输出序列所保存的最后一个元素的下一个位置。 这个算法有一个版本和 for_each()
我是 react-native 的新手。在项目上将 react-native 从 0.48.3 升级到 0.62.2 后,运行“react-native run-ios”命令时出现错误:“index.
我是一名优秀的程序员,十分优秀!