Opengl 存储缓冲区和错误对齐的数据

Opengl 存储缓冲区和错误对齐的数据,opengl,glsl,Opengl,Glsl,我给我的存储缓冲区提供了一些材质,这样我的着色器就可以拥有我试图绘制的对象的材质,但是颜色不一致,我认为这是由于内存对齐,但我是opengl新手,所以我没有发现错误 struct材质 { 颜色扩散; 彩色镜面反射; 颜色发射; 浮子; 材质():漫反射(0.8f,0.8f,0.8f),镜面反射(黑色()),发射(),ns(0){ }; 结构颜色 { 浮子r,g,b,a; }; 还有我的碎片着色器 struct材质 { vec4弥漫性; vec4镜面反射; vec4发射; 浮子; }; 布局(绑

我给我的存储缓冲区提供了一些材质,这样我的着色器就可以拥有我试图绘制的对象的材质,但是颜色不一致,我认为这是由于内存对齐,但我是opengl新手,所以我没有发现错误

struct材质
{
颜色扩散;
彩色镜面反射;
颜色发射;
浮子;
材质():漫反射(0.8f,0.8f,0.8f),镜面反射(黑色()),发射(),ns(0){
};
结构颜色
{
浮子r,g,b,a;
};
还有我的碎片着色器

struct材质
{
vec4弥漫性;
vec4镜面反射;
vec4发射;
浮子;
};
布局(绑定=1)只读缓冲区索引块{
单位颜色指数[];
};
布局(绑定=2)只读缓冲区材料块{
材料[];
};
大体上:

uint color_index=color_index[gl_PrimitiveID];
vec3 frag_color=材质[颜色索引].diffuse.xyz;

您可以轻松测试
颜色是否匹配
vec4

std::cout<< sizeof(Color) <<std::endl;
std::cout<< sizeof(vec4) <<std::endl;

顺便说一句:我认为vec4使用的是
double
,而不是
float
,我建议使用
std140
std430

见:

[……]

  • 如果构件是结构,则结构的基准对齐为N,其中 N是其任何成员的最大基准对齐值,[…]
  • 如果该成员是一个S结构数组,则根据规则(9),该数组的S元素按顺序排列
  • 可以向C++结构添加3个浮点。但最好使用一个,并将结构与16字节对齐:

    struct alignas(16)材质
    {
    颜色扩散;
    彩色镜面反射;
    颜色发射;
    浮子;
    // [...]
    }
    
    着色器:

    struct材质
    {
    vec4弥漫性;
    vec4镜面反射;
    vec4发射;
    浮子;
    };
    布局(绑定=1,std430)只读缓冲区索引块{
    单位颜色指数[];
    };
    布局(绑定=2,std430)只读缓冲区材料块{
    材料[];
    };
    
    std140
    std430
    之间的区别在于,对于
    std140
    而言,标量和向量数组以及结构数组的基本对齐方式和跨距向上舍入为
    vec4
    的基本对齐方式的倍数。
    std430的情况并非如此

    这不是c/c++。代码在GPU上执行“添加3个浮点到C++结构”,最好使用<代码>对齐(16)< /C>,而不是手动填充,在这种情况下。特别是如果你不确定你的ABI的对齐规则。
    Color c(1.0,2.0,3.0,4.0);
    vec4  v(1.0,2.0,3.0,4.0);
    unsigned char buf1[sizeof(Color)];
    unsigned char buf2[sizeof(vec4)];
    memcpy(buf1, &c, sizeof(Color));
    memcpy(buf2, &v, sizeof(vec4));
    bool equal = (memcmp(buf1, buf2, sizeof(Color)) == 0);
    std::cout<< "Is equal? " << equal ? "yes" : "no" <<std::endl;