opengl-vao-vbo

本文介绍了一个使用OpenGL ES进行三角形绘制的具体示例,包括定义顶点结构、设置顶点缓冲区对象(VBO)及索引缓冲区对象(IBO),并详细展示了如何通过顶点着色器和片段着色器来处理顶点坐标、法线及纹理坐标。
 struct MyVertex
  {
    float x, y, z;        //Vertex
    float nx, ny, nz;     //Normal
    float s0, t0;         //Texcoord0
  };
  
  MyVertex pvertex[3];
  //VERTEX 0
  pvertex[0].x = 0.0;
  pvertex[0].y = 0.0;
  pvertex[0].z = 0.0;
  pvertex[0].nx = 0.0;
  pvertex[0].ny = 0.0;
  pvertex[0].nz = 1.0;
  pvertex[0].s0 = 0.0;
  pvertex[0].t0 = 0.0;
  //VERTEX 1
  pvertex[1].x = 1.0;
  pvertex[1].y = 0.0;
  pvertex[1].z = 0.0;
  pvertex[1].nx = 0.0;
  pvertex[1].ny = 0.0;
  pvertex[1].nz = 1.0;
  pvertex[1].s0 = 1.0;
  pvertex[1].t0 = 0.0;
  //VERTEX 2
  pvertex[2].x = 0.0;
  pvertex[2].y = 1.0;
  pvertex[2].z = 0.0;
  pvertex[2].nx = 0.0;
  pvertex[2].ny = 0.0;
  pvertex[2].nz = 1.0;
  pvertex[2].s0 = 0.0;
  pvertex[2].t0 = 1.0;
  
  glGenBuffers(1, VertexVBOID);
  glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
  glBufferData(GL_ARRAY_BUFFER, sizeof(MyVertex)*3, &pvertex[0].x, GL_STATIC_DRAW);
  
  ushort pindices[3];
  pindices[0] = 0;
  pindices[1] = 1;
  pindices[2] = 2;
  
  glGenBuffers(1, &IndexVBOID);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
  glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(ushort)*3, pindices, GL_STATIC_DRAW);
  
  //Define this somewhere in your header file
  define BUFFER_OFFSET(i) ((char *)NULL + (i))
  
  glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
  glEnableVertexAttribArray(0);    //We like submitting vertices on stream 0 for no special reason
  glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(0));   //The starting point of the VBO, for the vertices
  glEnableVertexAttribArray(1);    //We like submitting normals on stream 1 for no special reason
  glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(12));     //The starting point of normals, 12 bytes away
  glEnableVertexAttribArray(2);    //We like submitting texcoords on stream 2 for no special reason
  glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(24));   //The starting point of texcoords, 24 bytes away
  
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
  //To render, we can either use glDrawElements or glDrawRangeElements
  //The is the number of indices. 3 indices needed to make a single triangle
  glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));   //The starting point of the IBO
  //0 and 3 are the first and last vertices
  //glDrawRangeElements(GL_TRIANGLES, 0, 3, 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));   //The starting point of the IBO
  //glDrawRangeElements may or may not give a performance advantage over glDrawElements
### 原理与作用 VBO(Vertex Buffer Object)即顶点缓冲对象,用于在GPU内存(显存)中存储顶点数据。在传统的绘制方式中,每次绘制时都需要将顶点数据从CPU传输到GPU,当数据量大时,频繁的数据传输会成为性能瓶颈。而VBO将顶点数据存储在显存中,避免了每次绘制时的重复数据传输,提高了绘制效率。 然而,每次在绘制的时候都需要频繁地绑定与解绑VBO,每次绘制还需要取出VBO中的数据进行赋值之后才能进行绘制渲染。当数据量大时,重复这些操作会变得很繁琐。VAO(Vertex Array Object)即顶点数组对象,可以简单理解成VBO的管理者,避免在帧绘制时再去手动操纵VBOVAO不能单独使用,需要搭配VBO使用,它记录了顶点属性的配置信息,包括顶点属性的启用状态、顶点属性指针等,使得在绘制时可以一次性应用这些配置,简化了绘制流程[^1]。 ### 使用方法 #### VBO的使用方法 ```python # 1. 生成VBO对象 import OpenGL.GL as gl vbo = gl.glGenBuffers(1) # 2. 绑定VBO对象 gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) # 3. 将顶点数据复制到VBO中 vertices = [ 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0 ] import numpy as np vertex_data = np.array(vertices, dtype=np.float32) gl.glBufferData(gl.GL_ARRAY_BUFFER, vertex_data.nbytes, vertex_data, gl.GL_STATIC_DRAW) # 4. 解绑VBO对象 gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0) ``` #### VAO的使用方法 ```python # 1. 创建VAO对象 vao = gl.glGenVertexArrays(1) # 2. 绑定VAO对象 gl.glBindVertexArray(vao) # 3. 绑定VBO对象 gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) # 4. 启用顶点属性 gl.glEnableVertexAttribArray(0) # 5. 设置顶点属性指针 gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 3 * 4, None) # 6. 解绑VAOVBO对象 gl.glBindVertexArray(0) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0) # 7. 绘制时绑定VAO对象并进行绘制 gl.glBindVertexArray(vao) gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3) gl.glBindVertexArray(0) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值