使用一个GL ELEMENT_ARRAY_BUFFER从0引用每个属性? [英] Use one GL ELEMENT_ARRAY_BUFFER to reference each attribute from 0?

查看:117
本文介绍了使用一个GL ELEMENT_ARRAY_BUFFER从0引用每个属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题



OpenGL 4.4,C ++ 11



我有权利使用索引通过将顶点属性设置为element_array_buffer和array_buffer?



数据布局



来为每个属性设置一个element_array_buffer pre> VAO
Buffer(array_buffer)
PositionFloat * n
TextureFloat * n
NormalFloat * n
Buffer(element_array_buffer)
PositionIndex * 1
TextureIndex * 1
NormalIndex * 1



使用



  // gen 
glBindVertexArray(VAO);

glBindBuffer(array_buffer,vbo);
glBufferData(array_buffer,size(vertices),data(vertices),access(vertices));
glVertexAttribPointer(POSITIONS,3,float,offset(0));
glVertexAttribPointer(UVS,2,float,offset(positions));
glVertexAttribPointer(NORMALS,3,float,offset(normals));

glBindBuffer(element_array_buffer,ebo);
glBufferData(element_array_buffer,size(elements),data(elements),access(elements));
...? / *无法设置元素属性!
如果可以的话,我将为每个属性设置一个strided,offset attribPointer,
,以便如果NORMALS属性中出现0,它将查找第一个法线
而不是第一个法线元素。 * /






问题



我写我的索引,我可以引用第一个顶点,UV和Normal与0/0/0。是否有可能将此映射到element_array_buffer并使用它?或者是我的解决方案添加nPositions到我的纹理索引和nPositions + nTextures到我的正常索引?

解决方案

OpenGL不支持每个顶点属性的单独索引。当为顶点属性使用缓冲区时,您需要为顶点属性的每个唯一组合创建一个顶点。



规范示例是一个立方体,其位置和法线为顶点属性。该立方体有8个角,因此它有8个不同的position属性值。它有6个边,所以它有6个不同的值为正常属性。多维数据集有多少个顶点?在OpenGL中,答案是... 24



至少有两种方法可以导出为什么这种情况下的顶点数24:




  • 立方体有6面。我们不能在两边之间共享顶点,因为它们有不同的法线。每边有4个角,因此我们每边需要4个顶点。 6 * 4 = 24。

  • 立方体有8个角。在这8个角落中的每一个,3个侧面相遇。由于这3个边具有不同的法线,我们需要为每个边有不同的顶点。 8 * 3 = 24。



现在,由于您特别询问OpenGL 4.4,还有其他可以考虑的选项。例如,您可以将顶点属性的值指定为索引而不是坐标。因为你当然可以使用多个顶点属性,你可以为每个顶点有多个索引。然后,您的顶点着色器将这些索引作为顶点属性的值。然后,它可以从不同的来源检索实际的属性值。这些来源的可能性包括:




  • 统一缓冲区。

  • 纹理缓冲区


  • $ b

    我不相信任何这些都会像使用顶点属性一样有效更传统的方式。



    实例渲染是另一种方法,有时可以帮助渲染顶点属性的不同组合,而不枚举所有组合。但这只有真正的工作,如果你的几何是重复的。例如,如果你想用一个绘图调用来渲染多个多维数据集,并为每个多维数据集使用不同的颜色,则实例化渲染可以完美地工作。


    Question

    OpenGL 4.4, C++11

    Do I have the power to use indices in an element_array_buffer from 0 for each attribute, by setting vertex attributes to both the element_array_buffer, and array_buffer?

    Data Layout

    VAO      
     Buffer(array_buffer)      
       PositionFloat * n  
       TextureFloat  * n
       NormalFloat   * n
     Buffer(element_array_buffer)      
       PositionIndex * 1
       TextureIndex  * 1
       NormalIndex   * 1
    

    Data Use

    //gen
    glBindVertexArray(VAO);
    
    glBindBuffer(array_buffer, vbo);
    glBufferData(array_buffer, size(vertices), data(vertices), access(vertices));
    glVertexAttribPointer(POSITIONS, 3, float, offset(0));
    glVertexAttribPointer(UVS,       2, float, offset(positions));
    glVertexAttribPointer(NORMALS,   3, float, offset(normals));
    
    glBindBuffer(element_array_buffer, ebo);
    glBufferData(element_array_buffer, size(elements), data(elements), access(elements)); 
    ...?! /*Cannot set element attributes!  
    If I could, I would set a strided, offset attribPointer for each attribute, 
    so that if 0 appears in the NORMALS attribute, it will look up the first normal, 
    and not the first element in the buffer. */
    


    Problem

    I write my indices such that I could reference the first vertex, UV, and Normal with 0/0/0. Is it possible to map this into the element_array_buffer and use it as such? Or is my solution to add nPositions to my texture indices, and nPositions+nTextures to my normal indices?

    解决方案

    OpenGL does not support separate indices per vertex attribute. When using buffers for your vertex attributes, you need to create a vertex for each unique combination of vertex attributes.

    The canonical example is a cube with positions and normals as vertex attributes. The cube has 8 corners, so it has eight different values for the position attribute. It has 6 sides, so it has 6 different values for the normal attribute. How many vertices does the cube have? In OpenGL, the answer is... 24.

    There are at least two ways to derive why the number of vertices in this case is 24:

    • The cube has 6 sides. We can't share vertices between sides because they have different normals. Each side has 4 corners, so we need 4 vertices per side. 6 * 4 = 24.
    • The cube has 8 corners. At each of these 8 corners, 3 sides meet. Since these 3 sides have different normals, we need a different vertex for each of them. 8 * 3 = 24.

    Now, since you specifically ask about OpenGL 4.4, there are other options that can be considered. For example, you could specify the value of your vertex attributes to be indices instead of coordinates. Since you can of course use multiple vertex attributes, you can have multiple indices for each vertex. Your vertex shader then gets these indices as the values of vertex attributes. It can then retrieve the actual attribute values from a different source. Possibilities for these sources include:

    • Uniform buffers.
    • Texture buffers.
    • Textures.

    I'm not convinced that any of these would be as efficient as simply using vertex attributes in a more traditional way. But it could be worth trying if you want to explore all your options.

    Instanced rendering is another method that can sometimes help to render different combinations of vertex attributes without enumerating all combinations. But this only really works if your geometry is repetitive. For example, if you wanted to render many cubes with a single draw call, and use a different color for each of them, instanced rendering would work perfectly.

    这篇关于使用一个GL ELEMENT_ARRAY_BUFFER从0引用每个属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