Artog
Artog

Reputation: 1142

OpenGL Array Buffer from a vector of pointers

Problem I have a vector of pointers to particles:

struct Particle {
    vec3 pos; // just 3 floats, GLM vec3 struct
    // ...
}
std::vector<Particle *> particles;

I want to use this vector as the source of data for an array buffer in OpenGL Like this:

glGenBuffers(1, &particleBuffer);
glBindBuffer(GL_ARRAY_BUFFER, particleBuffer);
int bufferSize = sizeof(Particle) * particles->size();
glBufferData(GL_ARRAY_BUFFER, bufferSize, /* What goes here? */, GL_STATIC_DRAW);

glEnableVertexAttribArray(positionAttribLocation);
glVertexAttribPointer(positionAttribLocation, 3, GL_FLOAT, GL_FALSE, sizeof(Particle), (void *)0);

Where the interesting line is glBufferData( ... )

How do I get OpenGL to get that the data is pointers?

Upvotes: 2

Views: 1623

Answers (2)

user2693587
user2693587

Reputation:

glBufferData requires a pointer to an array of the data you wish to use. In your case, a GLfloat[] would be used for the vertices. You could write a function which creates a GLfloat[] from the vector of particles. The code I use creates a GLfloat[] and then passes it as a pointer to a constructor which then sets the buffer data. Here is my code;

Creating the Vertex Array - GlFloat[]

GLfloat vertices[] = {  0, 0, 0, 
                        0, 3, 0,
                        8, 3, 0,
                        8, 0, 0  };

After I have created the vertices I then create a buffer object (Which just creates a new buffer and sets it's data);
Buffer* vbo = new Buffer(vertices, 4 * 3, 3);

The constructor for my buffer object is;

Buffer::Buffer(GLfloat* data, GLsizei count, GLuint componentCount) {
    m_componentCount = componentCount;

    glGenBuffers(1, &m_bufferID);
    glBindBuffer(GL_ARRAY_BUFFER, m_bufferID);
    glBufferData(GL_ARRAY_BUFFER, count * sizeof(GLfloat), data, GL_STATIC_DRAW); //Set the buffer data to the GLFloat pointer which points to the array of vertices created earlier.
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

After this array has been passed to the buffer, you can delete the object to save memory however it is recommended to hold onto it in case it is reused later.

For more information and better OpenGL practices I recommend you check out the following youtube playlist by TheChernoProject.
https://www.youtube.com/watch?v=qTGMXcFLk2E&list=PLlrATfBNZ98fqE45g3jZA_hLGUrD4bo6_&index=12

Upvotes: 0

Nicol Bolas
Nicol Bolas

Reputation: 473407

How do I get OpenGL to get that the data is pointers?

You don't.

The whole point of buffer objects is that the data lives in GPU-accessible memory. An pointer is an address, and a pointer to a CPU-accessible object is a pointer to a CPU address. And therefore is not a pointer to GPU-accessible memory.

Furthermore, accessing indirect data structures like that is incredibly inefficient. Having to do two pointer indirection just to access a single value basically destroys all chance of cache coherency on memory accesses. And without that, every independent particle is a cache miss.

That's bad. Which is why OpenGL doesn't let you do that. Or at least, it doesn't let you do it directly.

The correct way to do this is to work with a flat vector<Particle>, and move them around as needed.

Upvotes: 5

Related Questions