gpt4 book ai didi

c++ - 了解 GLSL 统一缓冲区 block 对齐

转载 作者:行者123 更新时间:2023-11-30 02:37:43 30 4
gpt4 key购买 nike

我无法理解 GLSL 统一缓冲区对象的 std140 布局。我的印象是,在下面的 uniform block 中,int 将从偏移量 0 开始,而矩阵将从偏移量 16 开始。下面的 uniform 给我一个错误的矩阵,很明显,因为屏幕上没有绘制任何内容。

layout (std140) uniform Camera
{
int renderMode;
mat4 projection;
} camera;

renderMode是它告诉我统一更新代码不起作用。

我有以下代码(自制的)来帮助我。这是在我的 C++ 应用程序中进行 Open GL 调用的代码。此代码位于名为 UniformBufferObject 的类中.

#define UpdateExData(o, s, d) glBindBuffer(GL_UNIFORM_BUFFER, _uboId); \
glBufferSubData(GL_UNIFORM_BUFFER, o, s, d); \
glBindBuffer(GL_UNIFORM_BUFFER, 0);

int Alignment(int offset, int alignment)
{
int leftOver = offset % alignment;
if (leftOver > 0)
{
return offset + (alignment - leftOver);
}
else
{
return offset;
}
}

template<typename T, typename... Args>
void UpdateEx(int offset, const std::vector<T>& data, Args&... args)
{
auto mySize = sizeof(T) * data.size();
int myAlignment = Alignment(offset, 16); // fixed for vectors of vec4 for now
UpdateExData(myAlignment, mySize, data.data());
UpdateEx(myAlignment + mySize, args...);
}

template<typename... Args>
void UpdateEx(int offset, int& data, Args&... args)
{
auto mySize = sizeof(int);
int myAlignment = Alignment(offset, mySize); // assume 4 byte alignment for ints
UpdateExData(myAlignment, mySize, &data);
UpdateEx(myAlignment + mySize, args...);
}

template<typename... Args>
void UpdateEx(int offset, const glm::mat4& data, Args&... args)
{
auto mySize = sizeof(glm::mat4);
int myAlignment = Alignment(offset, 16); // assume 16-byte alignment for mat4
UpdateExData(myAlignment, mySize, &data);
UpdateEx(myAlignment + mySize, args...);
}

启动更新的代码行如下。 m是一个整数。 cam是 glm::mat4。这篇文章的目的是更新我的着色器中的相机。

cameraUbo->UpdateEx(0, m, cam);

如果我翻转 uniform 使得矩阵在前,并将上面的调用更新为 cameraUbo->UpdateEx(0, cam, m) ,矩阵更新但 renderMode 不再有效。

我真的不知道出了什么问题,真正让我困惑的是 GL_UNIFORM_BLOCK_DATA_SIZE 返回的值远远超出了我预期的 80。在它所在的 5 个着色器中,我得到了不同的值,高于 1000。

我确实有另一个 uniform 看起来工作完美,并且在出现的两个着色器中具有相同的大小。

struct TowerLight
{
vec4 position;
vec4 color;
};

layout(std140) uniform Towers
{
int lightCount;
TowerLight lights[MaxLights];
};

使用以下代码。 count是一个整数并且lightsstd::vector<struct_of_2_vec4> .

ubo->UpdateEx(0, towerCount, lights);

[编辑]

这可能是我的视频卡驱动程序中的错误。我有一个 Radeon 6870。如果我使用默认的统一 block 布局或将我的着色器版本从 440 降低到 430,我在所有着色器中得到的 block 大小为 80。

最佳答案

此页面很好地解释了对齐的工作原理 http://learnopengl.com/#!Advanced-OpenGL/Advanced-GLSL

layout (std140) uniform ExampleBlock
{
// // base alignment // aligned offset
float value; // 4 // 0
vec3 vector; // 16 // 16 (must be multiple of 16 so 4->16)
mat4 matrix; // 16 // 32 (column 0)
// 16 // 48 (column 1)
// 16 // 64 (column 2)
// 16 // 80 (column 3)
float values[3]; // 16 // 96 (values[0])
// 16 // 112 (values[1])
// 16 // 128 (values[2])
bool boolean; // 4 // 144
int integer; // 4 // 148
};

关于c++ - 了解 GLSL 统一缓冲区 block 对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31488266/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com