Я использую 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;
}
Этот код в целом производит этот вывод:
Как вы можете видеть, частицы расположены так, как я и хотел, что означает, что свойство «InstanceTranslation» настроено правильно. Группа частиц слева имеет значение FluidID, равное 0, и число справа, равное 1. Второй набор частиц имеет правильные позиции, но неправильно указывается в массиве FluidColors.
Что я знаю:
Это не проблема с тем, как я настроил форму FluidColors. Если я жестко закодирую выделение цвета в шейдере следующим образом:
phereColor = FluidID == 0? FluidColors [0]: FluidColors1;
Я получил:
Мне кажется, это вопрос того, как вы настроили fluidID
указатель атрибута. Так как вы используете тип int
в шейдере ты должен использование glVertexAttribIPointer()
установить указатель атрибута. Атрибуты, которые вы создали с нормальным glVertexAttribPointer()
Функция работает только для типов атрибутов с плавающей точкой. Они принимают целочисленный ввод, но данные будут преобразованы в плавающие, когда шейдер получит к ним доступ.
В oglplus вы, видимо, должны использовать VertexArrayAttrib::IPointer()
вместо VertexArrayAttrib::Pointer()
если вы хотите работать с целочисленными атрибутами.