PDA

View Full Version : Creating a VBO with std::vector



BobbyLeChimp
06-18-2016, 09:31 AM
Hallo,

eventhough I found plenty of posts online asking the same question neither of those answers could actually help me.
I am trying to create a VBO using data stored in std::vectors which I am loading from a .md5mesh file.
Even though it should work in theory and my code compiles and runs fine, it just won`t render on screen..

An small example..

Using arrays works just fine:


static const GLfloat vertex_data[] =
{
//front
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,

//the same for the other 5 sides of the cube...
};

static const GLuint indices[] =
{
0, 1, 3,
1, 2, 3,
//the same for the other 5 sides of the cube...
};

//create the vertex array object
GLuint vao;
glGenVertexArrays(1, &vao);

//bind the vao
glBindVertexArray(vao);

//create the vertex buffer object
GLuint vbo;
glGenBuffers(1, &vbo);

//copy data into the vbo
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW);

//creat the element buffer object
GLuint ebo;
glGenBuffers(1, &ebo);

//copy data into6 the ebo
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

//set the vertex attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
//set the color attribute
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3*sizeof(GLfloat)));
glEnableVertexAttribArray(1);
//set the texture attribute
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));
glEnableVertexAttribArray(2);


//unbind the vao
glBindVertexArray(0);

(........)

glBindVertexArray(vao);

//draw the cube
glDrawElements(GL_TRIANGLES, sizeof(indices), GL_UNSIGNED_INT, 0);
(........)


Using vectors doesn`t:


//converting the arrays from above to vectors
std::vector<GLfloat> v_vertex_data(vertex_data, vertex_data + sizeof vertex_data / sizeof vertex_data[0]);
std::vector<GLfloat> v_indices(indices, indices + sizeof indices / sizeof indices[0]);

//create the vertex array object
GLuint vao;
glGenVertexArrays(1, &vao);

//bind the vao
glBindVertexArray(vao);

//create the vertex buffer object
GLuint vbo;
glGenBuffers(1, &vbo);

//copy data into the vbo
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, v_vertex_data.size() * sizeof(GLfloat), v_vertex_data.data(), GL_STATIC_DRAW);

//creat the element buffer object
GLuint ebo;
glGenBuffers(1, &ebo);

//copy data into6 the ebo
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, v_indices.size() * sizeof(GLfloat), v_indices.data(), GL_STATIC_DRAW);

//set the vertex attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
//set the color attribute
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3*sizeof(GLfloat)));
glEnableVertexAttribArray(1);
//set the texture attribute
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));
glEnableVertexAttribArray(2);


//unbind the vao
glBindVertexArray(0);

(........)

glBindVertexArray(vao);

//draw the cube
glDrawElements(GL_TRIANGLES, v_indices.size(), GL_UNSIGNED_INT, 0);

(........)


Maybe I am missing something completely obvious but I just don`t get what it might be?!?


Looking forward to your answers,

BobbyLeChimp

GClements
06-18-2016, 11:15 AM
glDrawElements(GL_TRIANGLES, sizeof(indices), GL_UNSIGNED_INT, 0);


sizeof(indices) is incorrect; it should be the number of indices, not the number of bytes.





std::vector<GLfloat> v_indices(indices, indices + sizeof indices / sizeof indices[0]);


This should be GLuint, not GLfloat.

mhagain
06-18-2016, 11:18 AM
std::vector::size (http://www.cplusplus.com/reference/vector/vector/size/):
Returns the number of elements in the vector.

This is the number of actual objects held in the vector, which is not necessarily equal to its storage capacity.
When loading data to a buffer object, you need to specify the total size in bytes, not the number of elements.

GClements
06-18-2016, 05:36 PM
std::vector::size (http://www.cplusplus.com/reference/vector/vector/size/):
When loading data to a buffer object, you need to specify the total size in bytes, not the number of elements.
That part he got correct; the result of .size() is multiplied by sizeof() the element type.





glBufferData(GL_ARRAY_BUFFER, v_vertex_data.size() * sizeof(GLfloat), v_vertex_data.data(), GL_STATIC_DRAW);
...
glBufferData(GL_ELEMENT_ARRAY_BUFFER, v_indices.size() * sizeof(GLfloat), v_indices.data(), GL_STATIC_DRAW);



The problem is that the element array is a std::vector<GLfloat> but glDrawElements() is expecting integers.

BobbyLeChimp
06-19-2016, 10:18 PM
Aaaaaaaahhhh.. dammit! Thanks for the help guys! I can`t believe I missed that!
Well once I pass the right input everything works like a charm!

Thanks again!

~BobbyLeChimp