V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
maxxfire
V2EX  ›  程序员

新手问个 OpenGL 工作原理的问题

  •  
  •   maxxfire · 2020-02-28 15:31:58 +08:00 · 2271 次点击
    这是一个创建于 1731 天前的主题,其中的信息可能已经有所发展或是发生改变。
    首先惭愧的说玩过不少游戏,但是对 OpenGL 却知之甚少。今天机缘巧合了解了一下,引发了一些疑问,如下:

    1. OpenGL 是一种 API 编程接口,但这个接口是规范在哪一层,应用层?驱动层?甚至是一种硬件规范?

    2. OpenGL 定义了一种着色器语言,这是一种解释型语言 /还是编译型语言?是跑在 CPU 上还是直接跑在 GPU 上?

    3. Linux 上万物皆文件。显卡上有多个 GPU 核心和显存,那么它在 Linux 系统上暴露出来的是不是一系列的字符设备 /块设备?

    4. 多任务在 CPU 上工作时,系统提供了进程上下文切换。那么开多个窗口跑多个游戏,是不是也有显卡的上下切换,这是操作系统提供的?什么机制?

    或者有什么书籍可以解释这些,帮忙推荐一下,谢谢!
    13 条回复    2020-03-02 09:58:24 +08:00
    charten
        1
    charten  
       2020-02-28 15:40:54 +08:00
    WebGL 属于 OpenGL ES 2 的子集,而 OpenGL ES 又是 OpenGL 的子集,那么四舍五入我也算是学过 OpenGL (的皮毛)了。
    glumess
        2
    glumess  
       2020-02-28 15:44:35 +08:00
    学习 OpenGL 可以关注一下我的公众号:音视频开发进阶,或者博客 https://glumes.com 当时学的时候写了不少博客,一起交流学习一下。
    OpenGL 是 Khronos Group 组织开发维护的一个接口规范,具体的实现是由驱动厂商完成。
    着色器语言按区分应该编译型语言,最终编译成二进制的。
    GPU 那块的切换机制就不太懂了....
    charten
        3
    charten  
       2020-02-28 15:46:12 +08:00
    我能回答的只能是 2 了,shader 着色器语言属于编译型语言,根据不同显卡的指令集,编译成对应的可执行二进制码,在 GPU 上执行。编译是在 CPU 上编译,执行是在 GPU 执行。
    crackhopper
        4
    crackhopper  
       2020-02-28 15:52:18 +08:00
    了解的不多。尽量答一下
    1. OpenGL 的调用像是在驱动层,但并不是给操作系统设计的,是给应用程序设计的规范。应用程序接入 OpenGL 会直接操作显卡,不走操作系统驱动。当然创建设备上下文的时候系统应该会有一定的工作。
    2. 着色器语言是编译型语言,一般会由 GPU 厂商提供编译器,链接的时候会和 CPU 的编译器的产出链接到一起。着色器程序直接跑在 GPU 上。
    3. 显卡是用文件标识的。多核心和显存,我不确定,我觉得是 OpenGL 还有 CUDA 这种 SDK 帮忙助理的。GPU 多核心一般很多,上千个,而且一般不会细粒度操作(就是一般不会对指定某个核心做某个事情,都是多核心协同运作)。显存本身是 GPU 的一部分,单独作为一个文件设备来映射还是挺诡异的。
    4. 显卡不对进程管理。虽然显卡会标注不同进程用了多少资源。但显卡更像是一个接收到命令,然后执行的一个东西。当进程切换的时候,如果进程窗口还在,那么对应的渲染还会执行;只不过上层窗口后渲染,覆盖了之前的区域。如果窗口最小化了,那么操作系统应该会有优化对设备上下文进行管理,实际不发生渲染。
    里面部分有我的猜测,如果不正确欢迎指正。
    misaka19000
        5
    misaka19000  
       2020-02-28 15:52:30 +08:00
    据我了解 OpenGL 只是一种规范,类似于 HTML
    23571113
        6
    23571113  
       2020-02-28 15:54:52 +08:00
    1. 如果你不是写驱动的或写系统的, 你能调用的 API 基本都是在应用层.
    2. 编译, 因为是跑在显卡上的, 而显卡不是通用计算设备(CPU), 没法给你解释.
    3. CPU 对于周边设备控制大部分都是靠写内存, GPU 也不例外.
    4. 实际上显卡渲染的是显存的数据, 而显存的数据在内存也有一份相同的, 显卡定时到内存对应地址拿数据更新, 因此 CPU 上下文切换和显卡没什么关系. 如果没有优化基本就是 while 循环遍历每个对象渲染.
    crackhopper
        7
    crackhopper  
       2020-02-28 16:01:36 +08:00
    @23571113 我感觉自己也明白了很多,感谢~
    有个问题:比如用 shader 渲染的结果应该是保存在显存中。但你说显卡定期去内存同步。那会不会内存的结果覆盖显存的结果呢?我猜测是有个机制,部分覆盖,部分不覆盖。
    across
        8
    across  
       2020-02-28 16:03:31 +08:00
    1. 记得这个术语叫硬件抽象层吧,OpenGL 内部实现了对硬件的支持,所以应用层可统一调用(所以叫驱动似乎也没啥问题···)

    2. 编译。你写过 GLSL 就知道,还有语句是加载代码并进行编译的,OpenGL 代码自然运行在 GPU 上,和硬件紧密相关。

    3. linux 不知道

    4. OpenGL 自己也是有上下文的,就是 OpenGL Context,内部状态机。

    OpenGL 教材就经典的那两本:
    OpenGL 编程指南
    OpenGL 超级宝典

    红蓝宝书····
    外加 OpenGL-ES 有一本 OpenGL ES 3.0 编程指南。
    看网络教程也行,不过初次上手挺难消化的,反复看书好点。
    23571113
        9
    23571113  
       2020-02-28 16:07:52 +08:00
    @crackhopper 就是要覆盖, 要不你游戏中的小人怎么动呢? CPU 负责游戏逻辑(比如改变小人的这个对象的坐标, 然后显存也会延迟更新) , GPU 只是单纯负责让你在屏幕上看到的效果罢了.
    across
        10
    across  
       2020-02-28 16:21:39 +08:00
    @across
    第二点回答得模糊了。
    着色器语言 GLSL 是运行在 GPU 上,针对硬件操作的。OpenGL 语言中就有读取文本格式的 GLSL 代码并编译的语句。
    gggxxxx
        11
    gggxxxx  
       2020-02-28 16:37:29 +08:00
    1. 应用层
    2. 编译型,gpu 执行
    3. 这种思路去看待 opengl 是错误的,你把 opengl 当作一个可以操作 gpu 的 sdk 就行了,任何操作一切按照 opengl 的规范来就是
    4. 操作系统提供
    TSai2019
        12
    TSai2019  
       2020-02-29 13:23:09 +08:00 via Android
    微软推出 dx,苹果推出 metal
    是不是证明了 gl 并不靠近底层,且效率不高
    crackhopper
        13
    crackhopper  
       2020-03-02 09:58:24 +08:00
    @23571113 小人动画啥的,有的是在 CPU 上算的,存内存,按照您说的应该是 ok 的;有的则是把矩阵传递给 GPU 在 GPU 上进行变换的,变换结果应该直接存放在显存里,如果后面再去 CPU 同步那么结果就被覆盖了?比如 fragment shader 这种的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2805 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 08:02 · PVG 16:02 · LAX 00:02 · JFK 03:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.