OpenGL入门教程——PT1

news2024/12/23 15:02:17

由于自己不是计算机图形学出身,所以采纳了一些教材、博客、GPT的综合答案,尽可能作为一篇认识图形学,学会OpenGL简单函数库的博客!多多包涵

我会从最基础的显示相关知识逐步导入OpenGL

一、屏幕是如何工作的,为什么电子屏幕能够显示出内容呢?

一般情况下,我们的手机屏幕和电脑屏幕都是有相同的工作原理的,只不过内部的一些硬件和参数有差别,所以可以归类总结,如下:

电子屏幕有几个组件构成:

        液晶层:液晶层位于两个透明电极中间,是由两个平行的玻璃或其他材料组成,液晶的物理特性是,当通电的时候,排列变有序,不通电的时候变混乱,阻止光线通过

        透明电极:位于液晶层的两侧,通过电流来创建电场,就是给液晶通电用的

        色彩滤光器:一种光学器件,用于在光线通过的时候选择性的透过或者阻挡不同波长的光,从而实现对光的颜色的调控

        光源:在电子显示屏的背部提供光源,一般是采用阴冷极荧光灯或者Led灯

所以从上面的信息可以知道,我们的电子显示屏工作原理就是在电场的作用下,利用液晶分子的排列方向发生变化,产生点、线、面,使外光源透光率改变(调制),完成电一光变换,再利用R、G、B三基色信号的不同激励,通过红、绿、蓝三基色滤光膜,完成时域和空间域的彩色重显,配合背部灯管构成画面。

二、如何在屏幕上显示我们输入的信息?

通过标题一我们知道,从硬件层面,我们的显示器就是通过电流刺激,使得液晶分子的排列方式产生变化,那我们是能够产生生动的各种画面呢?

        1:我们平时在电脑上看电影实际上就是把接收到的各种视频信号(比如广播电视信号,卫星信号,或者光盘存储的视频文件,亦或是在线加载),这些视频信号可以通过显示器的输入接口(HDMI,USB,DP)连接到显示器上

        2:视频解码,解码就是把压缩编码的视频数据还原成原始的图像或者声音信号,根据信号源的不同,显示器可能会使用不同的解码器进行解码(包含采样,量化,等步骤),因为我们在录制或者制作视频的时候,为了提高我们的传输效率,视频文件通常会使用压缩编码算法将连续的图像帧进行压缩,会使用汇编等底层硬件语言进行编码,不多冗余。

        3:图像处理,解码后的视频图像被传送到图像处理单元,图像处理单元负责对图像进行处理 和优化,以提高图像质量和显示效果

        4:帧缓冲,处理后的图像就被存储到了帧缓冲器,也成为帧缓存或者显存,这块区域是一块内存区域,用于存储图像的像素数据,图像帧缓冲器保存了当前要在屏幕上显示的图像帧,每个图像帧由一系列的像素组成,而每个像素则包含有关其颜色和亮度等信息。帧缓冲器通过存储这些像素数据,提供了对图像进行读取、写入和更新的能力。

        5:显示控制,根据帧缓冲器中的图像数据,控制电视屏幕上每个像素点的亮度和颜色

        6:屏幕刷新,电视屏幕上的每个像素点通过显示控制单元按照刷新率周期刷新屏幕上的像素,使得图像连续显示出来

三、键盘输入为什么能够显示在计算机屏幕上?

        1:键盘输入,当在键盘输入文本的时候,触发键盘的相应电路,每个按键都有对应的字符

        2:电信号传输,键盘内部的电路会把相应的按键信息转换成电信号,这些电信号通过连接电缆传输到计算机的输入接口

        3:操作系统接收,接收到传入的电信号,操作系统符合管理和处理输入信号

        4:字符编码,操作系统接收到电信号以后,把电信号转换成相应的字符,字符编码是一一种将字符映射为数字代码的方式,比如ASCII,Unicode等

        5:应用程序接收处理,操作系统把字符或者按键发送给应用程序,如文本编辑器,应用程序将对字符进行相应的文本处理

        6:图形处理,当应用程序更新文本后,它将通知操作系统和图形处理系统进行图形渲染,把文本转化成图形数据,以及计算和排列文字位置,字体,样式等

        7:帧缓冲器更新,如上,我们介绍过帧缓冲器,把存储在帧缓冲器中的像素数据更新

        8:显卡处理,显卡从帧缓冲器中读取图像数据,将其转化为电信号发送到显示器

        9:显示器输出,显示器接收到电信号后,根据信号指令来更新屏幕上的像素点,最终在显示器上显示出相应的文字

