Отправка массива uvec4 в SSBO - PullRequest
0 голосов
/ 24 мая 2018

Я пытаюсь отправить массив glm :: uvec4 в мой SSBO.Это возможно, или я должен использовать другой метод?

Я использую рисование экземпляров, и я говорю 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 */];
};

1 Ответ

0 голосов
/ 27 мая 2018

Вы определенно можете.Прямой способ сделать это - привязать буфер, как вы это сделали, установить данные перед вызовом рендеринга (если вы хотите изменить его) и затем прочитать их на своем шейдере.

В зависимости от того, как вы используетеТакже необходимо sotre размер arrya либо в SSBO непосредственно или на форме.

Таким образом, полное решение будет:

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).похоже, не выдает эту ошибку)

Добавьте следующую строку где-то в вашем коде перед привязкой буфера:

GLuint copy_warning = 0x20072;
glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_PERFORMANCE,
    GL_DONT_CARE, 1, &copy_warning, GL_FALSE);
...