OpenGL入门教程之 深入理解

2023-11-20

一、OpenGL简介

  • OpenGL是一种用于渲染2D、3D矢量图形的跨语言、跨平台的应用程序编程规范
  • OpenGL包含一系列可以操作图形和图像的函数,但OpenGL没有实现这些函数,OpenGL仅规定每个函数应该如何执行以及其输出值(类似接口),所以OpenGL仅是一种严格的规范
  • OpenGL规范严格规定了每个函数该如何执行,以及它们的输出值。至于内部具体每个函数是如何实现(Implement)的,将由OpenGL库的开发者自行决定。实际的OpenGL库的开发者通常是显卡的生产商
  • OpenGL被设计为只有输出的,所以它只提供渲染功能。核心API没有窗口系统、音频、打印、键盘/鼠标或其他输入设备的概念。虽然这一开始看起来像是一种限制,但它允许进行渲染的代码完全独立于他运行的操作系统,所以OpenGL允许跨平台开发
  • OpenGL没有提供着色器编译器,而是由显卡驱动来完成着色器的编译工作,也就是说,只要显卡驱动支持对GLSL的编译它就能运行,所以OpenGL能够跨平台
  • 核心模式与立即渲染模式:
    早期OpenGL使用立即渲染(Immediate mode,也就是固定渲染管线)容易使用和理解,但是效率太低。从OpenGL3.2开始废弃立即渲染模式,鼓励使用核心模式(Core-profile)。
    核心模式:要求使用者真正理解OpenGL和图形编程,有一些难度,然而提供了更多的灵活性,更高的效率,可以更深入理解图形编程。
  • 扩展:
    OpenGL的一大特性就是对扩展(Extension)的支持,当一个显卡公司提出一个新特性或者渲染上的大优化,通常会以扩展的方式在驱动中实现。
  • 状态机:
    OpenGL自身是一个巨大的状态机(State Machine):一系列的变量描述OpenGL此刻应当如何运行OpenGL的状态通常被称为OpenGL上下文(Context)。我们通常使用如下途径去更改OpenGL状态:设置选项,操作缓冲。最后,我们使用当前OpenGL上下文来渲染
  • 对象:
    OpenGL库是用C语言写的,同时也支持多种语言的派生,但其内核仍是一个C库。由于C的一些语言结构不易被翻译到其它的高级语言,因此OpenGL开发的时候引入了一些抽象层。“对象(Object)”就是其中一个
    使用对象的一个好处是在程序中,我们不止可以定义一个对象,并设置它们的选项,每个对象都可以是不同的设置在我们执行一个使用OpenGL状态的操作的时候,只需要绑定含有需要的设置的对象即可

二、OpenGL程序

 众所周知程序是运行在CPU上的,程序代码处于内存之中,在我们通常的理念中一般仅涉及CPU和内存,而使用OpenGL的渲染程序却有所不同,其涉及了GPU和显存,如下图所示:
在这里插入图片描述

从内存到显存

  • 我们的程序运行在CPU上,程序的数据储存在内存之中
  • 当我们需要渲染一个场景时,可能需要场景中物体的一些顶点数据、纹理数据、着色器参数等。这些数据是我们程序指定的,它们最初存储于外存中,当我们程序在CPU运行时我们将它们读入内存中
  • 显卡中有显存,这个缓冲区可以存储图形缓冲、深度缓存、纹理、顶点缓存等一系列渲染场景所需要的数据。利用这些数据,执行GPU的渲染指令,即可渲染我们想要的场景。
  • 那么问题来了,我们如何将内存中的数据传输到显存呢?
  • 毫无疑问这一切的答案都在OpenGL中,通过OpenGL有关函数,我们运行在CPU上的程序可以向显存中发送数据,将渲染场景所需的数据存储于显卡的显存缓冲区中

