为什么我的glBindBufferRange偏移对齐不正确?

时间:2016-05-15 17:20:51

标签: c++ c++11 opengl 3d opengl-4

我很难理解glvindBufferRange偏移/对齐在Nvidia示例项目gl_commandlist_basic中的工作原理。 我已经读过偏移量需要是GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT的倍数,该值是256和/或偏移和对齐对于glBindBuffer范围非常重要。。我有一个使用mat4 / vec4的示例UBO和一个使用mat4 / mat3 / vec4的非工作示例。在任何一种情况下,UBO都不会加起来为256的倍数。我尝试发送vec4(0.f,1.f,0.f,1.f)。

如果mat4 = 64字节,mat3 = 36字节,vec4 = 16字节,则工作示例具有64 + 16 = 80字节,不是256 的倍数。非工作示例具有64 + 36 + 16 = 116字节。

NV使用名为 uboAligned 的内联,定义为

inline size_t uboAligned(size_t size) { return ((size + 255) / 256) * 256; }

从工作/非工作中删除它无论如何都没有区别。

我认为我需要添加一些"填充"以浮点数/ vec2 / vec3 / vec4等形式的UBO。如果我想使用mat4 / mat3 / vec4 UBO,如何确定正确的填充量?

/* APPLICATION */
typedef struct
{
    glm::mat4 MM;
    // glm::mat3 NM;
    glm::vec4 Cs;
} myData0;

Gluint objectUBO;
glCreateBuffers(1, &objectUBO);
glNamedBufferData(objectUBO, uboAligned(sizeof(abjObjectData) * 2), 0, GL_STATIC_DRAW); //

for (unsigned int i = 0; i < allObj.size(); ++i)
{
    myData0 myDataTemp;
    myDataTemp.Cs = glm::vec4(0.f, 1.f, 0.f, 1.f);
    glNamedBufferSubData(objectUBO, sizeof(abjObjectData) * i, sizeof(abjObjectData), &objDataInit);
}

//hot loop
for (unsigned int i = 0; i < allObj.size(); ++i)
{
    glBindBufferRange(GL_UNIFORM_BUFFER, 1, objectUBO, uboAligned(sizeof(abjObjectData)) * i, sizeof(abjObjectData));
    //draw
}

/* HW */
out vec4 Ci;

struct ObjectData
{
    mat4 MM;
    // mat3 NM;
    vec4 Cs;
};

layout (std140, binding = 1) uniform objectBuffer { ObjectData object; };

void main()
{
    Ci = object.Cs;
}

2 个答案:

答案 0 :(得分:1)

使用glNamedBufferData的简单拼写错误。改变

glNamedBufferData(objectUBO, uboAligned(sizeof(abjObjectData) * 2), 0, GL_STATIC_DRAW);

glNamedBufferData(objectUBO, uboAligned(sizeof(abjObjectData)) * 2, 0, GL_STATIC_DRAW);

修复偏移/对齐问题。

答案 1 :(得分:-2)

OpenGL使用特定的对齐方式。例如,假设您正在使用std140布局,这是在Cpp中定义的结构:

$ vim `find . -type f -print`

你可以在着色器中传递给像这样的结构的统一:

struct PointLight
{
    glm::vec3 position;
    int padding; //this is needed for alignement
    glm::vec3 color; // because a vec3 has to be aligned
    float intensity; //no need for alignment because a float can be read directly without alignement
};

我会测试类似的东西:

uniform light
{
    vec3 Position;
    vec3 Color;
    float Intensity;
} PointLight;

但是我找不到更多的信息,我不记得我在哪里找到它。

你有不同类型的内存布局,你可以检查它们,std140在规范here中定义内存布局,我建议你使用这个布局。如果不这样做,将使用共享布局,您必须查询布局。您可以使用OpenGL查询布局,以了解应添加的填充BlockLayoutQuery

关于glBindBufferRange,我从来没有听说过256比特的对齐。以下是我如何使用它的示例:

struct ObjectData
{
    mat4 MM;
    mat3 NM;
    vec3 padding; //I think you have to add 3 floats of padding
    vec4 Cs;
};