How to draw set of point using one VBO? - c++

My question connected with another my question: How to render large number of similar objects?
I trying to render set of points. For one point I using this code:
glUseProgram(programId);
glUniformMatrix4fv(matrixId, 1, GL_FALSE, &(vp * getModelMatrix(pos, scale))[0][0]);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glDrawArrays(GL_POINTS, 0, 1);
glDisableVertexAttribArray(0);
I slightly puzzled with task about set of points. I allocated more memory for vertices:
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, totalParticleCount * 3 * sizeof(GLfloat), gVertexBufferData, GL_STATIC_DRAW);
And I using this draw call for rendering:
glDrawArrays(GL_POINTS, 0, totalParticleCount);
But I don't understand which transformation I must use for glUniformMatrix4fv function and how I must set vertices. I'm trying do this:
for (int i = 0; i < totalParticleCount; i++) {
gVertexBufferData[3 * i + 0] = hState[i].pos.x;
gVertexBufferData[3 * i + 1] = hState[i].pos.y;
gVertexBufferData[3 * i + 2] = hState[i].pos.z;
}
And set uniform matrix:
glUniformMatrix4fv(matrixId, 1, GL_FALSE, &vp[0][0]);
In my case I see nothing and I can't understand whats wrong.

This post (https://gamedev.stackexchange.com/questions/90471/should-unbind-buffers) turned out very helpful in my situation. After updating vertices I must bind VAO and VBO again. Now I have this working code:
for (int i=0; i<totalParticleCount; i++) {
gVertexBufferData[3 * i + 0] = hState[i].pos.x;
gVertexBufferData[3 * i + 1] = hState[i].pos.y;
gVertexBufferData[3 * i + 2] = hState[i].pos.z;
}
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, totalParticleCount * 3 * sizeof(GLfloat), gVertexBufferData, GL_STATIC_DRAW);
glUseProgram(programId);
glUniformMatrix4fv(matrixId, 1, GL_FALSE, &vp[0][0]);

Related

texture image does not map correctly

I am trying to map a texture image to a sphere.
I have vertices and texture coords in different vectors, that's why I am using glBufferSubData.
std::vector<glm::vec3> sphere_vertices;
std::vector<int> sphere_indices;
std::vector<glm::vec2> sphere_texcoords;
I don't use any colors , only vertices,indices,textures.
I am using:
// upload geometry to GPU
glBindVertexArray(sphere_VAO);
glGenBuffers(1, &sphere_vertices_VBO);
glBindBuffer(GL_ARRAY_BUFFER, sphere_vertices_VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * sphere_vertices.size() + sizeof(float) * sphere_texcoords.size(),
0, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float) * sphere_vertices.size(), sphere_vertices.data());
glBufferSubData(GL_ARRAY_BUFFER, sizeof(float) * sphere_vertices.size(), sizeof(float) * sphere_texcoords.size(), sphere_texcoords.data());
glGenBuffers(1, &sphere_indices_VBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, sphere_indices_VBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * sphere_indices.size(), sphere_indices.data(), GL_STATIC_DRAW);
// setup vertex attributes
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
// texture coords attrib
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float) , (void*)(sizeof(float) * sphere_vertices.size()));
and the image does not map correctly on the sphere.
The image I am receiving:
-- UPDATE ---
I used sphere_texcoords.push_back((glm::vec2((x + 1) / 2.0, (y + 1) / 2.0))); for texcoords and it works now!
The size of the buffer and the buffer offsets have to be specified in bytes.
Note, the size of an element is sizeof(glm::vec3) respectively sizeof(glm::vec2) rather than sizeof(float):
size_t vertices_size = sizeof(glm::vec3) * sphere_vertices.size();
size_t texcoords_size = sizeof(glm::vec2) * sphere_texcoords.size();
glBufferData(GL_ARRAY_BUFFER, vertices_size + texcoords_size, 0, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, vertices_size, sphere_vertices.data());
glBufferSubData(GL_ARRAY_BUFFER, vertices_size, texcoords_size, sphere_texcoords.data());
When named buffer object is bound the the last parameter of glVertexAttribPointer is treated as a byte offset into this buffer.
The offset of the texture coordinates has to be:
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec2), (void*)vertices_size);
In general the size of the data of a std::vector<T> v in bytes can be get by:
size_t size = sizeof(T) * v.size();
respectively
size_t size = sizeof(*v.data()) * v.size();

