OpenGL学习笔记【1】——简介

一、OpenGL概念

        OpenGL (Open Graphics Library,译名:开放式图形库开放式图形库) 是一种用于渲染 2D 和 3D 图形跨语言、跨平台编程接口(API)

二、OpenGL跨语言

       OpenGL 是一个 C 语言库,因此理解 C 语言(或 C++)的基本知识是非常有用的。然而,许多其他语言也有 OpenGL 的绑定,值得一提的包括:

(1)JavaScript绑定的WebGL(基于OpenGL ES 2.0在Web浏览器中的进行3D渲染的API);

(2)C绑定的WGL、GLX和CGL;

(3)iOS提供的C绑定;

(4)Android提供的Java和C绑定;

所以你可以选择你最熟悉的语言来学习。

三、OpenGL跨平台

        OpenGL 提供了一组底层的图形渲染函数,严格规定了每个函数该如何执行,以及它们的输出值,这些函数可以直接与图形硬件交互,实现高效的图形渲染。至于内部具体每个函数是如何实现(Implement)的,将由OpenGL库的开发者(通常是显卡的生产商)自行决定。   

     OpenGL被设计为只有输出的,只提供渲染功能,核心API没有窗口系统、音频、打印、键盘/鼠标或其他输入设备的概念,也正是这种限制使得OpenGL允许进行渲染的代码完全独立于它运行的操作系统,允许跨平台开发。

    OpenGL没有提供着色器编译器,而是由显卡驱动来完成着色器的编译工作,也就是说,只要显卡驱动支持对GLSL的编译它就能运行,所以能够跨平台具有强大的通用性和可移植性,可以将其轻松的移植在多个不同的平台上进行二次开发。因为OpenGL本身是一个与硬件无关的软件接口,所以,通用于市面上较为流行的平台:比如,Windows、Unix、Linux、MacOS等。

四、OpenGL扩展特性

       OpenGL的一大特性就是对扩展(Extension)的支持,当一个显卡公司提出一个新特性或者渲染上的大优化,通常会以扩展的方式在驱动中实现。扩展可能会引入新功能和新常量,并且可能放松或取消现有的OpenGL函数的限制。然后一个扩展就分成两部分发布:包含扩展函数原型
头文件和作为厂商的设备驱动。供应商使用扩展公开自定义的API而无需获得其他供应商或Khronos Group的支持,这大大增加了OpenGL的灵活性。

    每个扩展都与一个简短的标识符
关系,该标识符基于开发公司的名称。例如,英伟达(nVidia)的标识符是NV。如果多个供应商同意使用相同的API来实现相同的功能,那么就用EXT标志符。这种情况更进一步,Khronos Group的架构评审委员(Architecture Review Board,ARB)正式批准该扩展,那么这就被称为一个“标准扩展”,标识符使用ARB。

       OpenGL是一个不断进化的API,新版OpenGL规范会定期由Khronos Group发布,新版本通过扩展API来支持各种新功能。OpenGL 更像是一种显卡驱动标准,由各个硬件厂家适配,各个硬件厂商根据 OpenGL 接口规范编撰对应的驱动,换句话说,对于各个硬件厂商 OpenGL 确实是一个基于 GPU 的软件实现,但是对于普通的应用层开发者 OpenGL 就是一个由硬件厂商提供的驱动程序罢了。

       在OpenGL的发展历程中,总是兼顾向下兼容的特性,但是到了一定的程度之后,这些旧有的OpenGL API不再适应时代的需要,还有一些扩展并不是驱动一定要实现的扩展,这些被统一划入可选的Compatibility Profile;而由OpenGL规范规定必须支持的扩展,则是Core Profile,想要支持先进的OpenGL,相应的Core Profile扩展必须被实现。

五、OpenGL 上下文

