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;//初始化glfwif (!glfwInit())return -1;//创建一个窗口模式的窗口并设置OpenGL上下文window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);if (!window)//如果窗口创建失败,则终止程序{glfwTerminate();//释放glfw资源return -1;}//设置当前窗口的上下文,之后所有的OpenGL调用都会在这个上下文中进行glfwMakeContextCurrent(window);//初始化GLEWif (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;
}