Updating only Color of selected Triangles, VBO update

actually Im a bit confused about using glBufferSubData and glMapBuffer. In my program I'm loading a mesh of Triangles so i created a Struct of Vertex and initialized my VertexBuffer with the data of whole mesh. I implemented ray-casting and ray-triangle intersection. What im trying to do is, if my cursor intersects with the mesh, the intersected triangle changes his color as long its get intersected. Its working at the moment but when I try to load a bigger mesh with 50.000+ Vertices it doesnt work anymore. I am updating my whole VBO with glBufferData because I dont understand how I can update only Color of Triangles with glBufferSubData. Can someone explain me how I can update only the specific part (e.g. Color) of my VBO ?
struct Vertex
{
glm::vec3 Pos;
glm::vec3 Normal;
glm::vec3 Color;
};
VertexBuffer(void* vertices, size_t size)
{
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, size, vertices, GL_DYNAMIC_DRAW);
glBindVertexArray(0);
}
void Render()
{
glBindVertexArray(vertexBuffer->VAO);
glUseProgram(Fill->program);
glUniformMatrix4fv(glGetUniformLocation(Fill->program, "model"), 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(glGetUniformLocation(Fill->program, "view"), 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(glGetUniformLocation(Fill->program, "projection"), 1, GL_FALSE, glm::value_ptr(proj));
for (int j = 0; j < numVertices; j += 3){
if (intersectPlane(this->Vertices[j], this->Vertices[j + 1], this->Vertices[j + 2], ray, orig)){
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer->buffer);
this->Vertices[j].Color = glm::vec3(1.0, 0.0, 0.0);
this->Vertices[j + 1].Color = glm::vec3(1.0, 0.0, 0.0);
this->Vertices[j + 2].Color = glm::vec3(1.0, 0.0, 0.0);
glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(Vertex), Vertices, GL_DYNAMIC_DRAW);
}
else{
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer->buffer);
this->Vertices[j].Color = glm::vec3(0.695f, 0.695f, 0.695f);
this->Vertices[j + 1].Color = glm::vec3(0.695f, 0.695f, 0.695f);
this->Vertices[j + 2].Color = glm::vec3(0.695f, 0.695f, 0.695f);
glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(Vertex), Vertices, GL_DYNAMIC_DRAW);
}
}
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer->buffer);
GLuint posLoc = glGetAttribLocation(Fill->program, "Position");
GLuint norm = glGetAttribLocation(Fill->program, "Normal");
GLuint colo = glGetAttribLocation(Fill->program, "Color");
glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, Pos));
glVertexAttribPointer(norm, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, Normal));
glVertexAttribPointer(colo, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, Color));
glEnableVertexAttribArray(posLoc);
glEnableVertexAttribArray(norm);
glEnableVertexAttribArray(colo);
glDrawArrays(GL_TRIANGLES, 0, numVertices);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glUseProgram(0);
}
glBufferSubData updates part (or the whole) of the buffer without the need to recreate it.
In your case you can do some calculus to know the position in bytes inside the buffer (so called "offset") of the edge currently selected, and update the buffer just for that pair of vertices.
glMapBuffer gives you a (virtual) pointer to the buffer. You can read or write to that address directly using your C/C++ functions. Be aware to "unmap" when done.
Now, your buffer layout is Pos,Normal,Color and repeat. So: PxPyPzNxNyNzCrCgCbPxPyPzNxNyNzCrCgCbPxPyPzNxNyNzCrCgCb... "interleaved data". You must be carefull with the positions (bytes) you update.

Drawing triangle grid with glDrawArrays() - deformation of triangles

