OpenGL学习笔记四

这篇博客介绍了在OpenGL中如何使用顶点缓冲对象(VBO)存储顶点数据,以及如何配合顶点着色器进行图形渲染。首先,创建并初始化VBO来存储3D坐标,然后编写GLSL着色器,包括顶点着色器和片段着色器,用于处理顶点和计算像素颜色。接着,编译和链接着色器程序,并激活使用。最后,通过设置顶点属性指针和启用顶点数组对象(VAO)来准备渲染。整个过程展示了OpenGL基本的图形绘制流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.顶点输入
开始绘制图形之前,我们必须先给OpenGL输入一些顶点数据。OpenGL仅当3D坐标在3个轴(x、y和z)上都为-1.0到1.0的范围内时才处理它.

float vertices[] = {
    -0.5f, -0.5f, 0.0f,
     0.5f, -0.5f, 0.0f,
     0.0f,  0.5f, 0.0f
};

      1.1顶点着色器
它会在GPU上创建内存用于储存我们的顶点数据,还要配置OpenGL如何解释这些内存,并且指定其如何发送给显卡。顶点着色器接着会处理我们在内存中指定数量的顶点。
      1.2顶点缓冲对象(Vertex Buffer Objects, VBO)
它会在GPU内存(通常被称为显存)中储存大量顶点。
就像OpenGL中的其它对象一样,这个缓冲有一个独一无二的ID,所以我们可以使用glGenBuffers函数和一个缓冲ID生成一个VBO对象。

unsigned int VBO;
glGenBuffers(1, &VBO);

顶点缓冲对象的缓冲类型是GL_ARRAY_BUFFER,使用glBindBuffer函数把新创建的缓冲绑定到GL_ARRAY_BUFFER目标上,从这一刻起,我们使用的任何(在GL_ARRAY_BUFFER目标上的)缓冲调用都会用来配置当前绑定的缓冲(VBO)

glBindBuffer(GL_ARRAY_BUFFER, VBO);  

调用glBufferData函数,它会把之前定义的顶点数据复制到缓冲的内存中:

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

2.顶点着色器
用着色器语言GLSL(OpenGL Shading Language)编写顶点着色器,然后编译这个着色器,这样我们就可以在程序中使用它了。

#version 330 core
layout (location = 0) in vec3 aPos;

void main()
{
    gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}

每个着色器都起始于一个版本声明,使用in关键字,在顶点着色器中声明所有的输入顶点属性(Input Vertex Attribute),我们就创建一个vec3输入变量aPos。为了设置顶点着色器的输出,我们必须把位置数据赋值给预定义的gl_Position变量,可以把vec3的数据作为vec4构造器的参数。
3.编译着色器
暂时将顶点着色器的源代码硬编码在代码文件顶部的C风格字符串中,为了能够让OpenGL使用它,我们必须在运行时动态编译它的源代码

const char *vertexShaderSource = "#version 330 core\n"
    "layout (location = 0) in vec3 aPos;\n"
    "void main()\n"
    "{\n"
    "   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
    "}\0";

      3.1.创建一个着色器对象
注意还是用ID来引用的。所以我们储存这个顶点着色器为unsigned int,然后用glCreateShader创建这个着色器

unsigned int vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);

      3.2.把这个着色器源码附加到着色器对象上,然后编译它:

glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);

glShaderSource函数把要编译的着色器对象作为第一个参数。第二参数指定了传递的源码字符串数量,这里只有一个。第三个参数是顶点着色器真正的源码,第四个参数我们先设置为NULL。
4.片段着色器
片段着色器所做的是计算像素最后的颜色输出。片段着色器只需要一个输出变量,这个变量是一个4分量向量,它表示的是最终的输出颜色。编译片段着色器的过程与顶点着色器类似,只不过我们使用GL_FRAGMENT_SHADER常量作为着色器类型:

#version 330 core
out vec4 FragColor;

void main()
{
    FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
} 
unsigned int fragmentShader;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);

5.着色器程序
着色器程序对象(Shader Program Object)是多个着色器合并之后并最终链接完成的版本。如果要使用刚才编译的着色器我们必须把它们链接(Link)为一个着色器程序对象,然后在渲染对象的时候激活这个着色器程序。已激活着色器程序的着色器将在我们发送渲染调用的时候被使用。
      5.1.创建一个程序对象
glCreateProgram函数创建一个程序,并返回新创建程序对象的ID引用。现在我们需要把之前编译的着色器附加到程序对象上,然后用glLinkProgram链接它们:

unsigned int shaderProgram;
shaderProgram = glCreateProgram();

glCreateProgram函数创建一个程序,并返回新创建程序对象的ID引用。现在我们需要把之前编译的着色器附加到程序对象上,然后用glLinkProgram链接它们:

glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);

      5.2.激活这个程序
创建一个程序对象调用glUseProgram函数,用刚创建的程序对象作为它的参数,以激活这个程序对象,在glUseProgram函数调用之后,每个着色器调用和渲染调用都会使用这个程序对象

glUseProgram(shaderProgram);
glDeleteShader(vertexShader);//删除着色器对象
glDeleteShader(fragmentShader);

6.链接顶点属性
使用glVertexAttribPointer函数告诉OpenGL该如何解析顶点数据

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);

在OpenGL中绘制一个物体

// 0. 复制顶点数组到缓冲中供OpenGL使用
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 1. 设置顶点属性指针
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// 2. 当我们渲染一个物体时要使用着色器程序
glUseProgram(shaderProgram);
// 3. 绘制物体
someOpenGLFunctionThatDrawsOurTriangle();

7.顶点数组对象(Vertex Array Object, VAO)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值