四、为什么我们需要显卡?

从上面的内容我们知道,如果我们只是通过计算机来看视频,或者进行一些逻辑处理,或者显示一些简单的内容,完全可以通过帧缓冲器一样,你只需一个很大内存的内存条,那为什么我们需要引进显卡呢?

从最简单的需求开始,我们先引进一些图形学的知识来解释,假设我们需要在屏幕上绘制一个旋转的立方体

        1:我们需要先定义立方体的模型数据,包括顶点坐标、法线向量,纹理坐标等

        2:然后需要定义着色器程序,用于计算顶点和片元的属性,比如位置、颜色、光照,所以绘制一个立方体至少需要一个顶点着色器和片元着色器,顶点着色器负责计算顶点的位置和变换,片元着色器负责计算像素的颜色

        3:创建帧缓冲器,用来存储图像帧数据的内存区域,如上

        4:设置视口和投影矩阵,视口定义了绘制区域的大小和位置,投影矩阵定义了场景的透视或者正交投影,这些参数可以确定立方体在屏幕上的位置和大小

        5:在每一帧中更新立方体的旋转变换矩阵,通过修改矩阵参数就能实现不同旋转速度和方向

我们现在来缕一缕,如果交给CPU来处理上述的步骤,也是可以的,但是当有成千上万个旋转的方块呢?就是需要成千上万个重复的顶点坐标变换,像素着色和纹理采样工作,由于CPU中的计算单元占比并不多,也就是ALU,这受限于计算机的设计初衷,CPU的指令比较复杂,可以实现很多核心功能,相当于一个爱因斯坦,而GPU就是相当于普通人,用来做大量简单重复的工作,它内部有大量的计算单元,所以矩阵变换这种小事儿,就交给GPU来做吧!

五、好了,我们有显卡了,可是渲染是什么?

当我们得到了第一块显卡,我们可以用显卡来做一个飞机大战的游戏,就是通过控制屏幕的像素点,那我们就需要了解一些渲染管线的知识了,什么是渲染???什么是渲染管线??

        1:渲染,Rendering,又名呈现,绘制,我觉得我们一开始把Rendering这个单词翻译成呈现,可能会有更多人理解它,呈现就是展示,所以我们的渲染就是把我们的一些几何数据,比如顶点坐标计算,光照计算,纹理映射等,转化成为我们能够肉眼看到的图形,就是把一堆数据经过加工,变成一个活灵活现的样子

        2:渲染管线,有了渲染以后,自然就需要渲染管线,渲染管线就是对渲染整个流程处理的统称,我们的常规渲染流程包括:

        ①顶点处理阶段(Vertex Processing Stage),也就是把输入的顶点坐标进行处理,进行几何变换和顶点属性的计算,包括顶点坐标变换,法线计算法线计算就是通过对模型的顶点坐标进行处理,而获得每个顶点的法线向量,这些法线向量可以用来进行光照计算,阴影计算和视觉效果等计算),颜色和纹理坐标的插值等

        ②几何处理阶段(Geometry Process Stage),对经过定点处理的几何图元进行处理和组装,包括三角形的裁剪用于剔除或裁剪掉位于视景体之外的三角形,以提高渲染效率和减少不必要的计算和绘制操作),投影变换将三维场景投影到二维屏幕上,包括透视投影和正交投影,透视投影是模拟人眼视角的投影方式,呈现近大远小,而正交投影是无论距离相机远近,都不变大小的投影方式),光栅化将连续的几何形状转化为离散的像素,通过逐像素的处理和插值计算,确定每个像素的最终颜色值。这样可以在屏幕上生成二维图像,并通过渲染管线的后续阶段进行显示)。

        ③片元处理阶段(Pixel Processing Stage)对光栅化后的像素进行处理,包括对每个像素进行片元着色,纹理采样等操作

        ④输出合成阶段(Output Assembly Stage),将处理后的像素最终合成为渲染结果,包括将像素写入帧缓冲器中,并应用混合,深度测试,模板测试等结果

        

     六、引入OpenGL!我们来一起创造简单的图形吧!

针对上述的渲染管线过程,我们当然需要用工具来控制,常见的图形学接口包括