OpenGL渲染状态机

  • 当渲染所需数据已经传输到显存中时,我们如何执行GPU的渲染命令呢?
  • GPU的渲染指令是非常底层的,涉及显卡类型等硬件参数,这样复杂的指令让我们去调用是不可能的。但是我们有OpenGL。
  • 渲染是一套固定的流程,我们无法对接GPU的底层指令,那我们是否可以建立一个通用的、无关硬件的渲染模型呢?当然可以,这就是OpenGL。
  • 渲染是一个流程,这个过程中拥有很多可设置的选项,我们称这些选项为OpenGL的状态。所谓状态机,即拥有众多参数作为状态,当在不同的状态情况下会做出不同的反应,例如在不同的场景选项下呈现出不同的渲染结果。
  • OpenGL是一个完整的渲染状态机,Khronos组织制定并维护了OpenGL,换句话说:他们建立了OpenGL的状态机模型。这个模型是用于渲染的,它包含很多参数作为状态。针对这个模型,Khronos组织制定了OpenGL应该包含的函数,这些函数包括一些状态设置函数(State-changing Function)和状态应用函数(State-using Function)。使用状态设置函数可以改变OpenGL上下文即OpenGL的状态,使用状态应用函数会根据当前OpenGL的状态执行一些操作。
  • 如简介所说,OpenGL只是一个规范并没有具体的函数实现。如上文所说,OpenGL只是一个包含许多状态的渲染模型,其制定了一整套渲染所需的函数规范。那么我们如何搭建起OpenGL这个数学模型和GPU底层渲染指令间的桥梁呢?即OpenGL制定的函数该由谁实现呢?这通常是显卡开发商该思考的,显卡开发商针对OpenGL模型规范开发出具体显卡的OpenGL驱动程序,即在特定的OpenGL的状态下,显卡会执行特定的渲染指令
  • 如此一来,我们只需要和OpenGL这个通用的、和硬件无关的状态机进行交互,即可执行出我们所需的GPU渲染指令。而程序和OpenGL的交互无非是改变OpenGL的状态,例如设置OpenGL的选项,或操作缓冲区,通过调用状态设置函数实现。而执行渲染操作等行为通过状态应用函数实现。总之就是先设置渲染的状态,然后基于状态进行渲染操作。

三、GLFW和GLEW

 书接上文,OpenGL只提供渲染功能,核心API中没有创建窗口、键盘监听等输入概念,那么我们要进行渲染,肯定要把渲染后的画面呈现的电脑的窗口上,这该怎么办呢?
 使用GLFW即可,GLFW是一个跨平台的OpenGL应用框架,支持窗口创建,接受输入和事件等功能其成员以GLFW形式开头
 上文中提到扩展,当我们想要使用一个OpenGL函数时,需要查询当前平台是否支持这个函数,并且返回这个函数的指针。这毫无疑问是一件非常麻烦的事情,那么有什么方便的途径吗?
 使用GLEW即可,GLEW是一个基于OpenGL图形接口的跨平台的C++扩展库GLEW能自动识别当前平台所支持的全部OpenGL高级扩展涵数。只要包含glew.h头文件,就能使gl,glu,glext,wgl,glx的全部函数。GLEW支持目前流行的各种操作系统。其成员常常以gl开头。

