Предоставление контейнеров С++ для OpenGL?

Я создал объект буфера хранения шейдера, чтобы передать информацию моему вершинному шейдеру. Он привязан к буферу, содержащему одну структуру. Но есть проблема. Данные, которые я храню в этой структуре, представляют собой не простой массив, а std::vector.

Вот структура:

typedef struct {
    glm::mat4 modelMatrix;
} entityInfo;

typedef struct {
    std::vector<entityInfo> entityInfoBuffer;
} shaderData;

mat4 - это просто матрица с плавающей запятой 4x4.

Если я отдам это в OpenGL, данные, передаваемые на GPU, будут просто кучей указателей и инфы о матрице/векторе, а не данных в них.

Одним из решений было бы создание структуры только для OpenGL:

typedef struct {
    float* modelMatrix;
} SSBOentityInfo;

typedef struct {
    SSBOentityInfo* entityInfoBuffer;
} SSBOshaderData;

Но мне пришлось бы копировать eeeeevery указатели, соответствующие данным контейнеров.

Есть ли лучший способ сделать это?


person Talesseed    schedule 27.07.2016    source источник
comment
Разве вы не хотите просто отправить содержимое entityInfoBuffer в GPU? Вы не хотите копировать указатели CPU на GPU, они ничего не будут значить для GPU (с таким же успехом вы можете копировать случайные числа).   -  person user253751    schedule 28.07.2016
comment
Я думаю, что при использовании объекта буфера хранилища шейдеров вы должны использовать структуры? Я не прав ? Это означало бы, что я должен установить entityInfoBuffer.data() в SSBOshaderData entityInfoBuffer ? Кроме того, OpenGL сможет читать только &mat4[0][0].   -  person Talesseed    schedule 28.07.2016
comment
@Talesseed: вы должны использовать структуры? Почему? Данные — это данные, память — это память, а буферные объекты — это буферные объекты.   -  person Nicol Bolas    schedule 28.07.2016
comment
Да, мой плохой... Я просто хочу использовать структуры, чтобы иметь возможность добавлять элементы, которые мне могут понадобиться позже.   -  person Talesseed    schedule 28.07.2016


Ответы (1)


glm::mat4 — это, по сути, массив из 16 float. Не указатель на 16 чисел с плавающей запятой, а настоящий массив float[16]. 16 floatс, один за другим.

Следовательно, vector<glm::mat4> управляет непрерывным массивом элементов, где каждый элемент представляет собой 16 чисел с плавающей запятой. Это те данные, которые вы хотите сохранить в своем буферном объекте. Итак... сделай это.

vector управляет непрерывным массивом данных, поэтому вполне законно получить указатель на этот массив. Вот для чего нужен vector.data(). Итак, это указатель источника, который вы даете glBufferSubData или чему-то еще. Размер будет равен количеству элементов в массиве (vector.size()), умноженному на размер каждого элемента, вычисленный с помощью sizeof.

person Nicol Bolas    schedule 27.07.2016
comment
Спасибо, я думал, что mat4 не был массивом. Однако что мне делать, если я хочу использовать структуры для добавления элементов позже? - person Talesseed; 28.07.2016
comment
@Talesseed: неясно, что вы имеете в виду, но я уверен, что это вопрос, отличный от того, который вы задали здесь. - person Nicol Bolas; 28.07.2016
comment
Я хотел добавить больше элементов в shaperData. Но да, я думаю, это другой вопрос. - person Talesseed; 28.07.2016
comment
А для typedef второй автор поясняет, что отсутствие typedef может привести к ошибке (stackoverflow.com/questions/612328/) - person Talesseed; 28.07.2016
comment
@Talesseed: для этого и нужны пространства имен. Кроме того, это настолько редкая ошибка, что большинство преданных делу программистов на C++ даже не подозревают о ее возможности. - person Nicol Bolas; 28.07.2016