OpenGL using std::vector with glm::vec3
Solution 1
In your glBufferData()
&vertices[0]
should probably have been, &vertices[0].x
.
That's because &vertices[0]
points to a glm::vec3
but you want it to point to a float
because that's what OpenGL expects.
Solution 2
I don't think you are allowed to pass complex types to the shader. I have always created a struct with a float array for the positions:
struct vertex{
GLfloat positions[3];
};
Then to use in your code:
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex) * vertices.size(),
&vertices[0], GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindVertexArray(buffer);
a_learner
Updated on June 07, 2022Comments
-
a_learner almost 2 years
I'm having the following issue.
I've loaded 8 glm::vec3 into a std::vector, such that:
std::vector <glm::vec3> vertices;
returns:
0.250000 -0.250000 -0.250000
0.250000 -0.250000 0.250000
-0.250000 -0.250000 0.250000
-0.250000 -0.250000 -0.250000
0.250000 0.250000 -0.250000
0.250000 0.250000 0.250000
-0.250000 0.250000 0.250000
-0.250000 0.250000 -0.250000if:
for(int i{0}; i<8; i++){ std::cout<<"\n"; for(int j{0}; j<3; j++){ std::cout<<vertices[i][j]<<" "; } }
When I pass the following code into OpenGL,
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * vertices.size(), &vertices[0], GL_DYNAMIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); glBindVertexArray(buffer);
my shader program loads and the window opens, however there is no cube.
A slight alteration to the first line,
glBufferData(GL_ARRAY_BUFFER, sizeof(vert), &vert, GL_DYNAMIC_DRAW); //Here glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); glBindVertexArray(buffer);
while taking vectors from,
const GLfloat vert[9] = {-0.5,-0.5, 0.0, 0.0, 0.5, 0.0, 0.5,-0.5, 0.0};
and a pretty red triangle is drawn onto the screen.
My question: Is it possible to use a vector container in combination with glm? If so, how can it be implemented?
My hypothesis:The glVertexAttribPointer function is reading sequentially from the starting address of the vertices container. The elements of the vertices container are fragmented throughout my memory. -
a_learner over 9 yearsIt does point to a glm::vec3. I tried your method and I've also tried
&vertices[0][0]
. Still, it does not render. -
Axalo over 9 years@a_learner is it possible that
vertices
gets destructed after callingglBufferData
? -
a_learner over 9 yearsThis is an interesting alternative, but surely OpenGL would allow you to send a glm::vec3 to the shader. First of all, they are essentially small arrays of floats, and secondly, GLM is the OpenGL math library, so why would they design it not to be compatible with their shaders?
-
a_learner over 9 yearsNo,
vertices
is apublic:
vector container from an object that I'm calling frommain()
. I checked thevertices
with afor
loop from main, after callingglBufferData
from a function that is public under the same class asvertices
. -
Axalo over 9 years@a_learner what are the values of
std::vector<float> vv(&vertices[0].x, &vertices[0].x + sizeof(vertex) * vertices.size());
? -
a_learner over 9 yearsI see what you did there.
std::vector<GLfloat> vv(&vertices[0].x, &vertices[0].x + sizeof(glm::vec3) * vertices.size());
gave me an exact copy ofvertices
. I then made a copystd::vector <GLfloat> v
under thepublic
of that class so it wouldn't be destroyed once I left the function call. IglBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3)*vertices.size(), &v, GL_DYNAMIC_DRAW);
AND BAM IT DREW SOMETHING! It's not exactly a cube, but damn it's something! -
a_learner over 9 yearsCube accomplished. This was my first time loading vertex data from a .obj file. I know your code worked, I'm going to study the details tomorrow, but likely I'm going change my approach since copying the container is going to kill performance. I may just throw it all into a
std::vector <GLfloat>
and forget 'std::vector <glm::vec3>` altogether. I might also forget aboutstd::vector
and store it some other way. I've heard of performance issues withstd::vector
for things greater than a cube. -
Axalo over 9 years@a_learner yes, using an array of floats is usually the way it's done.
std::vector
s are fine though. -
eklukovich over 9 yearsThis method allows for all the data for each vertex to be packaged nicely, ie. texture coordinates and normal vectors.
-
a_learner over 9 yearsYes, I know your way is one of the more popular methods.
-
Mars over 8 yearsYou are allowed to pass complex types, as long as they are designed to do so. And GLM library was designed just to support this type of usage. So there is really no point in re-inventing the wheel with own classes for vectors and matrices. And GLM is NOT part of OpenGL nor it comes from any corner of Khronos group. It is external tool based on the GLSL specs. There could be bugs or some undefined behaviour, but it's here for years and proved to be really stable and reliable.