opengl - 如何使用 C 或 C++ 与显卡进行接口(interface)?

标签 opengl graphics

OpenGL等库访问显卡,可以生成图形程序,这些库是如何访问显卡的,因为它们是用C实现的。据我所知,C和C++不提供内置的图形功能语言和生成图形需要库。那么这些库是如何用 C 语言编写的呢?同样的问题也适用于声音吗?

C/C++ 语言的附加功能(例如图形、声音、互联网访问)是否用较低级语言编写,然后使用库提供给 C/C++?

我将感谢任何纠正我的概念的总结,或者网络或书籍上的任何建议读物。

最佳答案

OpenGL 并不是真正的库。这是一个规范。您系统上的 opengl32.dll 或 libGL.so 只是非常薄的层,与 GPU 驱动程序通信。

According to what i've heard, c and c++ do not provide graphics features built in the language and producing graphics requires libraries. How then are these libraries written in c?

操作系统提供与硬件对话的功能。驱动程序使用这些设施来驱动(因此得名)硬件。例如,写入序列 A、B、C、D 可能会使某些特定 GPU 在帧缓冲区中绘制三角形。

我已经在 On Windows, how does OpenGL differ from DirectX? 中解释了这些事情在这里 How does OpenGL work at the lowest level? (我在这里逐字引用):

This question is almost impossible to answer because OpenGL by itself is just a front end API, and as long as an implementations adheres to the specification and the outcome conforms to this it can be done any way you like.

The question may have been: How does an OpenGL driver work on the lowest level. Now this is again impossible to answer in general, as a driver is closely tied to some piece of hardware, which may again do things however the developer designed it.

So the question should have been: "How does it look on average behind the scenes of OpenGL and the graphics system?". Let's look at this from the bottom up:

  1. At the lowest level there's some graphics device. Nowadays these are GPUs which provide a set of registers controlling their operation (which registers exactly is device dependent) have some program memory for shaders, bulk memory for input data (vertices, textures, etc.) and an I/O channel to the rest of the system over which it recieves/sends data and command streams.

  2. The graphics driver keeps track of the GPUs state and all the resources application programs that make use of the GPU. Also it is responsible for conversion or any other processing the data sent by applications (convert textures into the pixelformat supported by the GPU, compile shaders in the machine code of the GPU). Furthermore it provides some abstract, driver dependent interface to application programs.

  3. Then there's the driver dependent OpenGL client library/driver. On Windows this gets loaded by proxy through opengl32.dll, on Unix systems this resides in two places: * X11 GLX module and driver dependent GLX driver * and /usr/lib/libGL.so may contain some driver dependent stuff for direct rendering

    On MacOS X this happens to be the "OpenGL Framework".

    It is this part that translates OpenGL calls how you do it into calls to the driver specific functions in the part of the driver described in (2).

  4. Finally the actual OpenGL API library, opengl32.dll in Windows, and on Unix /usr/lib/libGL.so; this mostly just passes down the commands to the OpenGL implementation proper.

How the actual communication happens can not be generalized:

In Unix the 3<->4 connection may happen either over Sockets (yes, it may, and does go over network if you want to) or through Shared Memory. In Windows the interface library and the driver client are both loaded into the process address space, so that's no so much communication but simple function calls and variable/pointer passing. In MacOS X this is similar to Windows, only that there's no separation between OpenGL interface and driver client (that's the reason why MacOS X is so slow to keep up with new OpenGL versions, it always requires a full operating system upgrade to deliver the new framework).

Communication betwen 3<->2 may go through ioctl, read/write, or through mapping some memory into process address space and configuring the MMU to trigger some driver code whenever changes to that memory are done. This is quite similar on any operating system since you always have to cross the kernel/userland boundary: Ultimately you go through some syscall.

Communication between system and GPU happen through the periphial bus and the access methods it defines, so PCI, AGP, PCI-E, etc, which work through Port-I/O, Memory Mapped I/O, DMA, IRQs.

更新

要回答的是,如何从 C 程序(例如用 C 编写的操作系统内核和/或驱动程序)连接实际硬件:

C 标准本身将地址视为纯粹抽象的东西。您可以将指针强制转换为 uintptr_t,但如果强制转换回指针,则获得的数值只需遵守指针算术。否则该值可能与地址空间无关。实现对 C 的硬件访问的唯一安全方法是按照所用 C 实现和系统的 ABI 在汇编中编写最低级别的内容。

所有正确的操作系统都是这样做的。在 C 中地址永远不会被转换为指针!操作系统用汇编程序实现了这一点,与系统的C编译器相匹配。用汇编编写的代码导出为可在 C 中调用的函数。然后内核将这些函数提供给 GPU 驱动程序。所以链条是:

应用程序→[OpenGL API层→厂商OpenGL实现]→GPU驱动→操作系统内核→硬件。

关于opengl - 如何使用 C 或 C++ 与显卡进行接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7967073/

相关文章:

c - GLUT 计时器循环过早停止

c++ - 如何使用 OpenGL 绘制 OpenMesh

math - 如何在法线周围逆时针排列3个点

java setOpaque(false) 使悬停速度变慢

java - 缓慢改变颜色,Java 图形

javascript - PaperJS Canvas 绘图区域仅位于左上角,除非采取外部操作

OpenGL - 如何填充没有数据的缓冲区?

c++ - 旋转和平移显示列表

c++ - 使用面向对象的方法加载着色器

java - AffineTransform 线性插值