OpenGL打包正常

时间:2017-11-27 18:51:45

标签: opengl

我试图了解使用GL_INT_2_10_10_10_REV与我的数据V.S的正常之间的区别。 GLbyte。目前我正在将我的法线加载到glm::vec4中,我就像这样包装它:

int32_t floatToSignedNormalizedByte(float x, float y, float z, float w)
{
    int32_t result = 0;
    const int16_t maxValue = static_cast<int16_t>(std::numeric_limits<int8_t>::max());
    const int16_t negativeValueScale = maxValue + 1;

    result |= static_cast<int8_t>(x < 0 ? x * negativeValueScale : x * maxValue);
    result |= static_cast<int8_t>(y < 0 ? y * negativeValueScale : y * maxValue) << 8;
    result |= static_cast<int8_t>(z < 0 ? z * negativeValueScale : z * maxValue) << 16;
    result |= static_cast<int8_t>(w < 0 ? w * negativeValueScale : w * maxValue) << 24;

    return result;
}

随着正常包装,我会打电话:

//Location, component count, type, normalized, stride, offset
glVertexAttribPointer(location, 4, GL_BYTE, true, format.getVertexSize(),  format.getFieldOffset(field, dataBasePtr));

我的问题是,考虑到我打包正常的方式,我应该使用GL_INT_2_10_10_10_REV作为我的类型(替换GL_BYTE)吗?我理解使用GL_INT_2_10_10_10_REV意味着每个组件获得10位而不是8位,这很好,因为我真的只需要xyz组件。哪一个更好,为什么?如果我使用GL_INT_2_10_10_10_REV,我猜测组件数仍然是4?

1 个答案:

答案 0 :(得分:2)

为什么

如你所说,使用10_10_10_2将为每个有意义的分量(xyz)提供10位,而为w分量留下2位,这对于法向量是无用的。对于10位,您有2^10个可能的x,y和z离散值,而不是8位提供的2^8值。因此,这将为法线和更平滑的渐变提供更准确的值。您也可以使用浮点值,但这些将需要更多内存并且可能会更慢。这回答了&#34;我为什么要这样做&#34;一部分。

如何

对于&#34; how&#34;,您当前的打包功能将每个float转换为8位整数。您需要更改此值以转换10位整数中的x,y和z分量,并将这些位与01一起打包为最后2位(w分量)。 REV版本只允许您以相反的顺序指定组件(wzyx)。

有关GL_INT_2_10_10_10_REV顶点格式

的详细信息

OpenGL规范的表10.3和10.4描述了这些组件如何以32位字排列:

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
|  w |             z               |              y              |         x         |

Table 10.3: Packed component layout for non-BGRA formats. Bit numbers are indicated for each component.

UNSIGNED_INT_2_10_10_10_REV:
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
|  w |             x               |              y              |         z         |

Table 10.4: Packed component layout for BGRA format. Bit numbers are indicated for each component.

如您所见,此顶点格式有4个组件。

如果您想要更多背景信息,您可能还会发现GL_ARB_vertex_type_2_10_10_10_rev的规范是一个有趣的读物:

  

两种新的顶点属性数据格式:带符号的2.10.10.10和无符号的2.10.10.10顶点数据格式。这些顶点数据格式描述了4分量流,其可用于以量化形式存储法线或其他属性。法线,切线,副法线和其他顶点属性通常可以以降低的精度指定,而不会引入明显的伪像,从而减少它们消耗的内存和内存带宽。

&#34;精度降低&#34;指的是使用10位整数而不是法线的半浮点(16位)或浮点(32位)值。每个顶点的位数较少可以提供更好的性能,因为顶点装配阶段需要更少的内存带宽。

此问题也有相关信息:Using GL_INT_2_10_10_10_REV in glVertexAttribPointer()