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