Opengl — экземпляры атрибутов

Я использую oglplus — это оболочка c ++ для OpenGL.

У меня проблема с определением экземпляров данных для моего рендерера частиц — позиции работают нормально, но что-то идет не так, когда я хочу скопировать целые числа из того же VBO.

Я собираюсь пропустить некоторые детали реализации, чтобы не усложнять эту проблему. Предположим, что я связываю VAO и VBO перед описанными операциями.

У меня есть массив структур (называемых «Частица»), которые я загружаю так:

glBufferData(GL_ARRAY_BUFFER, sizeof(Particle) * numInstances, newData, GL_DYNAMIC_DRAW);

Определение структуры:

struct Particle
{
float3 position;
//some more attributes, 9 floats in total
//(...)
int fluidID;
};

Я использую вспомогательную функцию для определения атрибутов OpenGL следующим образом:

void addInstancedAttrib(const InstancedAttribDescriptor& attribDesc, GLSLProgram& program, int offset=0)
{
//binding and some implementation details
//(...)

oglplus::VertexArrayAttrib attrib(program, attribDesc.getName().c_str());
attrib.Pointer(attribDesc.getPerVertVals(), attribDesc.getType(), false, sizeof(Particle), (void*)offset);

attrib.Divisor(1);
attrib.Enable();
}

Я добавляю атрибуты для позиций и флюидов, как это:

            InstancedAttribDescriptor posDesc(3, "InstanceTranslation", oglplus::DataType::Float);
this->instancedData.addInstancedAttrib(posDesc, this->program);

InstancedAttribDescriptor fluidDesc(1, "FluidID", oglplus::DataType::Int);
this->instancedData.addInstancedAttrib(fluidDesc, this->program, (int)offsetof(Particle,fluidID));

Код вершинного шейдера:

uniform vec3 FluidColors[2];

in vec3 InstanceTranslation;
in vec3 VertexPosition;
in vec3 n;

in int FluidID;

out float lightIntensity;
out vec3 sphereColor;

void main()
{

//some typical MVP transformations
//(...)
sphereColor = FluidColors[FluidID];
gl_Position = projection * vertexPosEye;

}

Этот код в целом производит этот вывод:

OpenGL-проблема

Как вы можете видеть, частицы расположены так, как я и хотел, что означает, что свойство «InstanceTranslation» настроено правильно. Группа частиц слева имеет значение FluidID, равное 0, и число справа, равное 1. Второй набор частиц имеет правильные позиции, но неправильно указывается в массиве FluidColors.

Что я знаю:

  • Это не проблема с тем, как я настроил форму FluidColors. Если я жестко закодирую выделение цвета в шейдере следующим образом:

    phereColor = FluidID == 0? FluidColors [0]: FluidColors1;

Я получил:

введите описание изображения здесь

  • OpenGL возвращает GL_NO_ERROR из glGetError, поэтому нет проблем с предоставленными мной перечислениями / значениями
  • Это не проблема с смещением макроса. Я пытался использовать жестко закодированные значения, и они тоже не работали.
  • Это не проблема совместимости с GLint, я использую простые 32-битные Ints (проверил это с помощью sizeof (int))
  • Мне нужно использовать FluidID в качестве экземпляра атрибута, который индексирует в массиве цветов, потому что в противном случае, если бы я установил цвет для группы частиц как простую униформу vec3, мне пришлось бы пакетировать те же типы частиц (с тем же FluidID ) сначала вместе, что означает их сортировку, и это будет слишком дорогостоящей операцией.

1

Решение

Мне кажется, это вопрос того, как вы настроили fluidID указатель атрибута. Так как вы используете тип int в шейдере ты должен использование glVertexAttribIPointer() установить указатель атрибута. Атрибуты, которые вы создали с нормальным glVertexAttribPointer() Функция работает только для типов атрибутов с плавающей точкой. Они принимают целочисленный ввод, но данные будут преобразованы в плавающие, когда шейдер получит к ним доступ.

В oglplus вы, видимо, должны использовать VertexArrayAttrib::IPointer() вместо VertexArrayAttrib::Pointer() если вы хотите работать с целочисленными атрибутами.

2

Другие решения


По вопросам рекламы [email protected]