我正在尝试向我的SSBO发送glm::uvec4数组。有可能还是我应该使用另一种方法?

我正在使用实例化绘图,并告诉OpenGL绘制X实例(取决于可以变化的glm::uvec4大小)

存储的数据:

std::vector<glm::uvec4> m_blocksToRender;

SSBO设置:
// SSBO
glGenBuffers(1, &m_ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_ssbo);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_blocksToRender), m_blocksToRender.data(), GL_STATIC_DRAW);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);

着色器:
layout(std430, binding = 0) buffer blocksData
{
    uvec4 data[/* ??? can varry, depends on gl_InstanceID size */];
};

最佳答案

你绝对可以。这样做的直接方法是绑定(bind)缓冲区,在渲染调用之前设置数据(如果要修改它),然后在着色器上读取它。

根据您的使用,您还需要直接在SSBO中或在制服上减小arrya的大小。

因此,完整的解决方案是:

C++

//Create SSBO
glGenBuffers(1, &m_ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_ssbo);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_blocksToRender), m_blocksToRender.data(), GL_STATIC_DRAW);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);

void render()
{
  /* additional code */

  //Only needed if another buffer has been bound to the binding point 0
  glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_ssbo);
  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_ssbo);
  //Only needed if the buffer data needs to be changed
  glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_blocksToRender)

  //If you use the uniform option
  glUniform1i(glGetUniformLocation(programID, "size"), m_blocksToRender.size());
}

分段

如果使用统一方法:
uniform int size;
layout(std430, binding = 0) buffer blocksData
{
    uvec4 data[];
};

如果使用元数据版本:
layout(std430, binding = 0) buffer blocksData
{
    uint size;
    uvec4 data[];
};

如果选择第二个选项,则需要对对齐问题感到不满,还需要实现一种将数据大小附加到发送给SSBO的缓冲区的开头的方法。

编辑:
要禁用驱动程序警告(顺便说一下,这是NVIDIA特定的,AMD卡似乎不会引发此错误)

在绑定(bind)缓冲区之前,在代码中的以下位置添加以下行:
GLuint copy_warning = 0x20072;
glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_PERFORMANCE,
    GL_DONT_CARE, 1, &copy_warning, GL_FALSE);

关于c++ - 在SSBO中发送uvec4阵列,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50516439/

10-11 07:07