OpenGL(Open Graphic Library),DirectX,Vulkan(更加底层),Metal(针对IOS)

我最终选择了OpenGL进行学习,如果你是针对苹果电脑或者苹果手机进行的图形学渲染管线编辑,就需要学习Metal。

好了,既然我们选择了OpenGL,那就来开始学会使用OpenGL!

        1:如何使用VS来创建OpenGL的应用程序呢?我们通常会选择GLUT或者GLFW,针对这两种工具库,我都会写好安装方法,步骤就很繁琐了,我会写的很详细,具体选择哪一种看你的需求,如果只是初学者,就安装GLUT就好了!

                GLUT(OpenGL Utility Toolkit):

                ①:该工具简化了OpenGL应用程序的开发过程,能够做到窗口管理,事件处理,基本绘图功能,定时器,菜单等功能,适合初学者学习。但是目前GLUT已经停止维护了,功能有限,官网下载地址:http://www.opengl.org/resources/libraries/glut/glutdlls37beta.zip

                ②:解压后,在VS的安装目录下,找到VC\Tools\MSVC\版本号\include,创建一个文件夹,名字叫openglfiles,然后把刚解压的glut.h头文件放进去

                ③:打开VC\Tools\MSVC\版本号\lib的64位文件夹,把glut.lib和glut32.lib放进去

                ④:再打开C:Windows\SysWOW64(64位),把glut.dll和glut32.dll放进去即可

                ⑤:新建一个VS项目,打开顶部菜单中的项目,打开管理NuGet程序包,搜索nupengl,随便安装一个,避免繁琐添加头文件路径,只需要每次新建项目安装此程序包即可

                GLFW(Graphics Library Framework):

                ①:一个更为强大和灵活的工具库,提供了更多的功能和控制权。它支持现代OpenGL功能、多窗口管理、输入处理、时间管理、窗口控件等。GLFW具有更好的跨平台支持,适用于开发较为复杂和高级的OpenGL应用程序。官方下载地址:Download | GLFW

                ②:根据自己的版本进行下载,打开VS安装路径,找到VC\Tools\MSVC\版本号\include,创建GLFW文件夹,然后打开GLFW文件夹glfw-3.3.6.bin.WIN64\include\GLFW,将glfw3.h和glwf3native.h文件夹放到,新建的GLFW文件夹中

                ③:打开下载的文件夹中的lib-vc2022文件夹glfw-3.3.6.bin.WIN64\lib-vc2019(根据自己版本),然后把glfw3.lib、glfw3_mt.lib、glfw3dll.lib放到VC\Tools\MSVC\版本号\lib的64位文件夹中

                ④:把glfw3.dll放到C:\Windows\SysWOW64,此时就安装完成了。

        2:除此之外,还需要下载GLAD(OpenGL Loader Generator),它是独立的工具库,用于生成OpenGL加载器的工具,加载和管理OpenGL函数指针,自动生成加载OpenGL函数的代码。GLAD简化了加载和管理OpenGL函数指针的过程,使得在使用OpenGL时更加方便和统一

                ①:官方网站下载:http://glad.dav1d.de/

                ②:只选择API中的gl和Profile中的Core即可,然后GENERATE

                ③:下载最后的Zip文件,打开glad\include,将glad和KHR文件夹复制到VS的安装目录的VC\Tools\MSVC\14.31.31103\include中

                ④:glad.c则不需要换位置,如果该项目用到了GLAD,就把glad.c复制到源文件目录下即可!

3:新建cpp文件,输入如下的测试代码

#include <math.h>
#define GLUT_DISABLE_ATEXIT_HACK
#include <gl/glut.h>

