OpenGL и загрузка / чтение данных в формате AoSoA (гибридный SoA) - PullRequest
2 голосов
/ 06 января 2020

Предположим, у меня есть следующая упрощенная структура в формате AoSoA для представления вершины или точки:

struct VertexData
{
    float px[4]; // position x
    float py[4]; // position y
};

То есть каждый экземпляр VertexData хранит 4 вершины. Почти все примеры OpenGL, которые я видел, используют традиционный макет AoS, но это не вариант для меня. Я не могу изменить фактические структуры, и я также хотел бы избежать преобразования данных в формат AoS перед рендерингом.

Итак, можно ли дать OpenGL команду читать данные вершин, когда данные организованы так? Кстати, и если да, то какие функции GL я должен посмотреть? Проблема, на мой взгляд, состоит в том, чтобы заставить OpenGL осознать тот факт, что VertexData.px[i] связан с VertexData.py[i], и эти два значения должны образовывать вершину / точку.

Пояснение 1 : В конце будет массив VertexData, например: std::vector<VertexData>. Тогда размер std::vector будет total number of vertices / 4.

Пояснение 2 : AoSoA = Массив структуры массивов.

Обновление : См. Как рисовать вершины, которые хранятся в SSBO? о том, как рисовать вершины, которые хранятся в SSBO в формате AoSoA.

1 Ответ

2 голосов
/ 06 января 2020

Форматы массивов вершин OpenGL предназначены для ... массивов данных. Каждая отдельная привязка массива / буфера может иметь значительный размер. Но этот шаг, расстояние от данных одной вершины (для этого атрибута) до следующей, одинаково для каждой вершины в массиве; вот что делает его массивом. Ваш шаг не постоянен. Иногда это 4 байта, а иногда 16.

Так что аппаратное извлечение вершин здесь не поможет.

Существует один вариант, который будет работать независимо от того, что вы делаете : programmati c извлечение вершины. То есть вообще игнорировать массивы атрибутов вершин. Свяжите свои «буферы вершин» как SSBO со своим шейдером и используйте gl_VertexID для получения любых данных, которые вы хотите. В GLSL это будет выглядеть примерно так:

struct Vertex4
{
    float px[4]; // position x
    float py[4]; // position y
};

layout(std430) readonly buffer VertexData
{
    Vertex4 vertices[];
};

void main()
{
  int dataIx = gl_VertexID / 4;
  int vertexIx = gl_VertexID % 4;
  vec2 my_position = vec2(vertices[dataIx].px[vertexIx], vertices[dataIx].py[vertexIx]);
}

Это будет быстрее, чем любое решение на основе геометрических шейдеров, поскольку GS в основном убивает производительность.

Если у вас нет доступа к SSBOs , поскольку ваше оборудование не может их обработать, вы можете использовать буферные текстуры .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...