LearnOpenGL笔记2画个三角形

2024-02-26 23:18

本文主要是介绍LearnOpenGL笔记2画个三角形,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

画个三角形

  • 英语单词
  • 基础知识:管线过程、着色器
  • 管线过程详细
    • 顶点输入
    • 顶点着色器
    • 编译着色器
    • 片段着色器
    • 着色器程序
    • 链接顶点属性
    • 顶点数组对象
    • 绘制
  • 索引缓冲对象
  • 个人总结

英语单词

顶点数组对象:Vertex Array Object,VAO
顶点缓冲对象:Vertex Buffer Object VBO
索引缓冲对象Element Buffer Object,EBO或者Index Buffer Object,IBO
图形渲染管线(管线,Graphics Pipeline)

基础知识:管线过程、着色器

OpenGL中,任何事物都在3D空间中,屏幕和窗口却是在2D像素数组,导致大部分工作都是在将3D转2D,这个过程叫做图形渲染管线,一堆原始图形数据途径一个输送管道,各种变化最终出现在屏幕的过程,主要两个部分:
1、3到2D坐标变换
2、2D坐标变成有颜色的像素
2D坐标精确表示一个点在2D空间中的位置,而2D像素是这个点的近似值,2D像素受到你的屏幕/窗口分辨率的限制

管线可以分成高度专门化的阶段,很容易执行,现在的显卡都有很多小处理核心,GPU上为每一个(渲染管线)阶段运行各自小程序,快速处理数据,这些小程序叫做着色器(shader)
开发者可以配置的着色器,可以让我们更细致的控制图形渲染管线特定部分,因为运行在GPU上,节约CPU时间,着色器是用的OpenGL着色器语言(OpenGL shading Language,GLSL)
蓝色部分代表我们可以注入自定义的着色器部分

管线过程详细

1、输入:数组形式传递3个3D坐标,表示一个三角形,叫做顶点数据(Vertex Data);顶点数据是一系列顶点集合
顶点数据用顶点属性(vertex attribute)表示,假定每个顶点只由一个3D位置和一些颜色组成。
2、顶点着色器,一个单独的顶点作为输入,目的将3D坐标转换为另一种3D坐标,同时允许对顶点属性进行一些基本处理。
3、图元装配(Primitive assembly)将所有顶点着色器输出的顶点作为输入,装配成指定的图元形状
4、3中输出传递给几何着色器(geometry shader)。通过产生新顶点构造出新的图元来生成其他形状。
5、光栅化阶段(Rasterization stage),上一步映射为屏幕上最终相应的屏幕上像素生成供片段着色器(Fragment Shader)使用的片段,在片段着色器运行之前进行裁切,丢弃超出视图之外的像素,提升执行效率。
片段着色器主要目的是计算一个像素最终颜色,是所有OpenGL高级效果产生的地方,包括3d场景中的数据(如,光照、阴影、光的颜色等)。
6、Alpha测试和混合(blending)阶段。这个阶段检测片段对应深度值,判断像素是其他物体前后,是否应该舍弃。alpha是透明度,所以即使片段着色器计算出来了一个像素输出颜色,渲染多个三角形最后的像素颜色可能不同。
大多数场合,几何着色器选择默认,只配置顶点和片段着色器。

顶点输入

OpenGL仅当3d坐标在3个轴都是(-1,1)(设备标准化坐标范围)范围内才处理它。
你的标准化设备坐标接着会变换为屏幕空间坐标(Screen-space Coordinates),这是使用你通过glViewport函数提供的数据,进行视口变换(Viewport Transform)完成的。所得的屏幕空间坐标又会被变换为片段输入到片段着色器中。
定义后,顶点着色器在GPU上创建用于储存顶点数据,配置OpenGL如何解释这些内存,并且指定如何发送显卡。顶点着色器会直接处理内存中指定数量的顶点。
顶点缓冲对象(vertex buffer objects,VBO)管理这个内存,会在GPU内存(显存)中储存大量顶点。使用这些缓冲对象好处:可以一次性发送一大批数据到显卡上,每个顶点发送一次。从CPU到数据发送到显卡相对缓慢,所以只可能一次发尽可能多的数据。当数据发送到显卡内存中后,顶点着色器可以立即访问。