四、其他

 本文参考并引用参考文章内容。
 本文内容仅为个人在OpenGL学习中的感想,如有不当之处请不吝赐教。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenGL入门教程之 深入理解 的相关文章

  • 给定焦点和相机主中心,如何创建透视投影矩阵

    我设法使用 OpenCV 获取相机的内在和外在参数 因此我有 fx fy cx 和 cy 我还有屏幕 图像的宽度和高度 但是如何根据这些参数创建 OpenGL 透视投影矩阵呢 glFrustum 展示了如何在给定 Z 近 Z 远以及图像宽度
  • VBO - 没有指数化的指数化

    我正在尝试将 VBO 与元素数组缓冲区一起用于我的三角形 如下所示 glBindBuffer GL ARRAY BUFFER g Buffer 0 glVertexPointer 3 GL FLOAT 0 BUFFER OFFSET 0 g
  • libgdx 中帧缓冲区的结果不明确

    我得到以下奇怪的结果帧缓冲区 http libgdx badlogicgames com nightlies docs api com badlogic gdx graphics glutils FrameBuffer htmllibgdx
  • 如何以编程方式在 qml 中渲染 vtk 项目?

    到目前为止 我了解到我们在 QML 中有两个线程 我们的主应用程序线程和我们的 场景图 线程 http doc qt io qt 5 qtquick visualcanvas scenegraph html http doc qt io q
  • 对 VBO 中的特定三角形使用不同的纹理

    我有 9 个由三角形组成的四边形 如下所示 我在用着VBO存储有关它们的数据 它们的位置和纹理坐标 我的问题是 是否可以仅使用一个来使四边形 5 具有与其余四边形不同的纹理VBO and shader 绿色代表纹理 1 黄色代表纹理 2 到
  • 没有着色器的 OpenGL

    我已经阅读了一些教程来编写以下代码 唯一的区别是原始教程使用 SDL 而不是 GLEW 我不明白这段代码有什么问题 它可以编译 但我没有看到三角形 教程也没有使用着色器 include
  • 如何将 3D 图像输出到 3D 电视?

    我有一台 3D 电视 如果我不至少尝试让它显示我自己创作的漂亮 3D 图像 我就会逃避我的责任 作为一个极客 我之前已经完成了非常基本的 OpenGL 编程 因此我了解所涉及的概念 假设我可以为自己渲染一个简单的四面体或立方体并使其旋转一点
  • 纹理openGl。 C++、qt

    我试图用草纹理覆盖我的地形 由高度图制成 但它没有按预期工作 我什至无法在简单的 GL QUAD 上获取纹理 结果是多色网络 void GLWidget initializeGL glEnable GL TEXTURE 2D 在 QGLwi
  • 三角形未在 OSX 上的 OpenGL 2.1 中绘制

    我正在学习有关使用 OpenGL 在 Java 中创建游戏引擎的教程 我正在尝试在屏幕上渲染一个三角形 一切运行良好 我可以更改背景颜色 但三角形不会显示 我还尝试运行作为教程系列的一部分提供的代码 但它仍然不起作用 教程链接 http b
  • OpenGL:调试“单通道线框渲染”

    我正在尝试实现论文 单通道线框渲染 它看起来很简单 但它给了我所期望的厚暗值 论文没有给出计算海拔高度的确切代码 所以我按照自己认为合适的方式进行了操作 代码应该将三个顶点投影到视口空间中 获取它们的 高度 并将它们发送到片段着色器 片段着
  • 使用 glDrawElements 时在 OpenGL 核心配置文件中选取三角形

    我正在使用 glDrawElements 绘制三角形网格 并且希望能够使用鼠标单击来拾取 选择三角形 三角形的网格可以很大 在固定功能 OpenGL 中 可以使用 GL SELECT http content gpwiki org inde
  • 不理解 gluOrtho2D 函数

    我不能做什么gluOrtho2D 函数是做什么的 是否将原点固定在 OpenGL 窗口上的某个特定点或其他位置 这是因为gluOrtho2D 1 1 1 1 将原点固定在窗口的中间 如果它在某个时刻没有修复原点 那么有什么方法可以修复原点
  • 使用 OpenGL 着色器进行数学计算 (C++)

    我有一个矩阵 例如 100x100 尺寸 我需要对每个元素进行计算 matrix i j tt 8 5例如 我有一个巨大的矩阵 我想使用 OpenGL 着色器来实现该算法 我想使用着色器 例如 uniform float val unifo
  • glut 库中缺少 glutInitContextVersion()

    我正在练习一些 opengl 代码 但是当我想通过以下方式强制 opengl 上下文使用特定版本的 opengl 时glutInitContextVersion 它编译过程失败并给出以下消息 使用未声明的标识符 glutInitContex
  • 如果我用opengl绘图的话SDL Renderer就没用了吗?

    我正在学习 SDL2 但我也在使用使用 OpenGL 调用的 imgui 库 从我在网上各种博客上读到的内容来看 我无法轻松混合 SDL2 渲染器和 opengl 调用 我要么使用其中之一 要么使用另一个 我读过的大多数教程都使用渲染器 所
  • 无法在 WSL2 上运行 OpenGL

    我尝试在 WSL2 上运行 OpenGL 代码 但在尝试运行可执行文件时出现以下错误 GLFW error 65543 GLX Failed to create context GLXBadFBConfig Unable to create
  • 将四元数旋转转换为旋转矩阵?

    基本上 给定一个四元数 qx qy qz qw 我如何将其转换为OpenGL旋转矩阵 我也对哪个矩阵行是 向上 向右 向前 等感兴趣 我有一个四元数的相机旋转 我需要在向量中 以下代码基于四元数 qw qx qy qz 其中顺序基于 Boo
  • GL_CULL_FACE使所有对象消失

    我正在尝试在 openGL3 3 中创建一些简单的多边形 我有两种类型的对象 具有以下属性 对象 1 10 个顶点 按顺序在下面列出 存储在GL ARRAY BUFFER并使用GL TRIANGLE FAN v x y z w v 0 0
  • OpenGL缓冲区更新[重复]

    这个问题在这里已经有答案了 目前我正在编写一个模拟水的程序 以下是我所做的步骤 创建水面 平面 创建VAO 创建顶点缓冲区对象 在其中存储法线和顶点 将指针绑定到此 VBO 创建索引缓冲区对象 然后我使用 glDrawElements 渲染
  • Glew+GLFW Win32 无依赖项 Visual Studio

    是否可以在不将文件复制到 C 的情况下构建并链接 Glew 和 GLFW 我找不到任何说明如何在不将 DLL 复制到 C 上的 Visual Studio 目录的情况下使用这些库的文档 我只想包含项目目录中所需的所有 dll 和 lib 文