5.1、Context上下文的理解

   OpenGL Context,中文解释就是OpenGL的上下文。OpenGL只是图形API,它只负责渲染,渲染指令执行所需要的那些东西就是Context

     OpenGL在渲染的时候需要一个Context来记录了OpenGL渲染需要的所有信息和状态,可以把它理解成一个大的结构体,它里面记录了当前绘制使用的颜色、是否有光照计算以及开启的光源等。

       对于OpenGL的上下文的理解看到一个比较形象的比喻:好比一个画家在画图,OpenGL就是这个画家(可以发出各种指令),而画家作画需要用到的画笔、画布等东西就是Context,Context的切换就像画家同时作多幅画,当要画另外一幅画的时候,画家需要放下原来的画笔,拿起了另外一幅画所需要的画笔。

5.2、Context上下文的历史版本

     (1)在OpenGL 3.0版本之前,OpenGL创建Context都是一致的;

     (2)但是从OpenGL 3.0开始,为了摆脱历史的“包袱”,OpenGL想要彻底的废弃掉之前的许多特性,但是无奈市面上已经有大量依赖OpenGL之前版本的代码,导致OpenGL维护小组的这一想法难以付诸实施, OpenGL 3.0 引入了废弃机制,标记了许多OpenGL的函数是废弃的(但是3.0并没有真正移除它们,也就是说3.0版本仍然是一个可以向后兼容的Context);

    (3)在OpenGL 3.1的发布删除了之前3.0标记的过时函数(固定管线相关的函数),但是为了之前的OpenGL代码可用, 引入了一个扩展ARB_compatibility,这个扩展可以让OpenGL 3.1支持之前的OpenGL固定管线的内容,

  (4)OpenGL 3.2中开始引入了OpenGL Context的一些分类,正式引入了模式的概念(Profile),之后随着版本发展到OpenGL 3.3,一切算是确定下来。

    (5)到了OpenGL3.3之后,OpenGL的context profile分为了两个版本,core pfofile和compatibility profile,前者表示删除任何标记为deprecated(弃用)的功能,后者则表示不删除任何功能。

  5.3、创建上下文context使用的图形界面框架

     不同的操作系统,都有各自的上下文创建方法和设置当前上下文的API,最简单的上下文可以通过Glut或是Glfw创建,相比较而言glfw是一个轻量级的图形界面框架,托管在 www.glfw.org,现在非常的活跃,如果新入门可以优先考虑glfw,相关的教程网上也比较多。

  使用glfw创建一个窗口,并使该窗口的上下文成为当前上下文:

 // 设置窗口提示glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // OpenGL主版本号glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // OpenGL次版本号glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 使用核心模式// 创建窗口GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL);if (window == NULL) {glfwTerminate();return -1;}// 使窗口上下文当前上下文glfwMakeContextCurrent(window);

    创建了绘制上下文,并设置为当前上下文以后,还不能使用OpenGL最新的特性,

一般我们使用Glfw库,首先初始化GLFW库,即需要调用glfwInit(),:得到OpenGL随显卡驱动一起发布的新特性的函数入口地址。

   //初始化GLFW,得到OpenGL随显卡驱动一起发布的新特性的函数入口地址glfwInit();//下面glfwWindowHint函数配置GLFW====================glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);//设置主板本号为3glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);//设置副版本号为3glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//核心模式(Core-profile)//参数1:选项的名称。可以从很多以GLFW_开头的枚举值中选择//参数2:接受一个整型,用来设置这个选项的值//设置版本号为3.3版本,需要告诉GLFW我们要使用的OpenGL版本是3.3//GLFW会在创建OpenGL上下文时做出适当的调整。//这也可以确保用户在没有适当的OpenGL版本支持的情况下无法运行//如果你使用的是Mac OS X系统,你还需要解除下面这行代码的注释//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);// 创建窗口对象GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL);if (window == NULL) {//创建窗口对象失败,打印错误信息std::cout << "Failed to create GLFW window" << std::endl;//需要引用iostream头文件//终止GLFWglfwTerminate();return -1;}//参数1:窗口宽//参数2:窗口高//参数3:窗口标题(名字)//参数4,参数5暂时忽略//返回值类型:GLFWwindow*:我们会在其它的GLFW操作中使用到// 使窗口上下文当前上下文glfwMakeContextCurrent(window);

 5.4、线程私有

        OpenGL的绘制命令都是作用在当前的Context上,这个Current Context是一个线程私有(thread-local)的变量,也就是说如果我们在线程中绘制,那么需要为该线程制定一个Current Context的,当多个线程参与绘制任务时,需要原线程解绑再重新绑定新的线程。多个线程不能同时指定同一个Context为Current Context,否则会导致崩溃。