顶点缓冲对象,有唯一的ID,使用函数和缓冲ID,生成一个VBO对象。
OpenGL有很多缓冲对象,顶点缓冲对象缓冲类型是GL_ARRAY_BUFFER,允许我们同时绑定多个缓冲,使用glBindBuffer创建的新的缓冲绑定到GL_ARRAY_BUFFER目标上,任何缓冲调用都会用来配置当前绑定的缓冲VBO,可以调用glBufferData函数,把之前定义的顶点数据复制到缓冲的内存中。

顶点着色器

使用GLSL编写,标明使用核心模式。
使用in关键字,声明所有输入顶点属性,现在只关心位置数据,所以只需要一个顶点属性(用向量)。
GLSL中一个向量有最多4个分量,每个分量值都代表空间中的一个坐标,它们可以通过vec.x、vec.y、vec.z和vec.w来获取。注意vec.w分量不是用作表达空间中的位置的(我们处理的是3D不是4D),而是用在所谓透视除法(Perspective Division)上。
在真实的程序里输入数据通常都不是标准化设备坐标,所以我们首先必须先把它们转换至OpenGL的可视区域内。

编译着色器

运行时候动态编译源码

片段着色器

**在计算机图形中颜色被表示为有4个元素的数组:红色、绿色、蓝色和alpha(透明度)分量,通常缩写为RGBA,**当在OpenGL或GLSL中定义一个颜色的时候,我们把颜色每个分量的强度设置在0.0到1.0之间。比如说我们设置红为1.0f,绿为1.0f,我们会得到两个颜色的混合色,即黄色。
用out关键字声明输出变量,
编译片段着色器和顶点着色器类似,使用
GL_FRAGMENT_SHADER常量作为着色器类型。
两个着色器现在都编译了,剩下的事情是把两个着色器对象链接到一个用来渲染的着色器程序(Shader Program)中。

着色器程序

着色器程序是多个着色器合并后最终链接完成的版本。
得到的结果就是一个程序对象,我们可以调用glUseProgram函数,用刚创建的程序对象作为它的参数,以激活这个程序对象。
把着色器对象链接到程序对象以后,记得删除着色器对象,我们不再需要它们。
我们已经把输入顶点数据发送给了GPU,并指示了GPU如何在顶点和片段着色器中处理它。就快要完成了,但还没结束,OpenGL还不知道它该如何解释内存中的顶点数据,以及它该如何将顶点数据链接到顶点着色器的属性上。我们需要告诉OpenGL怎么做。

链接顶点属性

必须在渲染前指定OpenGL该如何解释顶点数据。glVertexAttribPointer函数告诉OpenGL该如何解析顶点数据。

顶点数组对象

VAO可以像顶点缓冲对象那样被绑定,随后顶点属性都直接调用VAO,好处:配置顶点属性指针时候只需要调用执行一次,之后绘制物体只需要绑定对于VAO。
OpenGL的核心模式要求我们使用VAO,所以它知道该如何处理我们的顶点输入。如果我们绑定VAO失败,OpenGL会拒绝绘制任何东西。

绘制

glDrawArrays函数,它使用当前激活的着色器,之前定义的顶点属性配置,和VBO的顶点数据(通过VAO间接绑定)来绘制图元。

索引缓冲对象

只储存不同的顶点,并设定绘制这些顶点的顺序。这样子我们只要储存4个顶点就能绘制矩形了,之后只要指定绘制的顺序就行了。
与VBO类似,我们先绑定EBO然后用glBufferData把索引复制到缓冲里。同样,和VBO类似,我们会把这些函数调用放在绑定和解绑函数调用之间,只不过这次我们把缓冲的类型定义为GL_ELEMENT_ARRAY_BUFFER。

个人总结

整个过程

// ..:: 初始化窗口代码(只运行一次 (除非你的物体频繁改变)) :: ..
//上一节内容窗口加载过程
//编译shader program:vertex shader、fragment shader
//链接shaders
//删除
//初始化顶点数据、缓冲、环境、顶点属性
// 1. 绑定VAO
glBindVertexArray(VAO);
// 2. 把顶点数组复制到缓冲中供OpenGL使用
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 3. 设置顶点属性指针
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
//这里可以设置索引对象如果有必要的话
[...]// ..:: 绘制代码(渲染循环中) :: ..
// 4. 绘制物体
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
someOpenGLFunctionThatDrawsOurTriangle();
//删除对象

