【问题标题】:Programming graphics in assembler?在汇编程序中编程图形?
【发布时间】:2022-01-27 03:47:19
【问题描述】:

我使用 Visual C++ 6.0 和 DirectX 开发了一个正在运行的 Super Mario Sprite。但这对我来说不是很令人满意(仅使用 3D 多媒体框架来显示 2D 精灵),所以我希望能够仅使用 C 和汇编程序来编写动画精灵。

因此,在查看旧游戏(例如 Wolfenstein)时,看起来大部分游戏都是用 C 编写的,并且每次涉及图形输出时都会使用汇编程序。

不幸的是,当尝试使用这个旧的汇编代码时,总是会出现错误消息“NTVDM.exe 发现一条无效指令”,所以这件事现在似乎不起作用。

有没有什么关于汇编图形编程的教程仍然有用?

(我不想使用任何臃肿的框架或库,我只想自己开发一切。WinAPI 可以用于创建全屏窗口和捕获用户输入,但不适用于图形,因为我读过GDI 对于快速图形来说太慢了。)

我使用的是 WindowsXP 和 MASM 或 A86。

【问题讨论】:

  • 所以不要使用“旧”的汇编代码。您是在尝试运行 16 位 DOS 代码还是什么?

标签: graphics assembly


【解决方案1】:

我完全同意 samcl

不再使用汇编程序的主要原因是您无法再访问 Videomemory。早在早期(您提到了德军总部),有一种特殊的视频模式称为0x13h,其中您的图形只是一块内存(每个像素都是调色板颜色,范围从 0-255

今天你拥有非常快的显存,使用你的 CPU 访问它只会降低所有性能,因为你的 CPU 是通过 PCI-Express/AGP/PCI/VESA-LOCALBUS/ISA 连接的(

图形编程通常是大量的读写访问(读取像素,检查是否透明,与 alpha 相乘,写入像素等) 现代内存接口比直接访问内部显卡要慢得多。这就是为什么你真的应该使用着色器,正如 Robert Gould 所建议的那样。通过这种方式,您可以编写更快、更容易理解的代码,并且不会让您的 GFX 内存停滞。

如果您对 GFX 编程更感兴趣,可以通过 shadertoy 来满足您的胃口,这是一个致力于基于着色器的效果以及基于 WebGL 的着色器代码执行的社区。​​p>

你的初学者汇编代码也会很蹩脚。在质量和性能上。相信我。优化这样的原始代码需要大量时间。因此,您编译的 C/C++ 代码将轻松胜过您的手写 asm。

如果您对 Assembler 感兴趣,请尝试编写类似 diskaccess 的代码。在这里您可以获得很多性能。

【讨论】:

    【解决方案2】:

    听起来您只使用 Assembler 是因为您似乎认为这是必要的。事实并非如此。如果您没有任何其他原因(即想学习它),请不要在此处使用 Assembler,除非您确切知道自己在做什么。

    对于普通的图形引擎,完全不需要汇编程序编程。特别是当涉及到超级马里奥风格的 2D 精灵引擎时。如今,即使是像 Python 这样“慢”的脚本语言也足以应付这些事情。

    此外,如果您不太清楚自己在做什么,Assembler不会比 C 快(事实上,它可能会更慢,因为您会重新- 实现现有 C 函数的效率较低)。

    【讨论】:

      【解决方案3】:

      我猜你是否已经在使用 C 和 DirectX,速度不是问题,这更像是一个学习练习。对于 Windows 下的 2D,C 和 DirectX 确实会非常快,正如 Konrad Rudolph 指出的那样,手动汇编程序不太可能比高度优化的 SDK 更快。

      从纯教育的角度来看,这是一项有趣的活动,但相当复杂。早在家用电脑和第一台 PCS 的早期,图形屏幕看起来就像一块内存,其中字节对应一个或多个彩色像素。通过更改屏幕内存的值,您可以绘制点,从而绘制线,并绘制到精灵等...在现代 PC 上,这往往不是一个选项,因为您通常通过 SDK 对显卡进行编程,以做同样的工作。然后,卡片会进行艰苦的工作,并为您提供更高级别的抽象。如果你真的想感受一下当时的感觉,我会推荐一个模拟器。对于现代游戏,请坚持使用您的 SDK。

      【讨论】:

        【解决方案4】:

        如果您想研究这个途径,可以在最新版本的 Directx 中编写您自己的 2D 引擎。您可以创建一个“屏幕空间”对齐的多边形,无需透视校正,其是纹理映射的。然后,您可以将您的精灵逐个像素地绘制到此纹理贴图上。


        至于模式 13h(彼得帕克),它带回了一些回忆!

        __asm
        {
        mov ax,0x13
        int 10h           // 16-bit code only, not Windows
        }
        

        但这当然会在 32 位或 64 位 Windows 程序中出错; Windows 内核不支持 16 位 BIOS 调用(它会安装自己的中断表,作为引导并将 CPU 切换到 64 位模式的一部分。)

        我倾向于避免使用驳船杆的汇编程序,它可能特别难以调试和维护;但是,如果您想更详细地探索这个主题,我可以推荐Michal Abrash's Graphics Programming Black Book。它有点旧,但读起来不错,可以让您深入了解 3D 硬件之前的图形编程技术。

        【讨论】:

        • 如果他想要 2D,没有必要在 3D 多边形上做纹理。 DirectX 不仅是 3D 图形,它还是技术的集合。 2D 部分称为 DirectDraw。
        【解决方案5】:

        图形汇编器是因为当时大多数人缺乏支持 3d 的图形卡,所以它必须在 CPU 上完成,而不是现在。现在它是关于着色器编程的。着色器语言允许您拥抱裸机。因此,如果您应该尝试将 2d 图形编码为着色基础,那么这种体验将具有作为职业技能的价值。

        首先尝试 CUDA。

        【讨论】:

          【解决方案6】:

          我的建议是进行实验。从 C/GDI 和 C++/DirectDraw 开始,获取您的 sprite 代码并以多种形式编写。不用担心汇编程序。

          DirectX 是快速动作图形的最佳选择。学习它,然后弄清楚如何使用汇编程序进行微优化。一般来说,汇编程序不会让您的 API 调用更快。它将为 3D 旋转、纹理映射、着色等方面的更快计算提供灵活性。

          从 DirectDraw 开始。这是FAQ。从技术上讲,DirectDraw 在 DirectX 7 之后被弃用,但您仍然可以使用它并从中学习。它将允许您直接修改帧缓冲区,这可能是您正在寻找的。​​p>

          TripleBuffer Software 有一些有用的教程和论坛。

          还可以考虑将编译器升级到Visual C++ 2008 Express。 VC++ 6 有一个错误的编译器,在尝试编译某些 C++ 库时可能会出现问题。

          【讨论】:

            猜你喜欢
            • 2016-06-14
            • 1970-01-01
            • 2011-01-24
            • 2011-03-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-12-26
            相关资源
            最近更新 更多