六、OpenGL的开发模式

6.1、立即渲染模式 (Compatibility Profile)

     Compatibility Profile兼容之前的OpenGL固定管线的内容,也可以使用Core Profile中的内容。

      早期的OpenGL使用立即渲染模式(Immediate mode,也就是固定渲染管线),OpenGL 3.2版本以前都是该模式,该模式固定以glBegin开始绘制,以glEnd结束绘制,明确规定了先做什么后做什么,有一套固定的函数和执行流程,开发者可以“傻瓜式”的使用这些函数来实现渲染效果,它面向过程,比较简单、易于理解,但是灵活性(固定的执行流程)和性能都较差(CPU与GPU通信频繁)。

6.2、 核心模式(Core Profile)

          核心模式即着色器渲染模式,从3.2版本开始废弃了立即渲染模式,开发者通过编写shader来完成图形的渲染,常见的shader有vertex shader和fragment shader,这种模式较为灵活和高效,但是比较复杂。

    从OpenGL3.2开始,规范文档开始废弃立即渲染模式,并鼓励开发者在OpenGL的核心模式(Core-profile)下进行开发,这个分支的规范完全移除了旧的特性。当使用OpenGL的核心模式时,OpenGL迫使我们使用现代的函数。当我们试图使用一个已废弃的函数时,OpenGL会抛出一个错误并终止绘图。

   现今,更高版本的OpenGL已经发布(写作时最新版本为4.6),你可能会问:既然OpenGL 4.6 都出来了,为什么我们还要学习OpenGL 3.3?答案很简单,​所有OpenGL的更高的版本都是在3.3的基础上,引入了额外的功能,并没有改动核心架构。​新版本只是引入了一些更有效率或更有用的方式去完成同样的功能。因此,所有的概念和技术在现代OpenGL版本里都保持一致。当你的经验足够,你可以轻松使用来自更高版本OpenGL的新特性


    除了core profile(核心渲染模式)和compatibility profile(立即渲染模式)外,还有一种模式:foward compatibility,这个表示所有标记为deprecated的函数都禁用,这个模式只对opengl3.0及以上的版本有效。但这个选项对OpenGL 3.2+ compatibility Profile Context没有任何作用。

七、OpenGL需要了解的技术和知识

1、计算机图形学基础:理解基本的计算机图形学概念,如向量、矩阵、变换、光照、纹理等,可以帮助你更好地理解和使用 OpenGL。这些主题通常在计算机图形学的入门课程中介绍。
2、线性代数:在计算机图形学中,我们经常需要处理 2D 或 3D 空间中的点和向量,这需要一些线性代数的知识。至少要熟悉向量的加法、减法和点积,以及如何使用矩阵进行变换。
3、计算机硬件:理解计算机硬件,特别是图形处理器 (GPU) 的基本工作原理,可以帮助你理解 OpenGL 的许多设计决策,以及为什么某些操作比其他操作更快。
4、IDE 和调试工具:熟悉一个集成开发环境(如 Visual Studio、Eclipse 或者 PyCharm)将会对你编写和调试代码非常有帮助。此外,学习使用像 gDEBugger 或者 RenderDoc 这样的 OpenGL 调试工具也是很有用的。
5、API 文档和教程:熟悉 OpenGL 的官方文档(或你正在使用的语言绑定的文档)。这将是你在学习和使用 OpenGL 时的重要资源。同时,还有许多优秀的在线教程,如https://learnopengl.com/Getting-started/OpenGL;https://learnopengl-cn.github.io/.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/757998.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux-线程同步

