0

In c++ and openGL4 I can do something like this

std::vector<Vertex> vertices;

Where Vertex is a class that holds the relevant per vertex data.

this->vertices.pushback(Vertex())
....define the rest of the vertices and set position and color data etc

//Opengl code
glBindBuffer(GL_ARRAY_BUFFER, this->vboID[0]);
glBufferData(GL_ARRAY_BUFFER, ( this->vertices.size() * sizeof(Vertex) ) , this->vertices.data(), GL_STATIC_DRAW);
glVertexAttribPointer((GLuint)0, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid *)0); // Set up our vertex attributes pointer
glEnableVertexAttribArray(0);

This works fine and displays what I am rendering fine. Now if I try to make the vector

std::vector<Vertex*> vertices;
this->vertices.push_back(new Vertex());
....

then the shape I want to display never shows up.

My question is this because I use pointers that the data is no longer continuous and so opengl can't read the vertex data or is it possible to alter the openGL code to accept the vector of pointers?

0

3 Answers 3

2

Well, of course. In the first version, you are passing the actual Vertex instances to OpenGL as a byte buffer. In the second version, you are passing pointers to the Vertex instances to OpenGL, and OpenGL won't dereference these pointers for you.

You need to use the first version, there is no way to pass pointers to your Vertices to OpenGL.

Sign up to request clarification or add additional context in comments.

Comments

2

OpenGL needs the raw vertex data. It has no conception of how that data is formatted when it is being buffered. It's a dumb buffer. It is not possible for OpenGL to accept the vector of pointers - even if it did, it would still have to extract the vertices and put them into a contiguous array for optimal layout and sending to the graphics hardware.

What you're doing is sending a bunch of raw data to the graphics hardware that will be interpreted as vertices per glVertexAttribPointer. Imagine it is doing a reinterpret_cast behinds the scenes - it is now interpreting some (say, 32-bit integral) pointers as though they were supposed to be sets of 4, 32-bit, floating point values.

I suspect you opted to make a vector of vertex pointers rather than an array of vertices because of the overhead when inserting into the vector? You should pre-size your vector with a call to reserve or resize, whichever is more appropriate so as to pay the reallocation costs once only.

4 Comments

Cheers for the detailed response mate. I would have accepted this as the answer but already accepted Kristian's answer.
You can change the accepted answer, but that's at your discretion. Upvoting is never the less valid, regardless of the selected answer. Thanks.
Once I have the reputation to I will ;)
Yup, this answer is better than mine ;-)
1

Do not use std::vector <...>::data (...) if you care about portability. That does not exist in older versions of C++. Beginning with C++03, &std::vector <...> [0] is guaranteed to return the address of a contiguous block of data representing the first element stored in the vector. It worked this way long before that, but this was the first time the behavior was absolutely guaranteed.

But your fundamental problem here is that GL is not going to dereference the pointers you stored in your vector when it comes time to get data. That is what your vector stores, after all. You need the vector to store actual data, and not a list of pointers to data.

4 Comments

I'm not sure I agree with avoiding vector::data(). It's much clearer than &vector[0] IMHO. Please do correct me if I'm wrong but C++03 should let you call data()
@StevenLu: No, data (...) was added to std::vector in C++11. It is definitely something to avoid if you want to support a wide range of systems. If you are using something like the GNU toolchain or Xcode then upgrading your development environment for this one function may not be a big issue. If you are using a commercial compiler or working on an embedded platform, often you cannot upgrade your compiler just so you can use functions that are only available in a newer version of the standard. I actually find taking the address of the first element to be more understandable than data ().
I used it with a stdlib bundled with a compiler that couldn't handle C++11 features (gcc 4.3). I am positive data() is not a C++11 addition regardless of what the reference sites declare (they probably label it C++11 because of the addition of the noexcept keyword at its declaration). At any rate, I will submit that this is completely not something worth arguing about so the take-away here is that if data() isn't declared for you, just go ahead and take the address of the first element of the vector.
The compiler does not have to handle any special features for it to be available, it is merely an addition to the C++ standard library. But if you look at the specification for C++03, you will not see std::vector::data (if it were there, it would be at the bottom of pg. 490). You also will not find it in C++TR. It was introduced with C++11, and the triviality of implementing the function means it can be back-ported to any other implementation. But you are only guaranteed to have it in C++11.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.