Giving C++ containers to OpenGL?

I created a shader storage buffer object to give information to my vertex shader. It is bound to a buffer containing a single structure. But there is a problem. The data I keep in this structure is not a simple array, it’s a std::vector.

Here is the structure :

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

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

mat4 is just a simple 4x4 float matrix.

If I give this to OpenGL, the data transmitted to the GPU will be just a bunch of pointers and info about the matrix/vector, and not the data in them.

One solution would be to create a structure only for OpenGL:

typedef struct {
    float* modelMatrix;
} SSBOentityInfo;

typedef struct {
    SSBOentityInfo* entityInfoBuffer;
} SSBOshaderData;

But I would have to copy eeeeevery pointer corresponding to the data of the containers. Also, OpenGL will only be able to read &mat4[0][0].

Is there a better way to do it?

Thanks in advance

What is “this”? &entityInfoBuffer.front() will point to an array of glm::mat4’s, each of which is 16 floats. There will be no other data or padding either within the matrices or between them.

One solution would be to create a structure only for OpenGL:

But that structure doesn’t correspond to your original data at all.

glm::mat4 is, for all intents and purposes, an array of 16 floats. Not a pointer to 16 floats, an actual float[16] array.

Therefore, a vector<glm::mat4> manages a contiguous array of elements, where each element is 16 floats. It is that data that you want to store in your buffer object. So… do that.

vector manages a contiguous array of data, so it’s perfectly legal to get a pointer to this array. That’s what vector.data() is for. So that’s the source pointer you give to glBufferSubData or whatever. The size would be the number of elements in the array (vector.size()) times the size of each element as computed by sizeof.

Lastly… why are you using typedef struct in C++?

Giving a GLM mat4 to OpenGL is done by the function glm::value_ptr. Por example:

mat4 matrix;

glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(matrix));