学习低级图形编程

54

我对学习制作图形应用程序的不同抽象层非常感兴趣。

我看到很多术语被抛出:在最高层次的抽象中,我听说过像C#,.NET,pyglet和pygame这样的东西。更低一级,我听说过DirectX和OpenGL。然后还有DirectDraw,SDL,Win32 API以及其他多平台库,如WxWidgets。

我该如何获得一个好的感觉,了解其中一层结束的地方以及下一层开始的地方?在Windows中,使用C的“最低可能级别”创建窗口是什么?C ++呢?(代码示例将是完美的。)在X11中呢? Windows的OpenGL和DirectX实现是建立在Win32 API之上的吗?我从哪里开始学习这些内容?

SO上有另一个问题,建议使用Programming Windows。那Linux呢?有类似的书籍吗?

我知道这非常低级,并且有许多友好的工具可用,但我至少想了解表面以下发生了什么的基础知识。尽管我很想开始操作窗口和向量,但从像pygame这样的东西开始太高级了。我真的需要完全概念性的电路,了解如何在计算机上绘制图形

我会非常感激关于书籍和资源的建议,但如果对这个问题的回答中有很多不同的方法来实现"Hello world"并涉及到不同的图形编程方法,那将是非常酷的。使用C?C++?使用OpenGL?使用DirectX?在Windows XP上?在Ubuntu上?也许我要求太多了。


5
针对 Linux 有没有类似的书籍,现在已经有一本了 - http://www.amazon.com/The-Linux-Programming-Interface-Handbook/dp/1593272200。这本书的评价非常高,很少有书能够获得100%五星评价,而且39个评价足以说明其质量还不错。 - Mozan Sykol
Max,我有同样的问题,我只是想知道你是否已经找到了解决所有问题的方法,因为这些相同的问题也困扰着我。 - Suraj Jain
@SurajJain,这不算太多,但我还有一些其他问题可以让你开始:https://dev59.com/HXVC5IYBdhLWcg3woCnNhttp://stackoverflow.com/questions/12850071/what-is-the-simplest-way-to-render-a-3d-cube-with-a-single-lighting-source - Max Cantor
9个回答

48

最低级别就是显卡的视频RAM。当计算机首次启动时,图形卡通常设置为80x25个字符的传统模式。

此时可以使用BIOS提供的中断写入文本。您还可以从16种不同的颜色调色板中更改前景和背景颜色,并使用访问端口/寄存器更改显示模式。此时,您可以加载不同的字体到显示内存中并仍然使用80x25模式(操作系统安装通常会这样做),或者可以继续启用VGA / SVGA。这很复杂,因此需要驱动程序。

一旦卡处于“较高”模式,就可以通过访问内存映射到视频卡上来更改屏幕上的内容。它以每行像素水平存储,并且在每行末尾有一些没有映射到屏幕上的“脏区域”,您必须进行补偿。但是,您可以将内存中图像的像素直接复制到屏幕上。

对于像DirectX、OpenGL这样的东西,指令被发送到图形卡,它会自动更新屏幕。像“嘿,你,画出我已经加载到VRAM中的这个图像,在这里、这里和这里”或“用这个变换矩阵画出这些三角形......”这样的指令,与逐像素相比只需一小部分时间。CPU会感谢你。

DirectX / OpenGL是用于向卡发送这些命令并具有所有支持功能以帮助您顺利完成工作的程序员友好库。更直接的方法只会徒劳无功。

SDL是一个抽象层,在不必在每个系统上都了解其工作方式的情况下,我猜测它可能会使用半直接屏幕写入、另一个Direct3D等。只要代码保持跨平台... 就可以使用最快的方式。

GDI / GDI +和XWindow系统。它们专门设计用于绘制窗口。最初它们使用逐像素绘图法(足以满足要求,因为只有在按下按钮或移动窗口等操作时才需要重绘),但现在它们使用Direct3D / OpenGL进行加速绘图(和特效)。优化取决于这些库的版本和实现。

所以,如果你想获得最强大、最快速的性能,DirectX/openGL 是最好的选择。SDL 在跨平台环境下获取最佳性能方面确实很有用,并且与 OpenGL 集成。窗口系统位于最后,但不要低估它。特别是最近 Microsoft 推出的一些东西。


1
嘿,嘿,那么,最低层次就是VHDL或Verilog设计的VGA控制器!实际上看看这个网站http://neil.franklin.ch/Projects/SoftVGA/,它只使用了一个微控制器! - NoMoreZealots