void myDisplay()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0, 0.0, 0.0);
    //画分割线,分成四个视见区  
    glViewport(0, 0, 400, 400);
    glBegin(GL_LINES);
    glVertex2f(-1.0, 0);
    glVertex2f(1.0, 0);
    glVertex2f(0.0, -1.0);
    glVertex2f(0.0, 1.0);
    glEnd();

    //定义在左下角的区域  
    glColor3f(0.0, 1.0, 0.0);
    glViewport(0, 0, 200, 200);
    glBegin(GL_POLYGON);
    glVertex2f(-0.5, -0.5);
    glVertex2f(-0.5, 0.5);
    glVertex2f(0.5, 0.5);
    glVertex2f(0.5, -0.5);
    glEnd();

    //定义在右上角的区域  
    glColor3f(0.0, 0.0, 1.0);
    glViewport(200, 200, 400, 400);
    glBegin(GL_POLYGON);
    glVertex2f(-0.5, -0.5);
    glVertex2f(-0.5, 0.5);
    glVertex2f(0.5, 0.5);
    glVertex2f(0.5, -0.5);
    glEnd();

    //定义在左上角的区域  
    glColor3f(1.0, 0.0, 0.0);
    glViewport(0, 200, 200, 400);
    glBegin(GL_POLYGON);
    glVertex2f(-0.5, -0.5);
    glVertex2f(-0.5, 0.5);
    glVertex2f(0.5, 0.5);
    glVertex2f(0.5, -0.5);
    glEnd();

    //定义在右下角  
    glColor3f(1.0, 1.0, 1.0);
    glViewport(200, 0, 400, 200);
    glBegin(GL_POLYGON);
    glVertex2f(-0.5, -0.5);
    glVertex2f(-0.5, 0.5);
    glVertex2f(0.5, 0.5);
    glVertex2f(0.5, -0.5);
    glEnd();
    glFlush();
}

int main(int argc, char* argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(400, 400);
    glutCreateWindow("OpenGL程序");
    glutDisplayFunc(&myDisplay);
    glutMainLoop();
    return 0;
}

运行,即可得到

 至此,我们的OpenGL的PT1到此结束!

后续会更新PT2,更加详细的介绍函数库

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

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

相关文章

Apache Doris 0.15.3升级至1.1.5避坑实用总结

概述&#xff1a; ​ Apache Doris 从0.15到1.1.5属于一个大版本升级&#xff0c;部分语法和使用方式也发生了较大的变化&#xff0c;本文除前期兼容性调研&#xff08;可以通过官网查到到一部分兼容性问题&#xff09;已知问题外&#xff0c;生产环境正式升级之后遇到的突发问…

【Web 安全】刚开始学渗透,零基础怎么入门?

上周旁听了一个大学学长组织的线上网络安全交流会&#xff0c;里边不乏充斥着各位行业大牛&#xff0c;讲的内容确实精彩&#xff0c;可能对于网络安全经验 5 年的人来说&#xff0c;是受益匪浅&#xff0c;欢迎程度极高&#xff0c;恨不得跳出屏幕来表示赞同&#xff0c;毕竟很…

2022年06月份青少年软件编程Scratch图形化等级考试试卷三级真题(含答案)

2022-06 Scratch三级真题 分数&#xff1a;100 题数&#xff1a;38 测试时长&#xff1a;60min 一、单选题(共25题&#xff0c;共50分) 1.点击绿旗&#xff0c;舞台上的角色会说出&#xff1f;&#xff08; &#xff09;(2分) A. 2022年5月1日 B. 1日5月2022年 C. 2022…

【2023最全教程】性能测试基础知识学习路线(建议收藏)

本文介绍一下性能测试的基础内容和一些学习经验&#xff0c;主要讲针对服务器端的性能测试。其他代码级性能测试、前端性能测试等属于比较细分的领域&#xff0c;建议大家有需要的时候针对性得去学。而对于服务器端的性能测试&#xff0c;即使是不做性能测试的人&#xff0c;最…

如何利用GIS数据转换器-栅格 实现去云

GIS数据转换器-栅格不仅能够实现数据转换、数据分割、数据。还可以实现简单去云。 首先打开一副LANDSAT的数据 然后查看云的值范围&#xff0c;值大约为&#xff1a;20000-45000之间 然后在数据转换器中设置设置&#xff0c;过滤范围 点转换按钮进行转换,这样云位置的像素就被…

SpringBoot教学资料3-SpringBoot启动常见问题

java.lang.RuntimeException: java.lang.RuntimeException: org.codehaus.plexus.component.repository.exc Maven版本过高 &#xff0c;与你使用的IDEA版本不兼容。 推荐版本&#xff1a;maven3.6(建议)/maven3.9 控制台Process terminated https://blog.csdn.net/weixin_4458…

SMALE周报_20230707

目录标题 1. 上周回顾2. 本周计划3. 完成情况3.1. 背景3.2. 不确定性类别3.3. 具体方法3.3.1. Aleatoric Uncertainty3.3.1. Epistemic Uncertainty 4. 存在的主要问题5. 下一步工作 1. 上周回顾 这周开始写周报&#xff0c;此项为空。 2. 本周计划 总结不确定性在神经网络中…

