C++图形库的内部工作原理

5

你可能已经知道,C++没有标准的图形库。大多数游戏使用DirectX或OpenGL。

但是这些库是如何工作的呢?换句话说,如果C++中没有绘图机制,第三方库又是如何绘制图形的呢?它们只是用另一种语言编写吗?

3个回答

7
具体而言,DirectX和OpenGL通过调用操作系统和/或视频硬件驱动程序来工作。驱动程序反过来通过与图形设备交互来进行实际绘图。交互的确切细节因视频卡而异。
在DOS时代,C++程序员可以直接与硬件打交道。这是通过两种方式实现的。首先,通过写入/读取存储像素或文本的特殊内存块(“帧缓冲区”)。它是一个位于已知地址的内存跨度,因此要使用它,必须将整数常量转换为指针并使用该指针。完全是C++机制。另一种交互方式是从/写入I/O端口。现在,这是一种不直接由C支持的机制,除非您计算内联汇编或编译器内部函数。有两个库函数会包装这两个操作(字面上是INP和OUTP两个CPU命令的包装器),但大多数程序员只会使用一个单行内联汇编片段。
即使现在,大多数视频硬件交互都归结为这两个路径 - 帧缓冲区和I/O端口(DMA和中断通常不用于图形)。但我们应用级程序员看不到这些。这是驱动程序的事情。
一个现代的警告与保护模式有关;在保护模式下,C指针与底层物理地址不同。即使在内核模式下,将0xA0000强制转换为指针也无法让您进入帧缓冲区。但是,内核级代码(即驱动程序)可以请求内存管理器提供与特定物理地址相对应的指针。

你确定DMA没有被使用吗?我记得当时由于图形内存不足,需要将纹理从/到主内存进行分页处理。 - MSalters
DMA通常用于流设备,这些设备逐个发出字节,例如硬盘和网络卡。但无论如何,从软件方面“使用”DMA归结为端口I/O,指定要从中读取/写入的内存地址。其余部分由设备本身完成。 - Seva Alekseyev
1
@SevaAlekseyev:现代GPU通常配备了一大堆DMA引擎,具有分散/聚集能力。 - datenwolf
然而,设置DMA硬件归结为I/O端口操作。 - Seva Alekseyev

6
他们将把电话转接到驱动程序,该驱动程序将将它们发送到显卡。

但是驱动程序本身也是用C或C++编写的。那么,如果它们所使用的语言没有图形库,这些驱动程序如何工作呢? - MOON

1

DirectX和OpenGL在相当低的级别上运行。也就是说,你说“画一个三角形,现在画一个正方形”。通常,程序员将这些调用封装到C ++类中,以提供更高级别的功能,例如“绘制模型,绘制树”。这被称为引擎。

我建议查看NeHe教程以获取更多信息:http://nehe.gamedev.net/


例如,在OpenGL中绘制三角形的调用如下:

GLBegin(BEGIN_POLYGONS);
GLVector3(0,0,0);
GLVector3(10,10,0);
GLVector3(-10,10,0);
GLEnd();

就像我之前说的,参见上面的NeHe教程链接,它们都是用C/C++编写的。


引擎通常是一个更高级别的概念,位于像场景图这样的东西之上。 - Eric
除非您的引擎包含屏幕图形。Ogre3D、Crystal Space、XNA和Irrlicht都是引擎,且均包含屏幕图形。 - Timothy Baldridge
但是他们怎么说“画一个三角形”? - Maxpm
1
通过调用标准的 C 函数...请参见上文 ^^ - Timothy Baldridge
有点晚了,但仅仅因为一个引擎包含场景图并不意味着它不是一个概念上独立的概念。场景图是一种数据结构,用于管理渲染3D数据。引擎管理场景图内容,以及其他事情。 - Eric

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