You can use c++. There are a few ways of doing it. An easy way is to use std::ifstream to open the file, then while not end of file get each line, and do whatever you need to based off of the first character of the current line for the .obj file.
No, you didn't really tell it what the data is, it has the data, but it doesn't know how to use it.
It is stored with the VAO, not the VBO. The VBO just acts a a buffer to pass data to the VAO, once its there it stays on the graphics card until glDeleteVertexArrays(1, &VAO); is called, or until VAO is released by the containing class(Model/Mesh) being destroyed. I've tested this, the VBO can go out of scope and the model will still render, but VAO cannot.
float vertices [] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f };
float textureCoords [] = {
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 0.0f,};
float normals [] = {
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f };
unsigned int VAO;
unsigned int VBO_verts;
unsigned int VBO_textureCoords;
unsigned int VBO_normals;
glGenVertexArrays(1, &VAO);
// This generates the VertexAttributeObject
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO_verts);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// This fills the buffer with data, but doesn't tell it what it is
glBindVertexArray(VAO); // Set current VAO to use
glEnableVertexAttribArray(0); // Enable whatever the first element is, typically vertex positions
// The order of the elements MUST match the shader's order, otherwise it'll use the wrong pieces of data from the VAO/VBO
// This line tells it how to split the data into something useful.
glVertexAttribPointer(0, // index to use, the same number we just enabled for vertex positions
3, // the size of the element
GL_FLOAT, // GL_FLOAT tells it the type(GLfloat)
GL_FALSE, // Is it already normalized, honestly I don't know what that means with vertex data so I leave it false
0, // the stride to the beginning of the next vertex element(textureCoods, which aren't in this array)
(GLvoid*)(NULL + (0 * sizeof(GLfloat))); // Position to start from
glBindBuffer(GL_ARRAY_BUFFER, VBO_textureCoords);
glBufferData(GL_ARRAY_BUFFER, sizeof(textureCoords), textureCoords, GL_STATIC_DRAW);
glEnableVertexAttribArray(1); // Enable whatever the second element is, normal/texture coords/color/whatever
glVertexAttribPointer(1, // Second element, were going to use texture coords
2, // the size of the element, only 2 floats this time
GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
glBindBuffer(GL_ARRAY_BUFFER, VBO_normals);
glBufferData(GL_ARRAY_BUFFER, sizeof(normals), normals, GL_STATIC_DRAW);
glEnableVertexAttribArray(2); // Enable whatever the third element is, normal/texture coords/color/whatever
glVertexAttribPointer(2, // Third element, were going to use normals
3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
glBindVertexArray(0); // Set current VAO to nothing first, so that the VBOs won't accidently get released or over written
glBindBuffer(GL_ARRAY_BUFFER, 0);
You can also use an interleaved data, hopefully I didn't make any mistakes with the above or below code:
float vertexData_Interleaved[] = {
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f };
unsigned int VAO;
unsigned int VBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindVertexArray(VAO);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE,
8 * sizeof(GLfloat), // Vertex position size(3 floats) + texture coord size(2 floats) + normals size(3 floats)
(GLvoid*)(NULL + (3 * sizeof(GLfloat))); // Position to start from
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE,
8 * sizeof(GLfloat), // Vertex position size(3 floats) + texture coord size(2 floats) + normals size(3 floats)
(GLvoid*)(NULL + (5 * sizeof(GLfloat))); // Position to start from
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
After this you can delete the vertex data array(s).