加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

当c没有指定struct layout时,为什么glBufferData缓冲区可以用于U

发布时间:2020-12-16 10:03:29 所属栏目:百科 来源:网络整理
导读:我正在浏览 this页面,了解如何在openGL中使用Uniform Buffer Objects,并看到以下结构: struct shader_data_t{ float camera_position[4]; float light_position[4]; float light_diffuse[4];} shader_data; 使用缓冲区缓冲到openGL Uniform Buffer Object中
我正在浏览 this页面,了解如何在openGL中使用Uniform Buffer Objects,并看到以下结构:

struct shader_data_t
{
    float camera_position[4];
    float light_position[4];
    float light_diffuse[4];
} shader_data;

使用缓冲区缓冲到openGL Uniform Buffer Object中

GLuint ubo = 0;
glGenBuffers(1,&ubo);
glBindBuffer(GL_UNIFORM_BUFFER,ubo);
glBufferData(GL_UNIFORM_BUFFER,sizeof(shader_data),&shader_data,GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER,0);

并在着色器中使用

...
layout (std140) uniform shader_data
{ 
  vec4 camera_position;
  vec4 light_position;
  vec4 light_diffuse;
};
...

但是,当glBufferData转换结构指针和void指针时,我不明白openGl如何知道如何将结构中的数据映射到制服,这应该使openGL不知道结构的内存布局. c struct layout是实现定义的,虽然UBO的作者和其他用户手动填充虚拟变量的c结构以匹配着色器中的标准化std140布局,但是什么阻止c编译器添加更多填充并破坏布局?在c标准中是否有一个强有力的保证,即不会插入更多的填充或者这是一个“实际上便携”的交易?

解决方法

OpenGL非常清楚地定义了std140接口块的字节布局.您在C侧所要做的就是提供符合该布局的数据.如果你可以定义一个编译器将与std140匹配的结构,那么你没问题.你是怎样做的?

您必须知道编译器用于布局类型的规则.

C 11定义了一个名为“standard layout types”的概念.如果您遵循某些规则,您的类型是标准布局.现在,这对于确切知道它们在内存中的布局方式并不是很有意义. C告诉你关于布局的标准布局类型的唯一内容是忽略空基类(只要它仍然是标准布局)并且第一个NSDM将在类的最开始.也就是说,前面永远不会有填充物.

标准所说的另一件事是,相同访问类的NSDM将按顺序分配,后者的偏移量比之前的偏移量大.由于您不允许在标准布局类型中使用不同访问类别的不同NSDM,因此您可以依赖它们按指定的顺序布局.

但就C标准而言,就是这样. [class.mem] / 13声明实现可以出于各种原因在成员之间添加填充.

但是,非正式地,“标准布局类型”的规则为您提供了一个很好的指导,以便知道何时不添加这种填充.遵循标准布局规则,对于大多数系统,您可以假设您的类的布局将与所使用类型的大小和对齐允许一样紧密.

实施必须发挥作用吗?不,但是没有理由认为他们不会.最糟糕的是,你总是可以检查实现是如何打出类型的.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读