图像绘制速度

2024-04-10

我正在开发一款游戏,但目前我正在运行基准测试。

如果有人能在这件事上帮助我,我将不胜感激。

我正在做的是,当我单击开始按钮时,使用以下代码在面板上触发绘制事件:

    private void startToolStripMenuItem_Click(object sender, EventArgs e)
    {
        try
        {
            pnlArea.Invalidate();

        }
        catch (Exception)
        {
            throw;
        }
    }

然后我在绘画事件中执行此操作:

    private void pnlArea_Paint(object sender, PaintEventArgs e)
    {
        try
        {
            stopwatch = new Stopwatch();
            // Begin timing
            stopwatch.Start();

            if (gameStatus == GameStatus.PlaceHead)
            {
                e.Graphics.DrawImage(dictHead["HeadRight"], 100, 100, 15, 15);
            }

            //e.Graphics.Clear(Color.White);

            if (gameStatus == GameStatus.GameTest)
            {
                int x = 0;
                int y = 0;
                for (int i = 0; i < 5000; i++)
                {
                    x += 15;
                    if (x > 1000)
                    {
                        x = 0;
                        y += 15;
                    }

                    e.Graphics.DrawImage(body.Value, x, y, 15, 15);

                }
            }

            toolTimer.Text = Math.Round((stopwatch.Elapsed.TotalMilliseconds / 1000), 2).ToString() + "s";

            // Stop timing
            stopwatch.Stop();
        }
        catch (Exception)
        {

            throw;
        }
    }

这是我在上面的代码中绘制的身体部分:

这是确切的尺寸 --> 15px x 15px

但这有时需要长达 1.2 秒! 有什么办法可以改善这个吗?

this is a sample of the end result screen: enter image description here


您需要考虑如何最大程度地减少绘图调用的次数。目前,您绘制 5000 个小方框以生成网格。每次绘制一个框时,您都会执行几条指令,然后调用图形方法来渲染缩放图像。对于每个网格方来说,这都是很大的开销。

因此,您可以考虑的第一件事是找到更有效的方法来绘制图像 - 例如,DrawImageUnscaled可能比DrawImage并达到你想要的结果。但这是优化低效算法的问题 - 要获得真正的性能优势,您需要做的是看看是否可以采用新的、更高效的算法。

如果您必须使用位图进行渲染,那么请查看图案如何重复 - 您可以制作一个更大的位图来提供 4x4 或 16x16 单元组,然后进行渲染吗?或者代表整列或整行的位图?那么您可能会使用 50 次调用而不是 5000 次进行渲染。

但如果您不需要使用位图渲染,您也许可以做得更好。例如,如果您gfx.Clear(backgroundColor)然后向下和横向绘制约 140 条黑线,只需 141 次调用即可创建相同的显示。或者,如果您绘制大约 70 个矩形,则每次调用可以有效地执行 2 行,这大大减少了必须进行的方法调用数量,并允许图形系统使用高度优化的线条渲染和矩形渲染例程一次性绘制更多像素(事实上​​,由于系统知道线始终是垂直和水平的,因此矩形的计算速度可能比广义线快得多)。

(如果有些位不遵循此模式,那么您仍然可以渲染背景网格,然后在顶部绘制更改吗?)

接下来,如果图像中只有一小部分区域从一帧到下一帧发生变化,那么您的算法将绘制 5,000 个框,即使其中 4999 个框没有变化(或者 70 个矩形,当 1 个就足够时)。因此,如果您(a)仅使需要更改的视图部分无效,并且(b)编写渲染例程来计算出哪些网格方块位于剪辑边界之外,因此绘制毫无意义,则可以大大改善问题。这可以减少每帧绘制 1 个矩形的更新,而不是 5000 个。 (实现相同效果的另一种方法是将图像保留在屏幕外位图中,然后在其上绘制更改。当您将其渲染到主屏幕显示时,显卡将为您剪辑它并实现相同的结果 -重绘速度更快)

这一切都是为了通过“懒惰”和横向思考以尽可能少地完成工作来实现相同的显示。 (让计算机运行得更快总是归结为要求它做得更少)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