随机推荐

  • 2018-12-13 LeetCode Q5 最长回文子串

    5 最长回文子串 给定一个字符串 s 找到 s 中最长的回文子串 你可以假设 s 的最大长度为 1000 示例 1 输入 babad 输出 bab 注意 aba 也是一个有效答案 示例 2 输入 cbbd 输出 bb 暴力解法 6004ms
  • 关于linux进程间的close-on-exec机制

    转载请注明出处 帘卷西风的专栏 http blog csdn net ljxfblog 前几天写了一篇博客 讲述了端口占用情况的查看和解决 关于linux系统端口查看和占用的解决方案 大部分这种问题都能够解决 在文章的最后 提到了一种特殊情
  • 判断字符串的两半是否相似(1704.leetcode)-------------------c++实现

    判断字符串的两半是否相似 1704 leetcode unordered map c 实现 题目表述 给你一个偶数长度的字符串 s 将其拆分成长度相同的两半 前一半为 a 后一半为 b 两个字符串 相似 的前提是它们都含有相同数目的元音 a
  • Tensorflow学习(五)——多任务学习验证码识别实战

    一 验证码生成 验证码生成脚本 使用captcha包提供的ImageCaptcha方法 from captcha image import ImageCaptcha import sys import random import numpy
  • 成功解决笔记本重装系统后没有无线网

    笔记本重装系统后没有无线网 一般的解决思路就是下载笔记本厂家官方提供的各类驱动程序 重新安装驱动 驱动下载的地址 建议到各个厂家的官网上去寻找驱动资源 以本人的笔记本型号为例 点击window R 然后输入dxdiag运行 然后找到该官方开
  • 用js/react写一个计算器

    效果图如下 直接上代码 目录如下 Button和Text是自己封装的Button组件和Input组件 Button index js import react Component from react import index css cl
  • 图像风格迁移cvpr2020_今日 Paper

    目录 CurricularFace 深度人脸识别的适应性课程学习损失 MaskGAN 多样和交互的面部图像操作 结合检测和跟踪的视频人体姿态估计 通过解纠缠表示的局部面部妆容迁移 基于自动生成的训练数据进行大规模事件抽取学习 Curricu
  • 【UiBot】RPA定时触发:机器人如何在指定时间执行任务?

    Q RPA机器人如何在指定时间点执行任务 A 用流程机器人 UiBot Worker 设置定时触发 人机交互的流程机器人 UiBot Worker 除了手动运行流程之外 还提供了 触发器 的功能 可以在满足一定条件时 有计划 有选择性地执行
  • C++定义二维数组并赋值,亲测可用

    代码在这里 拿走不谢 include
  • IDEA springboot项目导出jar包及运行jar包

    首先点击Terminal 在Terminal下输入 mvn clean package 看到以下这个提示则是打包成功 接着咱们可以在自己的项目下看到打包成功的jar包 如图 运行jar包 我的jar包位置如下 写一个bat文件 里面的内容为
  • 实时监控Cat之旅~配置Cat集群需要注意的问题

    在配置cat集群时 有一些设置是我们应该注意的 从它的部署文档中我们可以看到相关信息 但说的还不够明确和重要 大叔今天总结一下Cat集群配置的注意事项 服务端datasources xml用来设置连接的mysql 集群里的服务器对这项配置是
  • pyecharts运行后产生的html文件用浏览器打开空白

    引用 https github com pyecharts pyecharts issues 503 使用logging日志打印代码错误 coding utf 8 from future import unicode literals im
  • Mageia 9 发布:搭载 Linux 内核 6.4,支持 PulseAudio

    导读 Mageia 最初是 Mandriva Linux 的一个分支 但现在已经发展成全面的 独立 Linux 发行版 从 2010 年以来 Mageia 已经成为一个用于桌面或服务器的稳定且安全的操作系统 并且定期更新 它的近期的发布公告
  • C语言排序算法实现

    C语言实现各种排序算法 冒泡排序 选择排序 插入排序 希尔排序 插入方式 非交换方式 快速排序 归并排序 分治思想 基数排序 桶排序 基数排序的基本思想 典型的空间换时间方式 冒泡排序 include
  • moviepy 生成的视频只有声音没有图像

    问题描述 PDF转成视频 用moviepy 将图片生成视频的时候 生成的视频 有些播放器 播放只有声音没有图像 解决方案 查看源码后发现在 ffmpeg writer py 文件里面有一段这样的代码 if codec libx264 and
  • 在线AI日语视频音频翻译中文字幕

    新番视频没有字幕 AI日语字幕识别让你先睹为快 蓝海智能在线AI工具 niceaitools com languageTra 目前价格是每视频音频分钟0 42元 具体使用方法如下 1 格式工厂处理 把你的日语视频或音频文件 通过格式工厂处理
  • VBA 自定义函数 库存消耗截止

    两个自定义函数 按照库存 计算哪一周库存能消耗完 标出周 自定义函数 按照库存 计算消耗完的那一周实际消耗多少数量 自定义函数 从消耗完的那一周开始算起 后面的周消耗数量都变为0 按钮 Function HaoJin StockQty As
  • Pytorch中常用的损失函数

    Pytorch中常用的损失函数 回归 nn L1Loss nn MSELoss 分类 nn CrossEntropyLoss 回归 nn L1Loss 平均绝对误差 也称L1范数损失 计算预测值与真实值之间的误差绝对值 L 1 L o s
  • python中模块,包,库的概念

    https www cnblogs com mlgjb p 7875494 html 模块 就是 py文件 里面定义了一些函数和变量 需要的时候就可以导入这些模块 包 在模块之上的概念 为了方便管理而将文件进行打包 包目录下第一个文件便是
  • OpenGL入门教程之 深入理解

    一 OpenGL简介 OpenGL是一种用于渲染2D 3D矢量图形的跨语言 跨平台的应用程序编程规范 OpenGL包含一系列可以操作图形和图像的函数 但OpenGL没有实现这些函数 OpenGL仅规定每个函数应该如何执行以及其输出值 类似接