Hi thanks for clicking into my post first. I am recently learning OpenGL from scratch (Just finish the multiple boxes tutorial in learnopengl.com).
The tutorial is easy to understand. But when it comes to real scenario, things are becoming different. It only shows how one VBO binding to one VAO. In theory, VAO is just the way organizing similar VBOs together (same attributes and shaders). Now suppose I have 10k houses with different locations and shape, but they share the same shaders and attributes. Obviously, I could allocate 10k VAOs and 10k VBOs and 10k 10k EBOs to make 10k drawCalls to accomplish this. However, everyone would punch on my face in the forum if I did that I believe. Instead, I want to put these 10k VBOs & EBOs inside one VAO. However, I don’t know what is going wrong but it simply doesn’t render anything. (or I set camera in the wrong position?)
TL;DR
More details: I read data from disk dynamically and assigning them to "std::vector<std::vector<Vertex>> houses, there Vertex is just a simple class that represents the vertex (sizeof(Vertex) = 32, including 8 floats of data to represent position, color & textureCoord, honestly I wonder thy it’s only 32 bytes, coz the data itself has 4*8 bytes already, and a class should have some overhead. but it is continuous block of memory so I think it is fine). Now the code to bind my data is like this:
std::vector<std::vector<Vertex>> houses
std::vector<std::vector<unsigned int>> housesIndices
GLuint *VBOs;
GLuint *EBOs;
GLuint VAO;
GLShader shader;
unsigned int totalIndices = 0;
glGenVertexArrays(1, &VAO);
shader = GLShader("myshader.vs", "myshader.fs"); // I used the Shader class at learnopengl.com
VBOs = new GLuint[houses.size()];
EBOs = new GLuint[houses.size()];
glBindVertexArray(VAO);
for(size_t i = 0; i < houses.size(); ++i){
glGenBuffers(1, &VBOs[i]);
glBindBuffer(GL_ARRAY_BUFFER, VBOs[i]);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex)*houses[i].size(), &houses[i][0], GL_STATIC_DRAW);
glGenBuffers(1, &EBOs[i]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBOs[i]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)*housesIndices[i].size(), &housesIndices[i][0], GL_STATIC_DRAW);
totalIndices += housesIndices[i].size();
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
glEnableVertexAttribArray(0);
// this is to aoivd if I accidentally set my vertex in clockwise order
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glBindVertexArray(0);
}
// in rendering loop:
shader.use();
glm::mat4 model = glm::mat4(1.0f);
shader.setMat4("model", model);
// xmin is the min value of vertices in these houses, same for xmax, ymin, ymax
// I just wanna have a top down view of these houses, the z value is guaranteed to be small, around 0
// camera_dir is (0, 0, -1.0f) camera_up_ is(0, 1.0f, 0)
camera_pos_ = glm::vec3((xmin+xmax)/2, (ymin+ymax)/2, 50.0f);
view = glm::lookAt(camera_pos_, camera_pos_ + camera_dir_, camera_up_);
shader.setMax4("view", view);
// projection
glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)width/(float)height, 0.1f, 100.0f);
shader.setMat4("projection", projection);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, totalIndices, GL_UNSIGNED_INT, 0);
The shader I use is just having “aPos” as one attribute and three uniform mat4 representing MVP matix. In fragshader itonly outputs red color
Is it the correct way to bind VBOs, EBOs & VAO? Please correct me if I did something wrong in my code.
Note: Qt5.6, (I set OpenGL version to 3.3 in Qt format), Ubuntu 16.04, C++14