I am creating and storingthe position of the vertices of a 256*256 grid in a simple for loop like this:
ind=0;
for(i=0, i<256, i++){
for(j=0, j<256, j++){
vertexPosition[ind].x= i;
vertexPosition[ind].y= 1.0;
vertexPosition[ind].z= j;
ind++;
I am sending these vertices to the shader using vertex arrays. However, when drawing this with
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 256*256)
glBindVertexArray(0);
I get the following result.
I understand that this has to do with how opengl draws triangles? I am creating my vertices row by row but it seems that this is not how opengl draws the triangles (obviously). I am quite stuck here and would be glad if anyone could point me in the right direction in how to get the grid to display properly
This is how I store the vertex info in buffers
//Terrain Vertex Position
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(3, VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, nrOfVertices * 3 * sizeof(GLfloat), terrainVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), BUFFER_OFFSET(sizeof(glm::vec3) * 0));
//Terrain Normals
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ARRAY_BUFFER, nrOfVertices * 3 * sizeof(GLfloat), normals, GL_STATIC_DRAW);
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), BUFFER_OFFSET(sizeof(glm::vec3) * 3));
//Terrain UV
glBindBuffer(GL_ARRAY_BUFFER, VBO[2]);
glBufferData(GL_ARRAY_BUFFER, nrOfVertices * 2 * sizeof(GLfloat), uv, GL_STATIC_DRAW);
glEnableVertexAttribArray(5);
glVertexAttribPointer(5, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec2), BUFFER_OFFSET(sizeof(glm::vec3) * 6));
glBindVertexArray(0); //End the array here
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, nrOfVertices * 3 * sizeof(GLfloat), terrainVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 3, GL_FLOAT,GL_FALSE, sizeof(glm::vec3), BUFFER_OFFSET(sizeof(glm::vec3) * 0));
^^^^^^^^^^^^^^^^^
No. Your vertices buffer VBO[0] is XYZXYZXYZ. So no stride is needed. Set it to 0.
If your buffer was XYZnnXYZnnXYZ then stride=2 (the two 'n').
Correction: The stride is a number of bytes. If you have two 'n' interleaved and your are reading each vale in buffer as a float, then the stride for each XYZ is 2*sizeof(float)
Same for Normals and UV

Cannot create more than one VAO

I am attempting to create a simple graphics system using modern (3.3) OpenGL for use in a game. Dynamic objects will have dynamic geometry and VBOs will be updated whenever there is a change. This part was very easy to implement. While everything works well so long as only one VAO is used, further calls to glGenVertexArrays don't create another object (printing the ID for the first and the second both returns 1) and something in the VAO initialization for the new objects renders the first one unable to perform any edits. Every "modern OpenGL" tutorial either only uses one object or has some pretty significant conflicts (most often the use of glVertexAttribPointer). The following code is involved with the graphics system of the objects. (Don't know how important this is, but I am using glfw3 for window and and context creation).
Init Game Object (graphics snippet)
glGenVertexArrays(1, &vertexArrayID);
glBindVertexArray(vertexArrayID);
glGenBuffers(1, &vertexCoordBufferID);
glBindBuffer(GL_ARRAY_BUFFER, vertexCoordBufferID);
glBufferData(GL_ARRAY_BUFFER, 2000 * 3 * sizeof(float), nullptr, GL_DYNAMIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(0);
allocatedVerticies = 2000;
Update Mesh
//generate mesh
std::vector<float> vertices;
vertices.reserve(voxels.size() * 3 * 12);
//Vertices are added to the vector. This part works. Removed this code for clarity.
vertexCount = vertices.size() / 3;
glBindVertexArray(vertexArrayID);
glBindBuffer(GL_ARRAY_BUFFER, vertexCoordBufferID);
if (allocatedVerticies < vertexCount)
{
//reallocate the buffers
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
allocatedVerticies = vertexCount;
}
else
{
/////////////////////////////
//reallocate the buffers- originally a reallocation was not going to be used, but glBufferSubData does not work
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
allocatedVerticies = vertexCount;
////////////////////////////////////////this does not work for some reason
//reset data
//glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size() * sizeof(float), vertices.data());
}
edited = false;
Render Object
glBindVertexArray(vertexArrayID);
glDrawArrays(GL_TRIANGLES, 0, vertexCount);
If anyone more experienced with OpenGL could point out my mistake, (or some other problem) that would be fantastic.
In code that you provided I see nothing that can cause such a behaviour. Maby you should provide your entire solution that is connected with your rendering for better understanding what is going on in your program?
By the way: if you already defined glVertexAttribPointer() for your buffor you don't have to do it every time you update the data you stored in your vertexCoordBufferID if of course you don't change the data layout and its type. Instead of:
vertexCount = vertices.size() / 3;
glBindVertexArray(vertexArrayID);
glBindBuffer(GL_ARRAY_BUFFER, vertexCoordBufferID);
if (allocatedVerticies < vertexCount)
{
//reallocate the buffers
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
allocatedVerticies = vertexCount;
}
You can use just:
vertexCount = vertices.size() / 3;
glBindBuffer(GL_ARRAY_BUFFER, vertexCoordBufferID);
if (allocatedVerticies < vertexCount)
{
//reallocate the buffers
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_DYNAMIC_DRAW);
allocatedVerticies = vertexCount;
}

