PDA

View Full Version : Giving C++ containers to OpenGL?



Talesseed
07-27-2016, 04:26 PM
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

GClements
07-27-2016, 04:39 PM
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.

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.

Alfonse Reinheart
07-27-2016, 04:45 PM
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++?

class_OpenGL
07-30-2016, 07:00 PM
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));