图像绘制速度 的相关文章

  • 如何将 std::string& 转换为 C# 引用字符串

    我正在尝试将 C 函数转换为std string参考C 我的 API 如下所示 void GetStringDemo std string str 理想情况下 我希望在 C 中看到类似的东西 void GetStringDemoWrap r
  • 调用 McAfee 病毒扫描引擎

    我收到客户的请求 要求使用他们服务器上的 McAfee 病毒扫描将病毒扫描集成到应用程序中 我做了一些调查 发现 McScan32 dll 是主要的扫描引擎 它导出各种看起来有用的函数 我还发现提到了 McAfee Scan Engine
  • 在 xaml 中编写嵌套类型时出现设计时错误

    我创建了一个用户控件 它接受枚举类型并将该枚举的值分配给该用户控件中的 ComboBox 控件 很简单 我在数据模板中使用此用户控件 当出现嵌套类型时 问题就来了 我使用这个符号来指定 EnumType x Type myNamespace
  • 为什么 GCC 不允许我创建“内联静态 std::stringstream”?

    我将直接前往 MCVE include
  • 从经典 ASP 调用 .Net C# DLL 方法

    我正在开发一个经典的 asp 项目 该项目需要将字符串发送到 DLL DLL 会将其序列化并发送到 Zebra 热敏打印机 我已经构建了我的 DLL 并使用它注册了regasm其次是 代码库这使得 IIS 能够识别它 虽然我可以设置我的对象
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • 重载 (c)begin/(c)end

    我试图超载 c begin c end类的函数 以便能够调用 C 11 基于范围的 for 循环 它在大多数情况下都有效 但我无法理解和解决其中一个问题 for auto const point fProjectData gt getPoi
  • 结构体的内存大小不同?

    为什么第一种情况不是12 测试环境 最新版本的 gcc 和 clang 64 位 Linux struct desc int parts int nr sizeof desc Output 16 struct desc int parts
  • 为什么这个字符串用AesCryptoServiceProvider第二次解密时不相等?

    我在 C VS2012 NET 4 5 中的文本加密和解密方面遇到问题 具体来说 当我加密并随后解密字符串时 输出与输入不同 然而 奇怪的是 如果我复制加密的输出并将其硬编码为字符串文字 解密就会起作用 以下代码示例说明了该问题 我究竟做错
  • 两个类可以使用 C++ 互相查看吗?

    所以我有一个 A 类 我想在其中调用一些 B 类函数 所以我包括 b h 但是 在 B 类中 我想调用 A 类函数 如果我包含 a h 它最终会陷入无限循环 对吗 我能做什么呢 仅将成员函数声明放在头文件 h 中 并将成员函数定义放在实现文
  • C# xml序列化必填字段

    我需要将一些字段标记为需要写入 XML 文件 但没有成功 我有一个包含约 30 个属性的配置类 这就是为什么我不能像这样封装所有属性 public string SomeProp get return someProp set if som
  • 空指针与 int 等价

    Bjarne 在 C 编程语言 中写道 空指针与整数零不同 但 0 可以用作空指针的指针初始值设定项 这是否意味着 void voidPointer 0 int zero 0 int castPointer reinterpret cast
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • C# 中的 IPC 机制 - 用法和最佳实践

    不久前我在 Win32 代码中使用了 IPC 临界区 事件和信号量 NET环境下场景如何 是否有任何教程解释所有可用选项以及何时使用以及为什么 微软最近在IPC方面的东西是Windows 通信基础 http en wikipedia org
  • C++ 继承的内存布局

    如果我有两个类 一个类继承另一个类 并且子类仅包含函数 那么这两个类的内存布局是否相同 e g class Base int a b c class Derived public Base only functions 我读过编译器无法对数
  • 当文件流没有新数据时如何防止fgets阻塞

    我有一个popen 执行的函数tail f sometextfile 只要文件流中有数据显然我就可以通过fgets 现在 如果没有新数据来自尾部 fgets 挂起 我试过ferror and feof 无济于事 我怎样才能确定fgets 当
  • 为什么 std::uint32_t 与 uint32_t 不同?

    我对 C 有点陌生 我有一个编码作业 很多文件已经完成 但我注意到 VS2012 似乎有以下语句的问题 typedef std uint32 t identifier 不过 似乎将其更改为 typedef uint32 t identifi
  • 类型或命名空间“MyNamespace”不存在等

    我有通常的类型或命名空间名称不存在错误 除了我引用了程序集 using 语句没有显示为不正确 并且我引用的类是公共的 事实上 我在不同的解决方案中引用并使用相同的程序集来执行相同的操作 并且效果很好 顺便说一句 这是VS2010 有人有什么
  • 现代编译器是否优化乘以 1 和 -1

    如果我写 template

随机推荐