Learning to use VBOs properly

痞子三分冷 提交于 2019-12-05 08:33:24

The initial value is said to be 0; but it's supposed to be a pointer.

The context (not meaning the OpenGL one) matters. If one of the gl*Pointer functions is called with no Buffer Object being bound to GL_ARRAY_BUFFER, then it is a pointer into client process address space. If a Buffer Object is bound to GL_ARRAY_BUFFER it's an offset into the currently bound buffer object (you may thing the BO forming a virtual address space, to which the parameter to gl*Pointer is then an pointer into that server side address space).

Now let's have a look at your code

std::vector<float>* VertArray = new std::vector<float>;

You shouldn't really mix STL containers and new, learn about the RAII pattern.

pWorld->CreateVertexArray(VertArray);

This is problematic, since you'll delete VertexArray later on, leaving you with a dangling pointer. Not good.

unsigned short Indice = 0;
for (int i = 0; i < VertArray->size(); ++i)
{
    std::cout << (*VertArray)[i] << std::endl;
    glBufferSubData(GL_ARRAY_BUFFER, i * sizeof(float), sizeof(float), &((*VertArray)[i]));

You should submit large batches of data with glBufferSubData, not individual data points.

    glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, i * sizeof(unsigned short), sizeof(unsigned short), &(Indice));

You're passing just incrementing indices into the GL_ELEMENT_ARRAY_BUFFER, thus enumerating the vertices. Why? You can have this, without the extra work using glDrawArrays insteaf of glDrawElements.

    ++Indice;
}
delete VertArray;

You're deleting VertArray, thus keeping a dangling pointer.

Indice -= 1;

Why didn't you just use the loop counter i?

So how to fix this? Like this:

std::vector<float> VertexArray;
pWorld->LoadVertexArray(VertexArray); // World::LoadVertexArray(std::vector<float> &);

glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*VertexArray->size(), &VertexArray[0] );

And using glDrawArrays; of course if you're not enumerating vertices, but have a list of faces→vertex indices, using a glDrawElements is mandatory.

Don't call glBufferSubData for each vertex. It misses the point of VBO. You are supposed to create big buffer of your vertex data, and then pass it to OpenGL in a single go.

Read http://www.opengl.org/sdk/docs/man/xhtml/glVertexPointer.xml

When using VBOs those pointers are relative to VBO data. That's why it's usually 0 or small offset value.

stride = 0 means the data is tightly packed and OpenGL can calculate the stride from other parameters.

I usually use VBO like this:

struct Vertex
{
    vec3f position;
    vec3f normal;
};

Vertex[size] data;

...

glBufferData(GL_ARRAY_BUFFER, size*sizeof(Vertex), data, GL_STATIC_DRAW);

...

glVertexPointer(3,GL_FLOAT,sizeof(Vertex),offsetof(Vertex,position));
glNormalPointer(3,GL_FLOAT,sizeof(Vertex),offsetof(Vertex,normal));

Just pass a single chunk of vertex data. And then use gl*Pointer to describe how the data is packed using offsetof macro.

Ayyappa

For knowing about the offset of the last parameter just look at this post.... What's the "offset" parameter in GLES20.glVertexAttribPointer/glDrawElements, and where does ptr/indices come from?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!