Smart pointer and OpenGL

Hi,

Is there any reference where the new C++14 standard has been used along with the modern application ?

I have declared array of vertices as follows:


std::vector<std::shared_ptr<Vertex>>

And I am confused on how to send the vertex data to the opengl buffer :


glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(Vertex), &this->vertices[0], GL_STATIC_DRAW); 

Thanks

[QUOTE=sajis997;1279089]Hi,

Is there any reference where the new C++14 standard has been used along with the modern application ?

I have declared array of vertices as follows:


std::vector<std::shared_ptr<Vertex>>

And I am confused on how to send the vertex data to the opengl buffer :[/quote]

You would do it the same way as if you declared this:


std::vector<Vertex *>

That is, you don’t.

std::shared_ptr is a pointer. Smart or dumb, an array of pointers-to-T isn’t the same thing as an array of T. Your glBufferData call would appear to expect an array of T, not an array of pointers-to-T, since OpenGL buffer objects are arrays of values, not arrays of pointers to values. So you should use the correct thing.

Using modern C++ does not mean throwing shared_ptr everywhere. Like any tool, you use it where it is appropriate. And it isn’t appropriate here. As a general rule, if you’re creating a std::vectorstd::shared_ptr, you should strongly consider why you need to do this and/or what you are trying to accomplish.

Oh, and if you’re using C++11 or better, there’s no reason to pass the std::vector’s pointer via &vector[0]. Just use the std::vector::data member.

This doesn’t declare an array of vertices, it declares an array of shared pointers to vertices. Which is less than ideal for interfacing with OpenGL.

Ideally, you need an array of vertices, not an array of pointers to vertices.

If all you have is an array of pointers, then you’ll need to first dereference them to create an array of vertices, e.g.


std::vector<std::shared_ptr<Vertex>> src;
std::vector<Vertex> dst;
...
    for (auto const& v : src)
        dst.push_back(*v);

After that, you can upload the vertex data from [var]dst[/var].

Alternatively, you could avoid the intermediate vector and call glBufferSubData() for each iteration of the loop:


    for (size_t i = 0; i < src.size(); ++i)
        glBufferSubData(GL_ARRAY_BUFFER, i * sizeof(Vertex), sizeof(Vertex), (const GLvoid*) &*src[i]);

But that could be significantly slower than using an intermediate vector.

Or you could map the buffer and copy directly into it:


    Vertex* dstptr = (Vertex*) glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
    for (size_t i = 0; i < src.size(); ++i)
        dstptr[i] = *src[i];
    glUnmapBuffer(GL_ARRAY_BUFFER);

Needless to say, it would be better if you could avoid having to do this by not using pointers in the first place.