文章目录 前言一、为什么要线程同步&#xff1f;二、线程同步pthread_cond_initpthread_cond_destroypthread_cond_wait、pthread_cond_signal和 pthread_cond_broadcast 三、示例代码 前言 上节课学习了线程互斥&#xff0c;这节课针对线程互斥内容在做进一步的补充和完善&am…

【Python 48小时速成 3】输入与输出

在 Python 中&#xff0c;输入和输出通常通过内置函数来实现。主要的输入函数是 input()&#xff0c;用于从用户获取输入&#xff0c;而输出函数则是 print()&#xff0c;用于将结果打印到控制台。以下是简单的代码示例演示了输入和输出&#xff1a; # 输入示例 name input(&…

[C语言]一维数组二维数组的大小

对于一维数组我们知道取地址是取首元素的地址&#xff0c;二维数组呢&#xff0c;地址是取第一行的地址&#xff0c;sizeof(数组名)这里计算的就是整个数组的大小&#xff0c;&数组名 表示整个数组&#xff0c;取出的是整个数组的地址&#xff0c;显示的是数组的首元素 记…

网络工程师练习题2

网络工程师 将专用IP地址转换为公用IP地址的技术是&#xff08;&#xff09;。 A.ARPB.DHCPC.UTMD.NAT 【答案】D 【解析】概念题&#xff0c;NAT技术将源地址从内部专用地址转换成可以在外部Internet上路由的全局IP地址。 R1、R2是一个自治系统中采用RIP路由协议的两个相…

Java基础知识总结(8)

StringBuilder类(是线程不安全的) StringBuffer 和 StringBuilder二者及其相似&#xff0c;下面是构造方法&#xff1a; StringBuilder StringBuilder()创建空对象&#xff0c;空的字符序列 StringBuilder StringBuilder(StringBuilder builder)传入对象创造字符序列 Strin…

【计算机网络篇】物理层(4)信道的极限容量,信道复用技术

文章目录 &#x1f354;信道的极限容量&#x1f6f8;造成信号失真的主要因素⭐码元的传输速率 &#x1f6f8;奈氏准则&#x1f6f8;香农公式&#x1f388;练习 &#x1f5d2;️小结 &#x1f354;信道复用技术⭐常见的信道复用技术&#x1f388;频分复用FDM&#x1f388;时分复…

时序分解 | Matlab实现GWO-CEEMDAN基于灰狼算法优化CEEMDAN时间序列信号分解

时序分解 | Matlab实现GWO-CEEMDAN基于灰狼算法优化CEEMDAN时间序列信号分解 目录 时序分解 | Matlab实现GWO-CEEMDAN基于灰狼算法优化CEEMDAN时间序列信号分解效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.CEEMDAN方法的分解效果取决于白噪声幅值权重(Nstd)和噪声添…

【刷题】滑动窗口入门

送给大家一句话&#xff1a; 那脑袋里的智慧&#xff0c;就像打火石里的火花一样&#xff0c;不去打它是不肯出来的。——莎士比亚 滑动窗口入门 认识滑动窗口Leetcode 209. 长度最小的子数组题目描述算法思路 Leetcode 3. 无重复字符的最长子串题目描述算法思路 Leetcode 1004…

部署应用到K8s集群(未完)

&#xff08;等熟悉一番再来写&#xff0c;因为按小时结算的。。。&#xff09; 1 、 kubectl run 启动 nginx 应用 kubectl run nginx --imagenginx:latest 2、将本地机器的80端口转发到集群中名为nginx的Pod的80端口 kubectl port-forward --address 0.0.0.0 pod/nginx 80:8…

AHI对MySQL性能的影响

MySQL中出现很多latch锁&#xff0c;而这个很大程度上和MySQL自适应hash索引有关。 AHI概述 MySQL InnoDB存储引擎的自适应哈希&#xff08;Adaptive Hash Index&#xff0c;下简称AHI&#xff09;功能 若用户的访问模式基本都是类似KV操作的点查询&#xff08;point select&…

