我很难理解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;
}
答案 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;
};