OpenGL - Creating multiple VBOs incorrectly

The problem I am having is that once I create a VBO for the main geometry in a level, when I create a second for the objects, the object VBO does not work. I am assuming I have some buffer bound incorrectly but I can't for the life of me find it. I create the level VBO first and then the object VBO and again, when I disable the creation of the level VBO, the object VBO creates correctly.
Here is my code.
in level.h:
// Zone VBO
GLuint zoneVBO;
GLuint zoneVAO;
GLuint zoneIBO;
// Object VBO
GLuint objVBO;
GLuint objVAO;
GLuint objIBO;
Creation of zone (geometry) VBO - just as a note, the creation works correctly in both VBOs so the data moving around isn't the issue, it is I think, a binding error:
void WLD::createZoneVBO()
{
// Get the size for our VBO
int numVert = 0;
int numPoly = 0;
int VBOsize = 0;
int IBOsize = 0;
// Get the count of vertices and polygons
for(int i = 0; i < zoneFragMap[0x36]; i++)
{
numVert += zmeshes[i].numVert;
numPoly += zmeshes[i].numPoly;
VBOsize += zmeshes[i].numVert * sizeof(Vertex);
IBOsize += zmeshes[i].numPoly * 3 * sizeof(GLuint);
}
// Create the IBO and VBO data
GLuint* iboData = new GLuint[zonePolyProcessed * 3];
Vertex* vboData = new Vertex[zoneVertProcessed];
int iboPos = 0;
int vboPos = 0;
// Create the VBO and IBO
for(int i = 0; i < zoneFragMap[0x36]; i++)
{
// Copy the data to the IBO
memcpy(&iboData[iboPos], zmeshes[i].indices, zmeshes[i].numPoly * 3 * sizeof(GLuint));//sizeof(*zmeshes[i].indices));
// Advance the position
iboPos += zmeshes[i].numPoly * 3;
// Copy the data to the VBO
memcpy(&vboData[vboPos], zmeshes[i].vertices, zmeshes[i].numVert * sizeof(Vertex));//sizeof(*zmeshes[i].vertices));
// Advance the position
vboPos += zmeshes[i].numVert;
}
//Create VBO for the triangle
glGenBuffers(1, &zoneVBO);
glBindBuffer(GL_ARRAY_BUFFER, zoneVBO);
glBufferData(GL_ARRAY_BUFFER, zoneVertProcessed * sizeof(Vertex), vboData, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//Create the IBO for the triangle
//16 bit indices
//We could have actually made one big IBO for both the quad and triangle.
glGenBuffers(1, &zoneIBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, zoneIBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, zonePolyProcessed * 3 * sizeof(GLuint), iboData, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
// Create the VAO
glGenVertexArraysAPPLE(1, &zoneVAO);
glBindVertexArrayAPPLE(zoneVAO);
glBindBuffer(GL_ARRAY_BUFFER, zoneVAO);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
glVertexAttribPointer(opaque["position"], 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(0));
glVertexAttribPointer(opaque["normal"], 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(sizeof(float) * 3));
glVertexAttribPointer(opaque["texcoord"], 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(sizeof(float) * 6));
glVertexAttribPointer(opaque["color"], 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(sizeof(float) * 8));
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArrayAPPLE(0);
delete[] iboData;
delete[] vboData;
}
And the objects - again, the object geometry is loaded perfectly, but only if the zone geometry hasn't been loaded yet:
void WLD::createObjectVBO()
{
// Get the size for our VBO
int numVert = 0;
int numPoly = 0;
int VBOsize = 0;
int IBOsize = 0;
// Get the count of vertices and polygons
for(int i = 0; i < objFragMap[0x36]; i++)
{
numVert += objMeshes[i].numVert;
numPoly += objMeshes[i].numPoly;
VBOsize += objMeshes[i].numVert * sizeof(Vertex);
IBOsize += objMeshes[i].numPoly * 3 * sizeof(GLuint);
}
// Create the IBO and VBO data
GLuint* iboData = new GLuint[objPolyProcessed * 3];
Vertex* vboData = new Vertex[objVertProcessed];
int iboPos = 0;
int vboPos = 0;
// Create the VBO and IBO
for(int i = 0; i < objFragMap[0x36]; i++)
{
// Copy the data to the IBO
memcpy(&iboData[iboPos], objMeshes[i].indices, objMeshes[i].numPoly * 3 * sizeof(GLuint));//sizeof(*zmeshes[i].indices));
// Advance the position
iboPos += objMeshes[i].numPoly * 3;
// Copy the data to the VBO
memcpy(&vboData[vboPos], objMeshes[i].vertices, objMeshes[i].numVert * sizeof(Vertex));//sizeof(*zmeshes[i].vertices));
// Advance the position
vboPos += objMeshes[i].numVert;
}
//Create VBO for the triangle
glGenBuffers(1, &objVBO);
glBindBuffer(GL_ARRAY_BUFFER, objVBO);
glBufferData(GL_ARRAY_BUFFER, objVertProcessed * sizeof(Vertex), vboData, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//Create the IBO for the triangle
//16 bit indices
//We could have actually made one big IBO for both the quad and triangle.
glGenBuffers(1, &objIBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, objIBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, objPolyProcessed * 3 * sizeof(GLuint), iboData, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// Create the VAO
glGenVertexArraysAPPLE(1, &objVAO);
glBindVertexArrayAPPLE(objVAO);
glBindBuffer(GL_ARRAY_BUFFER, objVAO);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
glVertexAttribPointer(opaque["position"], 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(0));
glVertexAttribPointer(opaque["normal"], 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(sizeof(float) * 3));
glVertexAttribPointer(opaque["texcoord"], 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(sizeof(float) * 6));
glVertexAttribPointer(opaque["color"], 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(sizeof(float) * 8));
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArrayAPPLE(0);
}
Rendering these two VBOs:
opaque.Use();
glBindVertexArrayAPPLE(getVAO(2));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, zoneIBO);
glBindBuffer(GL_ARRAY_BUFFER, zoneVBO);
glUniformMatrix4fv(opaque("camera"), 1, GL_FALSE, glm::value_ptr(cameraMat));
renderGeometry(&cameraMat, 0, curRegion);
glBindVertexArrayAPPLE(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArrayAPPLE(objVAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, objIBO);
glBindBuffer(GL_ARRAY_BUFFER, objVBO);
glUniformMatrix4fv(opaque("camera"), 1, GL_FALSE, glm::value_ptr(cameraMat));
renderObjects(&cameraMat);
glBindVertexArrayAPPLE(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
opaque.UnUse();
To summarize, I think it's an issue in the creation of the VBOs. I think I am doing something wrong and keeping something bound when it should be bound.
// Create the VAO
glGenVertexArraysAPPLE(1, &zoneVAO);
glBindVertexArrayAPPLE(zoneVAO);
glBindBuffer(GL_ARRAY_BUFFER, zoneVAO); //<-------
glEnableVertexAttribArray(0);
In the line I have highlighted, this looks like it should be zoneVBO, not zoneVAO.
You should be checking for errors with glGetError, it might have spotted this mistake.
Also it's not required to bind the buffers before calling renderObjects. If you have the vertex pointer stored in the VAO, then you do not need to bind the buffer, as the vertex pointers already point to the correct location.