es bulk批量操作简单实例

&#xff08;1&#xff09;定义 bulk允许在单个步骤中进行多次create、index、update或delete请求。 bulk与其他的请求体格式稍有不同&#xff0c;如下所示&#xff1a; { action: { metadata }}\n { request body }\n { action: { metadata }}\n { request body …

FPGA高端项目:FPGA基于GS2971+GS2972架构的SDI视频收发+HLS图像缩放+多路视频拼接,提供4套工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐本博主所有FPGA工程项目-->汇总目录本博已有的 SDI 编解码方案本方案的SDI接收发送本方案的SDI接收图像缩放应用本方案的SDI接收纯verilog图像缩放纯verilog多路视频拼接应用本方案的SDI接收OSD动态字符叠加输出应用本方案的SDI接收HLS…

社会责任管理体系审核员

为满足国家越来越多的各种类型、各种规模的企业组织能按照 GB/T 39604-2020《社会责任管理体系要求及使用指南》国家标准建立相应制度&#xff0c;助力组织实现其社会责任管理体系的预期结果&#xff0c;以及满足各类组织对社会责任管理体系实践的需要&#xff0c;了解社会责任…

rr 为什么会出现幻读?

首先要知道mvcc的两个概念&#xff0c; 1. undolog 可以理解为就是一个数据快照&#xff0c;里面包含数据&#xff0c;当前事务ID&#xff08;相当于版本号&#xff09;和上一个快照的指针。类似链表。 2. readview 可以理解为事务 读快照&#xff0c; 记录当前事务ID&#xff…

工作需求iview 组件的使用

加油&#xff0c;新时代打工人&#xff01; 源码下载地址 <template><div mouseenter"mousein true" mouseleave"mousein false"><el-input type"text" clearable autocomplete"off" v-model"searchDoc.code&q…

【CSS】html滚动条相关

1.滚动条样式 ::-webkit-scrollbar {width: 10px;height: 10px;z-index: 101; } ::-webkit-scrollbar-thumb {border-radius: 5px;background: #cecece; } ::-webkit-scrollbar-track {// background: #f5f5f5be;background: rgba(33, 85, 163, 0); } ::-webkit-scrollbar-but…

Rust 基于 await、async 的异步编程和纤程、协程的实现

一、Rust 的异步编程 Rust 通过 await、async 实现了其他语言中纤程、协程的机制。下面是一个使用async和await的Rust示例代码。这个示例展示了如何异步地读取文件内容。 首先&#xff0c;确保你的Cargo.toml文件包含了tokio库的依赖&#xff0c;如下&#xff1a; [dependen…

python汽车租赁系统的设计与实现flask-django-php-nodejs

困扰公司的许多问题当中,汽车租赁管理一定是公司不敢忽视的一块。但是管理好汽车租赁又面临很多麻烦需要解决,例如有几个方面:第一,公司往往汽车数量都比较多,如何保证能够管理到每一汽车;第二,如何在工作琐碎,记录繁多的情况下将汽车租赁的当前情况反应给公司领导相关部门决策…

Python之Web开发中级教程----ubuntu中下载安装Postman

Python之Web开发中级教程----ubuntu中下载安装Postman PostMan 是一款功能强大的网页调试与发送网页 HTTP 请求的 Chrome 插件&#xff0c;可以直接去对我们写出来的路由和视图函数进行调试&#xff0c;作为后端程序员是必须要知道的一个工具。 查看ubuntu系统中是否已经安装了…

零基础学华为ip认证难吗?华为认证费用多少?

零基础学华为ip认证难吗&#xff1f; 首先&#xff0c;零基础的学习者可以通过系统的学习&#xff0c;逐步掌握网络基础知识和技能。可以通过阅读教材、参加培训课程、进行实践操作等方式&#xff0c;不断提升自己的知识和技能水平。同时&#xff0c;学习者还可以利用华为提供的…