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]: FluidColors 1;

Я получил:

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

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

1 ответ

Решение

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

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

Другие вопросы по тегам