bilibili视频链接:
【最好的OpenGL教程之一】https://www.bilibili.com/video/BV1MJ411u7Bc?p=5&vd_source=44b77bde056381262ee55e448b9b1973
一、知识点整理
1.1.OpenGL管线工作流程
- 为显卡提供绘制的所有数据,并将数据存储在GPU内存
- 使用着色器,即在GPU上执行的一种程序,来读取数据并将其显示在屏幕上
- 绘制图形时使用顶点缓存,即GPU一块内存。所以着色器开始读取时,顶点缓存需要知道缓存层,它包含在缓存区,是一大堆浮点数,决定每个顶点的位置。
- 还要告诉OpenGL像坐标、纹理、法线等、以及在内存里面有什么,是如何布局的
1.2 Vertex
- Vertex不只是顶点
- 还可以包含一些定点相关的信息。颜色、纹理、坐标、法线等。
1.3 glVertexAttribPointer
1.3.1 c规范
1.3.2 功能
定义一个通用顶点属性数据数组
1.3.3参数
index
指定要修改的通用顶点属性的索引。
size
指定每个通用顶点属性的组件数。必须是1、2、3、4。此外,符号常量GL_BGRA
被glVertexAttribPointer
接受。初始值是4。
type
指定数组中每个组件的数据类型。符号常量GL_BYTE
、GL_UNSIGNED_BYTE
、GL_SHORT
、GL_UNSIGNED_SHORT
、GL_INT
和GL_UNSIGNED_INT
被glVertexAttribPointer
和glVertexAttribIPointer
接受。此外GL_HALF_FLOAT
、GL_FLOAT
、GL_DOUBLE
、GL_FIXED
、GL_INT_2_10_10_10_REV
、GL_UNSIGNED_INT_2_10_10_10_REV
和GL_UNSIGNED_INT_10F_11F_11F_REV
被glVertexAttribPointer
接受。GL_DOUBLE
也被glVertexAttribLPointer
接受,并且是该函数的type
参数中唯一被接受的令牌。初始值是GL_FLOAT
。
normalized
对于glVertexAttribPointer
,指定当固定点数据值被访问时,是否应该进行归一化 (GL_TRUE
) 或直接作为固定点值进行转换 (GL_FALSE
)。
stride
指定连续的通用顶点属性之间的字节偏移量。如果 stride
为0,则通用顶点属性在数组中被认为是紧密包装的。初始值为0。
步幅。每个顶点之间的字节数量。一个顶点的多个字节被分配给多个属性,如纹理、颜色等。
pointer
指定缓冲区中当前绑定到GL_ARRAY_BUFFER
目标的数据存储中第一个通用顶点属性数组的第一个组件的偏移量。初始值为0。
1.3.4示例
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);
1.4 glEnableVertexAttribArray
1.4.1 c规范
1.4.2 功能
启用或禁用通用顶点属性数组
1.4.3参数
vaobj
指定用于glDisableVertexArrayAttrib
和glEnableVertexArrayAttrib
函数的顶点数组对象名称。
index
指定要启用或禁用的通用顶点属性的索引。
1.4.4示例
glEnableVertexAttribArray(0);
二、代码
2.1 代码
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include<iostream>
int main(void)
{
GLFWwindow* window;
//初始化glfw
if (!glfwInit())
return -1;
//创建一个窗口模式的窗口并设置OpenGL上下文
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)//如果窗口创建失败,则终止程序
{
glfwTerminate();//释放glfw资源
return -1;
}
//设置当前窗口的上下文,之后所有的OpenGL调用都会在这个上下文中进行
glfwMakeContextCurrent(window);
//初始化GLEW
if (glewInit() != GLEW_OK)
std::cout << "Error!" << std::endl;
//打印OpenGL版本信息
std::cout << glGetString(GL_VERSION) << std::endl;
//准备数据
float position[6] = {
0.0f, 0.5f,
-0.5f, -0.5f,
0.5f, -0.5f
};
unsigned int buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), position, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);
//渲染循环,直到窗口被关闭
while (!glfwWindowShouldClose(window))
{
//这部分主要:渲染窗口内容
glClear(GL_COLOR_BUFFER_BIT);
//刷新缓冲区并交换窗口
glfwSwapBuffers(window);
//处理窗口事件,如键盘输入、鼠标移动等
glfwPollEvents();
}
glfwTerminate();
return 0;
}