这篇关于LearnOpenGL笔记2画个三角形的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/750478

相关文章

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

【WebGPU Unleashed】1.1 绘制三角形

一部2024新的WebGPU教程,作者Shi Yan。内容很好,翻译过来与大家共享,内容上会有改动,加上自己的理解。更多精彩内容尽在 dt.sim3d.cn ,关注公众号【sky的数孪技术】,技术交流、源码下载请添加微信号:digital_twin123 在 3D 渲染领域,三角形是最基本的绘制元素。在这里,我们将学习如何绘制单个三角形。接下来我们将制作一个简单的着色器来定义三角形内的像素

论文阅读笔记: Segment Anything

文章目录 Segment Anything摘要引言任务模型数据引擎数据集负责任的人工智能 Segment Anything Model图像编码器提示编码器mask解码器解决歧义损失和训练 Segment Anything 论文地址: https://arxiv.org/abs/2304.02643 代码地址:https://github.com/facebookresear

数学建模笔记—— 非线性规划

数学建模笔记—— 非线性规划 非线性规划1. 模型原理1.1 非线性规划的标准型1.2 非线性规划求解的Matlab函数 2. 典型例题3. matlab代码求解3.1 例1 一个简单示例3.2 例2 选址问题1. 第一问 线性规划2. 第二问 非线性规划 非线性规划 非线性规划是一种求解目标函数或约束条件中有一个或几个非线性函数的最优化问题的方法。运筹学的一个重要分支。2

【C++学习笔记 20】C++中的智能指针

智能指针的功能 在上一篇笔记提到了在栈和堆上创建变量的区别,使用new关键字创建变量时,需要搭配delete关键字销毁变量。而智能指针的作用就是调用new分配内存时,不必自己去调用delete,甚至不用调用new。 智能指针实际上就是对原始指针的包装。 unique_ptr 最简单的智能指针,是一种作用域指针,意思是当指针超出该作用域时,会自动调用delete。它名为unique的原因是这个

查看提交历史 —— Git 学习笔记 11

查看提交历史 查看提交历史 不带任何选项的git log-p选项--stat 选项--pretty=oneline选项--pretty=format选项git log常用选项列表参考资料 在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史。 完成这个任务最简单而又有效的 工具是 git log 命令。 接下来的例子会用一个用于演示的 simplegit

记录每次更新到仓库 —— Git 学习笔记 10

记录每次更新到仓库 文章目录 文件的状态三个区域检查当前文件状态跟踪新文件取消跟踪(un-tracking)文件重新跟踪(re-tracking)文件暂存已修改文件忽略某些文件查看已暂存和未暂存的修改提交更新跳过暂存区删除文件移动文件参考资料 咱们接着很多天以前的 取得Git仓库 这篇文章继续说。 文件的状态 不管是通过哪种方法,现在我们已经有了一个仓库,并从这个仓

忽略某些文件 —— Git 学习笔记 05

忽略某些文件 忽略某些文件 通过.gitignore文件其他规则源如何选择规则源参考资料 对于某些文件,我们不希望把它们纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。通常它们都是些自动生成的文件,比如日志文件、编译过程中创建的临时文件等。 通过.gitignore文件 假设我们要忽略 lib.a 文件,那我们可以在 lib.a 所在目录下创建一个名为 .gi

取得 Git 仓库 —— Git 学习笔记 04

取得 Git 仓库 —— Git 学习笔记 04 我认为, Git 的学习分为两大块:一是工作区、索引、本地版本库之间的交互;二是本地版本库和远程版本库之间的交互。第一块是基础,第二块是难点。 下面,我们就围绕着第一部分内容来学习,先不考虑远程仓库,只考虑本地仓库。 怎样取得项目的 Git 仓库? 有两种取得 Git 项目仓库的方法。第一种是在本地创建一个新的仓库,第二种是把其他地方的某个