Как использовать структуру смешанного типа c ++ и передавать только некоторые значения в OpenGL? - PullRequest
1 голос
/ 20 марта 2019

Я прочитал высоко и низко и подумал, что понимаю макеты данных вершин в C ++ и OpenGL, но я где-то ошибаюсь ...

У меня есть структура для создания объекта Line. Следовательно, у него есть две точки (каждая из 3-х чисел, представляющих векторную позицию). Он также должен иметь идентификатор объекта, чтобы позволить мне отслеживать конкретный объект при создании на предмет столкновений и т. Д. Позже в приложении. Структура показана ниже.

struct Point
{
    Vector position = { 0.0f, 0.0f, 0.0f };
};

struct Line
{
    Point B = { 0.0f,0.0f,0.0f };
    Point C = { 0.0f,0.0f,0.0f };
    int ID = 0;
};

Затем я создаю STL-вектор simpe c ++ STL и отодвигаю два линейных объекта:

vector<Line> lines; 

Line w0;
    w0.B = { 2.0f,2.0f, 0.0f };
    w0.C = { 8.0f,2.0f, 0.0f }; 
    w0.ID = 0; 
    lines.push_back(w0);

Line w1;
    w1.B = { 10.0f,4.0f, 0.0f };
    w1.C = { 18.0f,4.0f, 0.0f };
    w1.ID = 1;
    lines.push_back(w1);

Далее я указываю glVertexAttribPointer следующим образом:

glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 0, (void*)(0));
glEnableVertexAttribArray(4);

Это дает рисовать только 1 линию, а не две, для которых я создаю объекты (!). Если я удаляю переменную ID int из моей структуры, обе строки отображаются правильно. Позже выяснилось, что, возможно, я неправильно указал glVertexAttribPointer, поэтому я изменил его логически следующим образом:

glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Line), (void*)offsetof(Line, B));

Затем он нарисовал только 1 линию в совершенно разных координатах! Различные комбинации смещений и т. Д. Не помогли. Могу ли я в конечном итоге использовать значение типа int, отличное от остальной части структуры, и передавать только плавающие значения в OpenGL? Мне действительно нужен идентификатор объекта и использовать его позже в приложении. Должен быть способ - я должен что-то упустить .. пожалуйста, помогите.

1 Ответ

3 голосов
/ 20 марта 2019

То, что вам нужно представлять линии определенным образом внутри вашего приложения, не означает, что вы должны точно передавать эти данные в OpenGL для рисования.OpenGL не нуждается в этом ID поле.Кажется, нет причин загружать эти ID данные в графический процессор.Кроме того, нет никакого способа заставить массивы атрибутов вершин OpenGL использовать макет памяти, подобный тому, который у вас есть с вашим массивом Line структур.Подумайте, как выглядят несколько Line в памяти:

B1 C1 ID1  B2 C2 ID2  B3 C3 ID3  …

Обратите внимание, что разрыв между последовательными позициями вершин не фиксирован, а равен либо 0 между двумя точками одного отрезка, либо sizeof(int) междуконечная вершина одной строки и начальная вершина следующей строки.Невозможно описать такой массив атрибутов вершин, используя только шаг и базовое смещение.И все это игнорирует тот факт, что компиляторы могут свободно добавлять байты заполнения между членами структуры любым удобным для них способом.Таким образом, ваш макет памяти даже не гарантированно будет выглядеть так, и, по крайней мере, теоретически, он может меняться в зависимости от того, какую версию какого компилятора вы используете, с какими опциями компиляции.

Я бы предложил разрешитьПодумайте о том, что структура Line является данным, и каждый аспект вашего приложения должен абсолютно точно работать с этим точным представлением данных.Вы все равно должны загрузить данные в графический процессор для рисования в какой-то момент.Когда вы это сделаете, просто скопируйте только начальную и конечную точки и пропустите идентификатор.Кроме того, учтите тот факт, что вы также можете просто переключиться с подхода Array of Structures , который у вас сейчас есть (где вы храните массив структур Line), на подход Structure of Arrays, т. Е.иметь один массив для всех начальных точек линии, один для всех конечных точек и один для идентификаторов.В зависимости от того, как именно вы обрабатываете свои данные, это часто полезно даже для процессора.Наконец, будет возможность загрузить данные в буфер хранения шейдера и вручную посмотреть атрибуты вершины в вершинном шейдере.Я не думаю, что я бы порекомендовал пойти по этому пути, хотя ...

...