像OpenGL这样的库访问显卡并可以生成图形程序,这些库如何访问显卡,因为它们是用C实现的.根据我所听到的,C和C++不提供用语言构建的图形功能和制作图形需要库.那么这些库是如何用C语言编写的?同样的问题也适用于声音吗?
C/C++语言的附加功能,如图形,声音,Internet访问是用低级语言编写的,然后使用库提供给C/C++?
我会感谢任何纠正我的概念或网上或书籍上的任何建议读物的摘要.
dat*_*olf 22
OpenGL实际上不是一个库.这是一个规范.您系统上的opengl32.dll或libGL.so只是非常薄的层,与GPU驱动程序通信.
根据我所听到的,c和c ++不提供语言内置的图形功能,并且生成图形需要库.那么这些库是如何用c语言编写的?
操作系统提供与硬件通信的功能.驱动程序使用这些工具来驱动(因此命名)硬件.例如,写入序列A,B,C,D可以使某些特定GPU向帧缓冲区绘制三角形.
我在On Windows上解释过那些东西,OpenGL与DirectX的不同之处是什么?在这里OpenGL如何在最低级别工作?(我在这里包括一个逐字引用):
这个问题几乎不可能回答,因为OpenGL本身只是一个前端API,只要实现符合规范并且结果符合这一点,它就可以按照您喜欢的方式完成.
问题可能是:OpenGL驱动程序如何在最低级别上运行.现在一般来说这也是不可能回答的,因为驱动程序与某些硬件密切相关,但是开发人员可以设计它.
所以问题应该是:"它在OpenGL和图形系统的幕后平均看起来如何?".让我们从下往上看:
在最低级别有一些图形设备.现在这些是GPU,它们提供一组寄存器来控制它们的操作(这些寄存器完全取决于设备)具有一些用于着色器的程序存储器,用于输入数据的大容量存储器(顶点,纹理等)以及用于其余部分的I/O通道它接收/发送数据和命令流的系统.
图形驱动程序跟踪GPU状态以及使用GPU的所有资源应用程序.它还负责转换或任何其他处理应用程序发送的数据(将纹理转换为GPU支持的pixelformat,在GPU的机器代码中编译着色器).此外,它还为应用程序提供了一些抽象的,依赖于驱
然后是依赖于驱动程序的OpenGL客户端库/驱动程序.在Windows上,这是由代理通过opengl32.dll加载的,在Unix系统上,它位于两个地方:*X11 GLX模块和驱动程序相关的GLX驱动程序*和/usr/lib/libGL.so可能包含一些驱动程序相关的东西,用于直接渲染
在MacOS X上,这恰好是"OpenGL框架".
正是这部分将OpenGL调用的方式转换为对(2)中描述的驱动程序部分中的驱动程序特定函数的调用.
最后是实际的OpenGL API库,Windows中的opengl32.dll,以及Unix /usr/lib/libGL.so; 这主要是将命令传递给OpenGL实现.
实际沟通的发生方式不能一概而论:
在Unix中,3 < - > 4连接可能通过套接字发生(是的,它可能,并且如果你愿意,它会通过网络)或通过共享内存.在Windows中,接口库和驱动程序客户端都被加载到进程地址空间中,因此没有那么多的通信,只有简单的函数调用和变量/指针传递.在MacOS X中,这与Windows类似,只是OpenGL界面和驱动程序客户端之间没有分离(这就是为什么MacOS X跟上新的OpenGL版本如此之慢的原因,它总是需要一个完整的操作系统升级来提供新的框架).
3 < - > 2之间的通信可以通过ioctl,读/写,或者通过将一些存储器映射到进程地址空间并配置MMU以在完成对该存储器的改变时触发一些驱动程序代码.这在任何操作系统上都非常相似,因为你总是必须跨越内核/用户空间边界:最终你会经历一些系统调用.
系统和GPU之间的通信是通过外围总线及其定义的访问方法实现的,因此PCI,AGP,PCI-E等通过端口I/O,内存映射I/O,DMA,IRQ进行工作.
更新
要回答一下,如何从C程序接口实际硬件说是用C编写的OS内核和/或驱动程序:
C标准本身将地址视为纯粹抽象的东西.您可以将指针强制转换为uintptr_t,但是如果转换为指针,您获得的数值只需要遵循指针算法.否则,该值可能与地址空间无关.实现C的硬件访问的唯一安全方法是在所使用的C实现和系统的ABI之后,在汇编中编写最低级别的东西.
这就是所有适当的操作系统如何做到这一点.永远不会将地址转换为C中的指针!操作系统在汇编程序中实现了这一点,与系统的C编译器相匹配.用汇编语言编写的代码导出为C中可调用的函数.内核然后将这些函数提供给GPU驱动程序.所以链是:
应用程序→[OpenGL API层→供应商OpenGL实现]→GPU驱动程序→OS内核→硬件.