28

1
目前可以在http://www.drdobbs.com/high-performance-computing/184404919找到(仅供参考 :))。 - Jeff Mattfield
谢谢您的推荐,我有预感这会是一个巨大的帮助。 - zeboidlund
这是给初学者的吗? - Suraj Jain

6
如果你真的想从最基础开始,那么画一条线就是最基本的操作。计算机图形学只是关于在网格(屏幕)上填充像素,因此您需要计算出要填充哪些像素,以获得从(x0,y0)到(x1,y1)的直线。
查看Bresenham算法,了解所涉及的内容。

6
如果在网格上通过填充像素来画一条直线,那么如何说画直线比设置单个像素更基础呢? :) - unwind

6
成为一名优秀的图形和图像处理程序员并不需要低级别的知识,但我确实不想对我所使用的东西一无所知。我认为有两种方法来追寻这个领域——从高级向下,或从底层向上。
自上而下是追踪高级图形操作(例如绘制圆)到硬件的方式。要充分了解OpenGL,然后查看Mesa(免费!)源代码以了解OpenGL在软件中的实现方式。接下来是查看Xorg的源代码,首先了解API调用如何通过客户端传递到X服务器。最后进入与硬件接口的设备驱动程序。
自下而上: 构建自己的图形硬件。考虑它如何连接到计算机-如何通过几个字节大小的寄存器处理大量像素,DMA将如何工作。编写设备驱动程序,尝试设计可能对应用程序员有用的图形库。
自下而上的方法是我多年前学习的方式,当时它是使用缓慢的8位微处理器实现的。直接经验使我更好地理解了电路和硬件软件交互的艰难设计决策,例如在设备驱动程序或更高级别的情况下使用聪明的硬件绘制矩形。所有这些都没有实际的日常价值,但提供了一种理解新技术的基础知识。

1
先生,我有一个问题想问很久了。在不包括任何图形库的情况下,C语言是否有函数可以让我做出像圆这样的东西,或者更基本的事情,比如操作像素,无论代码有多长都可以。 - Suraj Jain
@SurajJain 也许你可以在这里找到答案:https://dev59.com/OVwY5IYBdhLWcg3wH01C。据我所知,如果您能够使用纯C访问VRAM(它类似于普通RAM,但用于存储像素值的图形硬件将其用作存储器),则如果您更改VRAM中任何内容的值,则应该看到某个地方的像素颜色发生变化。 - ZiyadCodes

4

3
在MSWindows上很容易:使用API提供的标准Windows编程APIDirectX系列API,这是您要使用的,并且它们都有很好的文档。
在X Window环境中,您可以使用提供的任何X11库。如果您想了解在X下窗口化的原理,我建议您这样做,不用考虑其他人告诉您不要这样做,因为它真的会帮助您了解图像和在X下的窗口化。您可以阅读X编程文档(在Google上搜索)。完成此练习后,您将感激更高级别的库!
除上述之外,在您可以到达的最低级别(除了芯片级别)下,您可以调用切换到可用各种图形模式的中断,然后写入屏幕缓冲区,但是对于此操作,您必须使用汇编语言,任何其他语言都太慢了。这种方式将完全不可移植。
另一篇文章提到了Abrash's Black Book——一个很好的资源。
编辑:至于Linux编程书籍:它是社区事务,有许多howto周围;还要找到一个论坛,加入它,只要您表现得彬彬有礼,您将得到所有您需要的帮助。

2
首先,我想说“你要求太高了”。就我的少许经验而言,我建议先阅读一些有关DirectX或OpenGL的教程或图书。再往下学习会变得非常复杂。我看过的大多数OpenGL或DirectX图书都有很好的介绍,解释函数/类的作用。
一旦掌握了其中之一,您可以深入研究库,以了解它们到底在做什么,以便更深入地了解。
或者,如果您真的非常想学习最低级别...请阅读上面帖子中的书籍。

2

libX11是X11的最底层库。我认为opengl/directx直接与驱动程序/硬件通信(或者模拟不支持的操作),因此它们将是最底层的库。

如果您想从非常低级别的编程开始,请查找VGA的x86汇编代码,然后启动dosbox或类似程序。


1
Vulkan API是一种API,它可以让您非常低级地访问GPU的大多数(如果不是全部)功能,包括计算和图形功能,它适用于AMD和Nvidia GPU(不是所有型号)。您还可以使用CUDA,但它仅适用于Nvidia GPU,并且仅具有对计算功能的访问权限,没有视频输出。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接