Mesh
NDC
NDC(Normalized Device Coordinate)表示标准化设备坐标,使用-1到1之间的数字表示坐标,本质上就是比例。
使用NDC可以在不同尺寸的屏幕上显示相同的图形进行缩放处理。
VBO
vbo(Vertex Buffer Object):顶点缓冲对象,表示了在GPU显存上的一段存储空间对象,在C++中,它是一个无符号整型(unsigned int)类型变量,理解成为GPU端内存对象的一个ID编号。
绑定:将某个资源与opengl状态机中的某个状态插槽进行关联
vbo创建,绑定和销毁
//1 创建一个vbo *******还没有真正分配显存*********
GLuint vbo = 0;
glGenBuffers(1, &vbo);
//2 销毁一个vbo
glDeleteBuffers(1, &vbo);
//3 创建n个vbo
GLuint vboArr[] = {0, 0, 0};
glGenBuffers(3, vboArr);
//4 销毁n个vbo
glDeleteBuffers(3, vboArr);
float vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
//1 生成一个vbo
GLuint vbo = 0;
glGenBuffers(1, &vbo);
//2 绑定当前vbo,到opengl状态机的当前vbo插槽上
//GL_ARRAY_BUFFER:表示当前vbo这个插槽
glBindBuffer(GL_ARRAY_BUFFER, vbo);
//3 向当前vbo传输数据,也是在开辟显存
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBufferData最后一个参数:
GL_STATIC_DRAW:vbo模型数据不会频繁改变
GL_DYNAMIC_DRAW:vbo模型数据会频繁改变
SingleBuffer:每一个属性放在一个单独的vbo当中,下面的例子是分别创建顶点位置与颜色vbo数据
//1 准备顶点位置数据与颜色数据
float positions[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
float colors[] = {
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f
};
//2 为位置&颜色数据各自生成一个vbo
GLuint posVbo = 0, colorVbo = 0;
glGenBuffers(1, &posVbo);
glGenBuffers(1, &colorVbo);
//3 给两个分开的vbo各自填充数据
//position填充数据
glBindBuffer(GL_ARRAY_BUFFER, posVbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);
//color填充数据
glBindBuffer(GL_ARRAY_BUFFER, colorVbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
InterleavedBuffer:将所有属性都存储在一个vbo当中,并且数据是交叉的,下面的例子中vertices前三个表示顶点数据,后三个表示颜色数据。
float vertices[] = {
-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f
};
GLuint vbo = 0;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
VAO
VAO(Vertex Array Object):顶点数组对象,用于存储一个Mesh网格所有的顶点属性描述信息,VAO是一个数组,其中每一个元素可以用来描述VBO数据信息。
下图描述了如何创建VAO,和创建VBO类似,不同的是VAO必须要对相应的VBO进行描述,glBindBuffer方法设置当前的VBO,后面的操作就都与该VBO相关,glEnableVertexAttribArray方法激活VAO中的索引,就是使用哪个索引来描述当前的VBO,glVertexAttribPointer则设置具体的VBO描述信息,参数说明见下图。
使用SingleBuffer策略,进行VAO的构建
//1 准备positions colors数据
float positions[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
float colors[] = {
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f
};
//2 使用数据生成两个vbo posVbo, colorVbo
GLuint posVbo, colorVbo;
glGenBuffers(1, &posVbo);
glGenBuffers(1, &colorVbo);
glBindBuffer(GL_ARRAY_BUFFER, posVbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, colorVbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
//3 生成vao并且绑定
GLuint vao = 0;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
//4 分别将位置/颜色属性的描述信息加入vao当中
//4.1描述位置属性
glBindBuffer(GL_ARRAY_BUFFER, posVbo);//只有绑定了posVbo,下面的属性描述才会与此vbo相关
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
//4.2 描述颜色属性
glBindBuffer(GL_ARRAY_BUFFER, colorVbo);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
//5 扫尾工作:解绑当前vao
glBindVertexArray(0);
使用InterleavedBuffer策略,进行VAO的构建
//1 准备好Interleaved数据(位置+颜色)
float vertices[] = {
-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f
};
//2 创建唯一的vbo
GLuint vbo = 0;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//3 创建并绑定vao
GLuint vao = 0;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
//4 为vao加入位置和颜色的描述信息
//4.1 位置描述信息
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
//4.2 颜色描述信息
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
//5 扫尾工作:解绑当前vao
glBindVertexArray(0);
练习