我试图了解使用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?
答案 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()