#内存布局 #glsl #opengl #图形 #结构体字段 #glsl 着色器 #对齐

std140

GLSL 接口块内存,根据 std140 规范布局,表示为 Rust 结构体

10 个版本

0.2.6 2022 年 9 月 1 日
0.2.5 2021 年 10 月 27 日
0.2.4 2021 年 4 月 9 日
0.2.2 2020 年 2 月 6 日
0.1.2 2019 年 10 月 6 日

#311 in 图形 API

Download history 23/week @ 2024-03-16 50/week @ 2024-03-23 57/week @ 2024-03-30 18/week @ 2024-04-06 30/week @ 2024-04-13 33/week @ 2024-04-20 18/week @ 2024-04-27 17/week @ 2024-05-04 20/week @ 2024-05-11 18/week @ 2024-05-18 24/week @ 2024-05-25 21/week @ 2024-06-01 11/week @ 2024-06-08 15/week @ 2024-06-15 19/week @ 2024-06-22 3/week @ 2024-06-29

52 每月下载量
5 个 crate 中使用 (4 直接)

MIT 许可证

50KB
1K SLoC

Std140.rs

Crates.io docs.rs docs

提供类型和属性宏,帮助编写与 GLSL 接口块(例如 uniform 块)使用的 std140 内存布局匹配的 Rust 结构体

有关详细信息,请参阅文档


lib.rs:

此模块包含可用于定义与 GLSL std140 内存布局匹配的 Rust 结构体类型的类型。

Std140 是 GLSL 着色器接口块(例如 uniform 块)的标准内存布局。接口块是一组类型化的 GLSL 变量。有关 std140 布局规则的详细信息,请参阅OpenGL ES 3.0 规范的第 2.12.6.4 节 "标准统一块布局"。

此模块旨在通过将结构体作为 Rust 结构体来轻松构建和操作与 std140 兼容的内存块,使得结构体的内存布局将与 GLSL 接口块匹配,如果每个块成员与相应位置的结构体字段类型兼容。这里的“位置”与块成员和结构体字段声明的顺序有关,例如:第 1 个块成员必须与第 1 个结构体字段兼容,第 2 个块成员必须与第 2 个结构体字段兼容,等等。结构体本身必须带有#[repr_std140]属性:这确保 Rust 编译器将正确地排序和排列字段。

对于 GLSL 原始类型,兼容性由以下从 GLSL 类型到 std140 类型的映射定义

  • float: [float]
  • vec2:[vec2]
  • vec3:[vec3]
  • vec4:[vec4]
  • mat2:[mat2x2][struct@mat2x2]
  • mat3:[mat3x3][struct@mat3x3]
  • mat4:[mat4x4][struct@mat4x4]
  • mat2x2:[mat2x2][struct@mat2x2]
  • mat2x3:[mat2x3][struct@mat2x3]
  • mat2x4:[mat2x4][struct@mat2x4]
  • mat3x2:[mat3x2][struct@mat3x2]
  • mat3x3:[mat3x3][struct@mat3x3]
  • mat3x4:[mat3x4][struct@mat3x4]
  • mat4x2:[mat4x2][struct@mat4x2]
  • mat4x3:[mat4x3][struct@mat4x3]
  • mat4x4:[mat4x4][struct@mat4x4]
  • int:[int]
  • ivec2:[ivec2]
  • ivec3:[ivec3]
  • ivec4:[ivec4]
  • uint:[uint]
  • uvec2:[uvec2]
  • uvec3:[uvec3]
  • uvec4:[uvec4]
  • bool:[boolean]
  • bvec2:[bvec2]
  • bvec3:[bvec3]
  • bvec4:[bvec4]

GLSL结构体类型与字段兼容,当且仅当该字段的类型是带有#[repr_std140]属性的Rust结构体,并且该结构体的字段与相应位置的GLSL结构体字段逐对兼容。

具有兼容类型T_c(如上定义)和长度N的GLSL类型T的数组与类型为std140::array<T_c, N>的字段兼容。

示例

给定以下GLSL声明的一个(统一)接口块

struct PointLight {
    vec3 position;
    float intensity;
}

layout(std140) uniform Uniforms {
    mat4 transform;
    vec3 ambient_light_color;
    PointLight lights[2];
}

以下将生成一个与内存布局兼容的Rust结构体实例

#[std140::repr_std140]
struct PointLight {
    position: std140::vec3,
    intensity: std140::float,
}

#[std140::repr_std140]
struct Uniforms {
    transform: std140::mat4x4,
    ambient_light_color: std140::vec3,
    lights: std140::array<PointLight, 2>
}

let instance = Uniforms {
    transform: std140::mat4x4(
        std140::vec4(1.0, 0.0, 0.0, 0.0),
        std140::vec4(0.0, 1.0, 0.0, 0.0),
        std140::vec4(0.0, 0.0, 1.0, 0.0),
        std140::vec4(0.0, 0.0, 0.0, 1.0),
    ),
    ambient_light_color: std140::vec3(0.2, 0.2, 0.2),
    lights: std140::array![
        PointLight {
            position: std140::vec3(10.0, 0.0, 10.0),
            intensity: std140::float(0.5)
        },
        PointLight {
            position: std140::vec3(0.0, 10.0, 10.0),
            intensity: std140::float(0.8)
        },
    ]
};

请注意,尽管在此示例中字段名称与块成员名称匹配,但这不是必需的:仅需要逐对字段类型兼容性。

依赖项

~1.5MB
~34K SLoC