[opengl笔记]2017年8月18日

欢迎访问我的论坛帖:http://hongwgw.com/image/forum.php?mod=viewthread&tid=3&page=1&extra=#pid3

问题:
很多的例子中VBO中数据格式为XnYnZnUnVnRnGnBn.......,代表XYZ, UV and RGB的值。
问题一:能不能传入XYZ数据在一个VBO中,而在另一个VBO中传入UV值,第三个传入Color值?
问题二:能不能在一个VBO中传入500个顶点数据,而在另一个VBO中传入另外的500个顶点数据?


回答一:
答案都是肯定的。
第一个问题:先用glBindBuffer绑定一个合适的缓存区,然后分别调用glVertexAttribPointer。
第二个问题:调用两个draw()


接着问问题二:
对于第一个问题我们做一个test如下:

  1. public draw( int vertices, FloatBuffer xyz_in, IntBuffer idx_in, FloatBuffer rgb_in) {
  2.   int vao = glGenVertexArray(vao);
  3.   glBindVertexArray (vao); // Does this have to happen before glGenBuffer calls? I don't think so.
  4.                                       // Does it have to happen befire the glBindBuffer calls? Dunno.

  5.   int index_buf = glGenBuffers(); //allocate a vbo for the xyz data
  6.   int index_buf = glGenBuffers(); //allocate a vbo for the index data
  7.   int color_buf = glGenBuffers(); // allocatea a vbo for the color data

  8.   assert (vertices == xyz_ in.length / 3); // 3 floats per vertex
  9.   assert (vertices == rgb_in.length / 3); // 3 floats per vertex
  10.   assert (vertices >= idx_in.length); // No more indices than vertices. That would be silly.

  11.   // put the xyz data into the first (position) vbo
  12.   glBindBuffer(GL_ARRAY_BUFFER, xyz_buf); 
  13.   glBufferData(GL_ARRAY_BUFFER, xyz_in, vertices * 3 * sizeof(float) , GL_STATIC_DRAW);

  14.   // put the color data into the second (color) vbo
  15.   glBindBuffer(GL_ARRAY_BUFFER, color_buf);
  16.   glBufferData(GL_ARRAY_BUFFER, color_in, vertices * 3 * sizeof(float) , GL_STATIC_DRAW);

  17.   // put the index data into the third (index) vbo.
  18.   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
  19.   glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_in, idx_in.length() * sizeof(unsigned int), GL_STATIC_DRAW);
复制代码

有一个函数是 glEnableClientState, 使用的参数看上去是如何使用数据的,比如 GL_COLOR_ARRAY和 GL_INDEX_ARRAY。它和 glColorPointer  and  glIndexPointer一起调用,我想 glIndexPointer更多的是颜色调色板的索引而非顶点索引。我注意到 glVertexAttribPointer 是 glXXXPointer的成员函数,并且 glEnableClientState()可以运用 GL_VERTEX_ARRAY。 对于 glEnableClientState/glXXXPointer 以上我说的对吗?如果是这样,那么 glVertexAttribPointer的slot是什么意思,在例子中一般都为0?
接下来 glDrawXXX 如何使用以上我产生的缓冲区呢?


回答二:
Opengl的特性由扩展演变过来。可以参考 https://www.khronos.org/registry/OpenGL/index_gl.php,这上面列出了所有的扩展。仔细看看 ARB_vertex_buffer_object ,描述的与核心说明书中使用类似。

回答三:
让我们回到最初状态,在Opengl1.0中,问题可以通过调用 glColor, glNormal, glTexCoord解决。opengl有个“current”概念,这样你使用当前颜色、法线和纹理,并且调用 glColor/glNormal/glTexCoord。 glVertex会使用当前的数值、使用指定的位置,组成一个复杂的顶点,然后传递到驱动中,在下一阶段的管线中使用。
在很多材料中,你经常可以看到vertex意味着位置。
在固定管线中,每一个顶点属性有着特别的目标,如: colour, normal, texcoord, position, etc.
OpenGL 1.1引进了vertex数组,它用了相同的模型和术语。使用数组而不是单个单个的输入。接下来是 glEnableClientState所做的,提供一个告诉opengl从一个数组中获取特性替代直接指定。
  1. glEnableClientState (GL_VERTEX_ARRAY);
  2.     glEnableClientState (GL_NORMAL_ARRAY);
  3.     glEnableClientState (GL_COLOR_ARRAY);
  4.     glEnableClientState (GL_TEXTURE_COORD_ARRAY);
