Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically Packing Data for Vertex Buffer Objects of OpenGL

Tags:

c++

opengl

vbo

I am trying to write a wrapper for VBOs in OOP which consists of addVertex, addNormal.. addX, flush() and render() functions. At first, I am holding vertices, normals, indices in separate vectors like :

std::vector<glm::vec4> vertexBuffer;
std::vector<glm::vec4> colorBuffer;
std::vector<glm::vec3> normalBuffer;
std::vector<glm::vec2> texCoordBuffer;
std::vector<unsigned int> indexBuffer;

But as I read somewhere, holding different VBO IDs for each one is totally inefficient so it is better to pack them in order like VertexNormalTexCoordColor - VNTC - VNTC..., and represent them in a single VBO ID. Therefore the buffer can be used efficiently when uploaded to GPU. So this time I am still holding them in vectors but when I call flush() I want to pack them with structs, then upload that struct vector to GPU :

struct VBOData {
    glm::vec4 vert;
    glm::vec3 normal;
    glm::vec4 color;
    glm::vec2 texcoord;
};
std::vector<VBOData> vboBuffer;

and then i upload everything in flush() :

vboBuffer.reserve(vertexBuffer.size());

for (int i = 0; i < vertexBuffer.size(); ++i) {
    VBOData data;
    data.vert = vertexBuffer[i];
    data.color = colorBuffer[i];
    data.normal = normalBuffer[i];
    data.texcoord = texCoordBuffer[i];
    vboBuffer.push_back(data);
}

glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, vboBuffer.size() * sizeof(VBOData), (GLchar*) &vboBuffer[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

Now there is this problem, what if my object doesn't contain colors, normals, or tex coords and only consists of vertices ? Or only about vertices and normals ? Or different combinations of data that will always have vertices ? Can I dynamically pack them in V(N)(T)(C) order for efficiency ?

like image 351
deniz Avatar asked Oct 16 '13 05:10

deniz


People also ask

What are OpenGL buffers?

Buffer Objects are OpenGL Objects that store an array of unformatted memory allocated by the OpenGL context (AKA the GPU). These can be used to store vertex data, pixel data retrieved from images or the framebuffer, and a variety of other things.

What are vertex attributes in OpenGL?

A vertex attribute is an input variable to a shader that is supplied with per-vertex data. In OpenGL core profile, they are specified as in variables in a vertex shader and are backed by a GL_ARRAY_BUFFER . These variable can contain, for example, positions, normals or texture coordinates.

What is VAO OpenGL?

A Vertex Array Object (VAO) is an OpenGL Object that stores all of the state needed to supply vertex data (with one minor exception noted below). It stores the format of the vertex data as well as the Buffer Objects (see below) providing the vertex data arrays.

How do you use VBO?

Creating a VBO requires 3 steps; Generate a new buffer object with glGenBuffers(). Bind the buffer object with glBindBuffer(). Copy vertex data to the buffer object with glBufferData().


1 Answers

Now there is this problem, what if my object doesn't contain colors, normals, or tex coords and only consists of vertices ? Or only about vertices and normals ?

Then you are going to set the offset to components you got with glVertexAttribPointer, and not set of components you are not using.

BTW you have a nice tutorial on opengl.org about VBOs.

like image 174
BЈовић Avatar answered Oct 15 '22 10:10

BЈовић