opengl - 如何将法线打包到GL_INT_2_10_10_10_REV

标签 opengl

在我的宠物项目中,视频内存开始成为一个问题,因此,我研究了各种技术以最大程度地减少内存占用。我尝试使用GL_INT_2_10_10_10_REV,但是我使用打包方法得到了照明伪像。这些工件似乎不是错误的结果,因为使用规范化的char[3]short[3]可以完美地工作。由于其他方面无用的填充,我宁愿使用空间效率更高的GL_INT_2_10_10_10_REV

这是包装代码:

union Vec3IntPacked {
    int i32;
    struct {
        int a:2;
        int z:10;
        int y:10;
        int x:10;
    } i32f3;
};

int vec3_to_i32f3(const Vec3* v) {
    Vec3IntPacked packed;
    packed.i32f3.x = to_int(clamp(v->x, -1.0f, 1.0f) * 511);
    packed.i32f3.y = to_int(clamp(v->y, -1.0f, 1.0f) * 511);
    packed.i32f3.z = to_int(clamp(v->z, -1.0f, 1.0f) * 511);
    return packed.i32;
} // NOTE: to_int is a static_cast

如果我正确地读取了spec(第10.3.8节“打包的顶点数据格式”以及2.1和2.2中的转换规则),则应该可以,但是不能。

我还要注意,以上代码已在多个操作系统(虽然全为64位,但int仍应为32位)和图形卡供应商上进行过测试,以检查是否与驱动程序有关。

此外,使用了OpenGL 3.3核心配置文件。

顶点结构如下所示:
struct BasicVertex {
     float position[3];
     unsigned short uv[2];
     int normal;
     int tangent;
     int bitangent;
} // resulting in a 4-byte aligned 28 byte structure

希望我提供了足够的信息,并且有人可以阐明如何将法线正确打包到GL_INT_2_10_10_10_REV中。

最佳答案

您的位域声明中的顺序看起来不正确。根据规范文档(3.3规范的第32页的“2.8.2压缩的顶点数据格式”部分),每个组件的位范围是:

x: bits 0-9
y: bits 10-19
z: bits 20-29
w: bits 30-31

经过一些搜索后,看起来好像位域中的位顺序不是由C标准定义的。参见例如Which end of a bit field is the most significant bit?

我见过的编译器通常使用最低到最高位的顺序。例如,Microsoft为他们的编译器定义了这一点:

Bit fields are allocated within an integer from least-significant to most-significant bit.



如果您依赖于按此顺序使用编译器,则声明应如下所示:
union Vec3IntPacked {
    int i32;
    struct {
        int x:10;
        int y:10;
        int z:10;
        int w:2;
    } i32f3;
};

为了保证完全的可移植性,您将使用移位运算符来构建值,而根本不使用位域。

根据您在顶点着色器中声明和使用属性的方式,您可能还需要确保将w组件设置为1。当然,如果不在顶点着色器中使用w组件,则不会必要的。

关于opengl - 如何将法线打包到GL_INT_2_10_10_10_REV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35961057/

相关文章:

java - OpenGL (LWJGL+Slick-Util) - 文本无法正确显示

c - 使用 OpenGL/C 生成 N x N 网格以显示在窗口中心

opengl - gl_FragCoord 中的 1/w 坐标代表什么?

c++ - 从 2D 图像堆栈渲染 3D 体积

opengl - VAO 和 GL_ELEMENT_ARRAY_BUFFER 关联

linux - 如何在 linux 中使用 CMake 和 Kdevelop 编译 GLUT + OpenGL 项目?

math - 纹理投影+透视校正,数学正确

c++ - OpenGL 深度 Spaz 攻击

OpenGL 阴影贴图

opengl - 着色器创建弯曲纹理