OpenGL Uniform Buffer std140布局,驱动程序错误还是我误解了规范?

Rob*_*son 6 opengl uniform

OpenGL规范在于(或者这是一个错误?)...参考std140的布局,使用共享的统一缓冲区,它指出:

"GLL编译器使用Tabl e L-1中显示的规则集来布局符合std140的统一块中的成员.块中成员的偏移量是根据块中先前成员的大小累加的(那些在有问题的变量之前声明的那些,以及起始偏移量.第一个成员的起始偏移量总是为零.

标量变量类型(bool,int,uint,float) - 基本机器类型中标量的大小"

(http://www.opengl-redbook.com/appendices/AppL.pdf)

所以,有了这些信息,我在我的着色器中设置了一个看起来像这样的统一块:

// Spotlight.

layout (std140) uniform Spotlight
{
    float Light_Intensity;
    vec4  Light_Ambient;
    vec3  Light_Position;   
};
Run Code Online (Sandbox Code Playgroud)

...只是发现它不适用于我在CPU端设置的后续std140布局.这是前4个字节是浮点数(GLfloat的机器标量类型的大小),接下来的16个字节是vec4,后面的12个字节是vec3(末尾有4个字节,考虑到规则vec3真的是一个vec4).

当我改变CPU端以指定浮点数与vec4的大小相同时,即16个字节,并做我的偏移和缓冲区大小做出这个假设,着色器按预期工作.

所以,无论是规范是错还是我在这种情况下误解了"标量"的含义,或者ATI有驱动程序错误.任何人都可以对这个谜团有所了解吗?

Nic*_*las 12

您链接到PDF是不是OpenGL的规范.我不知道你从哪里得到它,但这肯定不是完整的规则列表.始终检查您的来源; 规范并不像许多人声称的那样难以理解.

是的,大小的基本类型的变量是大小作为基本的机器类型(即:4个字节)相同.但是单独的大小并不能确定变量的位置.

每种类型都有一个基本对齐,无论在统一块中找到哪种类型,它的整体字节偏移都必须符合该对齐.a的基本对齐vec4方式是其基本类型的对齐方式(即:float).所以a的基本对齐vec4是16.

因为Light_Intensity在4个字节之后结束,编译器必须插入12个字节的填充,因为Light_Ambient 不能在4字节边界上.它必须在16字节边界上,因此编译器使用12个字节的空白空间.

ATI确实有一些围绕std140布局的驱动程序错误,但这不是其中之一.

作为一般规则,我喜欢明确地将填充放入我的结构中,并且我避免vec3(因为它具有16字节对齐).这样做通常可以减少编译器错误,以及对事情发展方向和实际占用空间的意外误解.