复制代码
接下来定义一些数组:
  1. float positions[200 * 3];
  2.     float normals[200 * 3];
  3.     unsigned char colors[200 * 4];
  4.     float texcoords[200 * 2];
复制代码
最后我们建立指向这些数组的指针:
  1. glVertexPointer (3, GL_FLOAT, 0, positions);
  2.     glNormalPointer (GL_FLOAT, 0, normals);
  3.     glColorPointer (4, GL_UNSIGNED_BYTE, 0, colors);
  4.     glTexCoordPointer (2, GL_FLOAT, 0, texcoords);
复制代码
以上是建立单独特性的一种方法,还有一种交叉的方式( interleaving ):
  1. struct Vertex {
  2.         float position[3];
  3.         float normal[3];
  4.         unsigned char color[4];
  5.         float texcoord[2];
  6.     };

  7.     Vertex vertices[200];

  8.     glVertexPointer (3, GL_FLOAT, sizeof (Vertex), vertices->position);
  9.     glNormalPointer (GL_FLOAT, sizeof (Vertex), vertices->normal);
  10.     glColorPointer (4, GL_UNSIGNED_BYTE, sizeof (Vertex), vertices->color);
  11.     glTexCoordPointer (2, GL_FLOAT, sizeof (Vertex), vertices->texcoord);
复制代码
以上是非VBO的形式,那么VBO的形式是这样的,初始化数组如下:
  1. glBindBuffer (GL_ARRAY_BUFFER, positionsVBO);
  2.     glBufferData (GL_ARRAY_BUFFER, sizeof (positions), positions, GL_STATIC_DRAW);

  3.     glBindBuffer (GL_ARRAY_BUFFER, normalsVBO);
  4.     glBufferData (GL_ARRAY_BUFFER, sizeof (normals), normals, GL_STATIC_DRAW);

  5.     glBindBuffer (GL_ARRAY_BUFFER, colorsVBO);
  6.     glBufferData (GL_ARRAY_BUFFER, sizeof (colors), colors, GL_STATIC_DRAW);

  7.     glBindBuffer (GL_ARRAY_BUFFER, texcoordsVBO);
  8.     glBufferData (GL_ARRAY_BUFFER, sizeof (texcoords), texcoords, GL_STATIC_DRAW);
复制代码
然后建立指针去使用这些vbo:
  1. glBindBuffer (GL_ARRAY_BUFFER, positionsVBO);
  2.     glVertexPointer (3, GL_FLOAT, 0, 0);

  3.     glBindBuffer (GL_ARRAY_BUFFER, normalsVBO);
  4.     glNormalPointer (GL_FLOAT, 0, 0);

  5.     glBindBuffer (GL_ARRAY_BUFFER, colorsVBO);
  6.     glColorPointer (4, GL_UNSIGNED_BYTE, 0, 0);

  7.     glBindBuffer (GL_ARRAY_BUFFER, texcoordsVBO);
  8.     glTexCoordPointer (2, GL_FLOAT, 0, 0);
复制代码

看到如何工作了吗?  gl*Pointer调用之前绑定的VBO,可以直接修改VBO,而不需要断开这个联系,因为显示驱动已经知道了改如何使用这些数据。 接下来该轮到 glEnableVertexAttribArray and glVertexAttribPointer如何插进来了。 You'll remember that I mentioned "legacy" or "fixed-function" vertex attributes above? lEnableVertexAttribArray and glVertexAttribPointer提供普遍的顶点属性。从另一方面来讲,顶点属性不再含有固定的意思。你可以在着色器代码中自由解释这些顶点。通常vertex放在0 slot


最后忽视 index arrays (and glIndexPointer) 的存在,现在已经没人用它了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值