I'm working on creating a cloth simulation in openGL and I've been trying to use a VAO and VBO for rendering rather than the old immediate mode (glBegin, glEnd).
I reckon it's best if I only provide the relevant parts of the code rather than the all of it. So I currently have a class, Cloth, that stores the the mass (nodes) in a vector.
class Cloth {
private:
std::vector<Mass>masses;
public:
std::vector<Mass> getMasses() { return masses; };
// functions below
And a class, Mass.
class Mass {
glm::vec3 currentPos;
glm::vec3 oldPos;
glm::vec3 acceleration;
// functions below
I've createad a VBO like so
glGenBuffers(1, &VBO_ID);
glBindBuffer(GL_ARRAY_BUFFER, VBO_ID);
glBufferData(GL_ARRAY_BUFFER, cloth.getMasses().size() * sizeof(Mass), &cloth.getMasses().front(), GL_DYNAMIC_DRAW);
and a VAO
glGenVertexArrays(1, &VAO_ID);
glBindVertexArray(VAO_ID);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GL_FLOAT), 3*sizeof(GL_FLOAT)); // unsure about this part
From what I've gathered, by calling glVertexAttribPointer, you tell the VBO how to handle the data that has been given to it. I gave it a vector of type Mass.
What would be the correct way for me to tell it how to handle the data so that it uses currentPos as vertexes?
and
Is there a better (performance-wise) way of doing this, and if so, how and why?
For example, would it be best to use a struct to hold the currentPos?
I don't see anything wrong with the code. But with vertexBuffer attributes, you don't need to tell the openGL state machine to use currentPos as a vertex, this will be done in the vertex shader.
EDIT I see something wrong with the code. I thought you only sent primitive types. You cannot send your class to your GLSL code and hope that it will work. YOu can send data and the glVertexAttribPointer tells your shader the layout of your data. What you are doing cannot work.
I'd advise you to take a look at https://learnopengl.com/ it helped me a lot and is very complete.
You'll have:
layout (location = 0) in vec3 currentPos;
layout (location = 1) in vec3 oldPos;
layout (location = 2) in vec2 acceleration;
Then you output the position of the vertex with this:
gl_Position = mvp*vec4(currentPos, 1.0);
mvp beeing the Model View Projection matrix that you would probably send as a uniform.
What comes next is a bit out of the scope of your answer but might be interesting:
While I don't know exactly what you're trying to do, you should ne that in the vertex shader you cannot edit the vertex attributes, this means that considering how your code looks right now, you'll have to update your VBO every step of the simulation. you can either update it on you CPU (which might be slow), but it might be significantly faster to do it in a compute shader.