96、基于STM32单片机的温湿度DHT11 烟雾火灾报警器蓝牙物联网APP远程控制设计(程序+原理图+任务书+参考论文+开题报告+流程图+元器件清单等)

单片机及温湿度、烟雾传感器是烟雾报警器系统的两大核心。单片机好比一个桥梁&#xff0c;联系着传感器和报警电路设备。近几年来&#xff0c;单片机已逐步深入应用到工农业生产各部门及人们生活的各个方面。各种类型的单片机也根据社会的需求而开发出来。单片机是器件级计算机…

试题小结2

1.内部类和子类的区别 内部类是指在一个外部类的内部再定义一个类&#xff0c;内部类对外部类有访问权限&#xff0c;可以访问类中定义的所有变量和方法。 子类是从父类中继承的类&#xff0c;子类可以访问父类所有public和protected的属性和方法。 Java语言有四个权限访问修…

Android11 Settings菜单加载

一、加载默认亮度 1、top_level_settings.xml 2、AndroidManifest.xml 3、DisplaySettings ①getPreferenceScreenResId ②buildPreferenceControllers 4、display_settings.xml 5、AutoBrightnessPreferenceController 6、BrightnessLevelPreferenceController ①getCurren…

全网最细,Pytest自动化测试-重复执行用例 pytest-repeat(实战)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 平常在做功能测试…

应对Python爬虫IP被封的策略及建议。

我们在进行数据抓取使用代理ip的时候需要有一些约束规定&#xff0c;才能保证我们持续稳定的抓取数据。 大概整理了一下&#xff0c;需要注意以下几点&#xff0c;仅供参考&#xff1a; 1、使用高质量的代理服务器&#xff1a;选择一些可靠的代理服务器&#xff0c;确保它们的…

从歌手李玟的自杀传闻,看骑行健身对心理健康的深远影响

从歌手李玟的自杀传闻&#xff0c;看骑行健身对心理健康的深远影响 最近&#xff0c;歌手李玟的自杀传闻让大众一片哗然。这个消息无疑成为了各大平台的热点话题。然而&#xff0c;作为骑友&#xff0c;我们今天再次谈谈骑行健身的重要性。 首先&#xff0c;我们要明确一点&…

性能测试如何做?性能测试实战从0-1进阶(内涵面试题+答案)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 性能测试实战 - 部…

checkout

git-checkout - Switch branches or restore working tree files# 用index或者指定commit中的版本,来更新工作区中的文件 # 切换分支 Updates files in the working tree to match the version in the index or the specified tree. If no pathspec was given,git checkout wil…

SonarQube扫描常见Bug、漏洞修复整理(持续更新中)

目录 DMS1、A "NullPointerException" could be thrown; "sra" is nullable here.2、Cast one of the operands of this multiplication operation to a "long"3、Call "remove()" on "requestContainer".4、Use try-with-r…

echarts条形图 动态 设置标签背景和柱状图渐变颜色

<!--Description: 横向渐变柱状图 --> <template><div ref"horizontal" class"w-full h-full"></div> </template><script> import * as echarts from echarts export default {components: {},props: [data],data() …

c++11 标准模板(STL)(std::basic_ostream)(八)

定义于头文件 <ostream> template< class CharT, class Traits std::char_traits<CharT> > class basic_ostream : virtual public std::basic_ios<CharT, Traits> 类模板 basic_ostream 提供字符流上的高层输出操作。受支持操作包含有格式…

kubernetes 节点排水维护 cordon, drain, uncordon

1.这三个命令是正式release的1.2新加入的命令&#xff0c;三个命令一起介绍&#xff0c;是因为三个命令配合使用可以实现节点的维护。在1.2之前&#xff0c;因为没有相应的命令支持&#xff0c;如果要维护一个节点&#xff0c;只能stop该节点上的kubelet将该节点退出集群&#…

Java-API简析_java.net.InetAddress类(基于 Latest JDK)(浅析源码)

【版权声明】未经博主同意&#xff0c;谢绝转载&#xff01;&#xff08;请尊重原创&#xff0c;博主保留追究权&#xff09; https://blog.csdn.net/m0_69908381/article/details/131590559 出自【进步*于辰的博客】 因为我发现目前&#xff0c;我对Java-API的学习意识比较薄弱…