【OpenGL】零星感悟记录

1 OpenGL 是一个大的状态机。

我的理解是,OpenGL 是C编写的,绘图时需要记录大量的模式,最好的方式就是用状态机的方式。
OpenGL 提供了一些函数继续状态切换,以及对当前状态的修改。

2 OpenGL 是规范。

OpenGL 定义的API,都没有具体的实现。只是个 虚函数 ,具体的实现都是 GPU厂商实现的。
所以,在一开始,需要调用函数:initializeOpenGLFunctions();

//初始化函数,让opengl的函数都指向显卡提供的函数!
initializeOpenGLFunctions();

3 面向 GPU 编程

由于PC的当前架构,对GPU继续编程,没有对CPU方便。( CPU中代码是顺序执行,而GPU是并行)
所以,我们借助 OpenGL 对 GPU 进行编程。

顶点着色器 和 片段着色器 的编程

有一些过程代码,需要编译好后在GPU上运行。比如创建:顶点着色器,和 片段着色器。
所以你会看到这样的代码!program 里面添加的这些 不是C语言而是,GPU上编程用到的一种语言。

program = new QOpenGLShaderProgram(this);

//这段代码是针对着色器的,运行在显卡(GPU)上的一种语言
//用于搬运数据点
// 添加并编译顶点着色器源码。
// QOpenGLShader::Vertex 表示这是一个顶点着色器。
// 这段 GLSL 代码定义了一个简单的顶点着色器,版本是 330 核心 (core) 版本。
program->addShaderFromSourceCode(QOpenGLShader::Vertex, R"(
    #version 330 core                      // 指定 GLSL 的版本,330 表示 OpenGL 3.3 版本
    layout(location = 0) in vec3 vertexPosition;  // 声明一个输入变量,位置是 0,类型是三维向量 (vec3)
    void main() {
        gl_Position = vec4(vertexPosition, 1.0);  // 将输入的顶点位置转换为齐次坐标,赋值给内置变量 gl_Position
    }
)");


// 添加并编译片段着色器源码。
// QOpenGLShader::Fragment 表示这是一个片段着色器。
// 这段 GLSL 代码定义了一个简单的片段着色器。
program->addShaderFromSourceCode(QOpenGLShader::Fragment, R"(
    #version 330 core                      // 指定 GLSL 的版本,330 表示 OpenGL 3.3 版本
    out vec4 fragColor;                    // 声明一个输出变量,类型是四维向量 (vec4),表示颜色
    void main() {
        fragColor = vec4(0.0, 1.0, 0.0, 1.0);  // 将片段的颜色设置为绿色 (R=0.0, G=1.0, B=0.0, Alpha=1.0)
    }
)");

5 VAO,VBO,EBO

在 OpenGL 中,VAO(Vertex Array Object)、VBO(Vertex Buffer Object)、和
EBO(Element Buffer Object)是管理和组织顶点数据的核心对象。它们在现代 OpenGL
编程中用于高效地传递和绘制几何数据。以下是它们的详细解释:

1. VAO (Vertex Array Object) - 顶点数组对象

  • 作用VAO 是一个容器对象,记录与顶点属性相关的所有状态配置。它存储了顶点属性指针的设置,并与绑定的 VBOEBO 一起定义了顶点数据的组织方式。
  • 功能:通过使用 VAO,你可以一次性设置所有顶点属性配置(例如位置、颜色、法线等),之后只需绑定 VAO 即可快速绘制相应的几何体,而无需重新配置这些属性。
  • 绑定:通过 glBindVertexArray 函数绑定一个 VAO,然后所有后续的顶点属性设置(如 glVertexAttribPointer)都会被记录在这个 VAO 中。

2. VBO (Vertex Buffer Object) - 顶点缓冲对象

  • 作用VBO 是一个在显存中存储顶点数据的缓冲区对象。它用于在 GPU 上存储大量的顶点数据(例如顶点坐标、颜色、法线等),以便在渲染时快速访问。
  • 功能VBO 通过 glBufferDataglBufferSubData 函数上传数据,数据可以是顶点坐标、颜色、纹理坐标等。VBOVAO 结合使用,决定了如何将这些数据提供给顶点着色器。
  • 绑定:通过 glBindBuffer(GL_ARRAY_BUFFER, vbo) 绑定 VBO,然后可以使用 glVertexAttribPointer 来定义如何解释这些数据。

3. EBO (Element Buffer Object) - 元素缓冲对象

  • 作用EBO 是在显存中存储索引数据的缓冲区对象。它用于保存索引数组,这些索引用于在绘制时引用 VBO 中的顶点数据,从而避免顶点数据的重复定义。
  • 功能:使用 EBO,可以通过索引重用顶点数据,从而减少顶点数据的冗余和内存使用。索引缓冲区存储的整数引用顶点缓冲区中的顶点数据,在渲染时通过
    glDrawElements 函数绘制几何体。
  • 绑定:通过 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo) 绑定 EBO,然后可以使用 glDrawElements 函数根据索引数组绘制图元。

工作流程:

  1. 创建 VAOglGenVertexArraysglBindVertexArray 创建并绑定 VAO
  2. 创建 VBO 并绑定数据glGenBuffersglBindBuffer(GL_ARRAY_BUFFER) 创建并绑定 VBO,然后通过 glBufferData 上传顶点数据。
  3. 设置顶点属性指针:使用 glVertexAttribPointer 设置顶点属性指针(如位置、颜色等),然后启用顶点属性数组。
  4. 创建 EBO 并绑定索引数据glGenBuffersglBindBuffer(GL_ELEMENT_ARRAY_BUFFER) 创建并绑定 EBO,然后通过
    glBufferData 上传索引数据。
  5. 绘制:通过 glDrawElements 使用索引缓冲区绘制图元。

总结:

  • VAO:管理顶点属性配置,包含顶点数据和索引数据的绑定信息。
  • VBO:存储顶点数据(如位置、颜色等),提供给顶点着色器使用。
  • EBO:存储顶点索引数据,定义顶点的绘制顺序,以减少冗余。

这里需要强调一点。
VAO,就像一个记录仪, 会记录当前状态机下发生的”一切“!包括一些 一些对象的绑定和解绑。
比如,VAO会记录EBO的绑定和解绑过程。
所以,如果EBO在VAO之前解绑,就会导致 (glDrawElements)报错!!!!!
在这里插入图片描述

在这里插入图片描述
但是 VBO在VAO之前解绑,不会导致错误,是为啥?
这是因为,VAO不记录VBO的绑定状态!!!!!(但是会记录EBO的绑定状态!)

至于为啥,这么设计,我不知道:在这里插入图片描述

再回到之前报错的问题:

所以如果你不记录EBO 就必须直接给出 索引:
这样才不会报错

 // 定义索引数组,指定顶点的绘制顺序
 unsigned int indices[] = {
     0, 1, 2,  // 第一个三角形
     2, 3, 0   // 第二个三角形
 };
 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, &indices);

如果记录了,就不用给:

 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
  • 10
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

code bean

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值