Will Will - 3 months ago 11
C++ Question

How can I draw a 2D grid in 3D?

I am trying to draw a simple "floor" with a grid of triangles, but only the first quarter of them are being drawn. For example, here is a screenshot of an attempt of a 5 x 5 grid:

Ignore the white thing in the corner, it's unrelated.

I've triad a few different

M x N
grids, it seems to be drawing ⌊(MxN)/4⌋ squares every time.

So, for a 5 x 5 grid:

int QUAD_DEPTH = 5;
int QUAD_WIDTH = 5;
std::vector<GLfloat> vertices;


I am loading a vector; six floats per vertex (XYZRGB), three vertices per triangle, two triangles per square:

for (int row = 0; row < QUAD_WIDTH; row++) {
for (int dist = 0; dist < QUAD_DEPTH; dist++) {
vertices.push_back(0.0f + row); // X
vertices.push_back(0.0f); // Y
vertices.push_back(0.0f + dist); // Z
vertices.push_back(1.0f); // R
vertices.push_back(0.0f); // G
vertices.push_back(0.0f); // B

vertices.push_back(1.0f + row); // X
vertices.push_back(0.0f); // Y
vertices.push_back(1.0f + dist); // Z
vertices.push_back(0.0f); // R
vertices.push_back(1.0f); // G
vertices.push_back(0.0f); // B

vertices.push_back(1.0f + row); // X
vertices.push_back(0.0f); // Y
vertices.push_back(0.0f + dist); // Z
vertices.push_back(0.0f); // R
vertices.push_back(0.0f); // G
vertices.push_back(1.0f); // B

vertices.push_back(0.0f + row); // X
vertices.push_back(0.0f); // Y
vertices.push_back(0.0f + dist); // Z
vertices.push_back(1.0f); // R
vertices.push_back(0.0f); // G
vertices.push_back(0.0f); // B

vertices.push_back(0.0f + row); // X
vertices.push_back(0.0f); // Y
vertices.push_back(1.0f + dist); // Z
vertices.push_back(0.0f); // R
vertices.push_back(1.0f); // G
vertices.push_back(0.0f); // B

vertices.push_back(1.0f + row); // X
vertices.push_back(0.0f); // Y
vertices.push_back(1.0f + dist); // Z
vertices.push_back(0.0f); // R
vertices.push_back(0.0f); // G
vertices.push_back(1.0f); // B
}
}


Then I buffer the floats:

glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);

glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertices.size(), &vertices[0], GL_STATIC_DRAW);

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);

glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);

glBindVertexArray(0);


Then draw it:

glBindVertexArray(VAO);
glUniformMatrix4fv(glGetUniformLocation(this->shader->Program, "projection"), 1, GL_FALSE, &projection[0][0]);
glUniformMatrix4fv(glGetUniformLocation(this->shader->Program, "view"), 1, GL_FALSE, &view[0][0]);
glUniformMatrix4fv(glGetUniformLocation(this->shader->Program, "model"), 1, GL_FALSE, &this->model_matrix[0][0]);
glDrawArrays(GL_TRIANGLES, 0, vertices.size());
glBindVertexArray(0);


I also tried
glDrawArrays(GL_TRIANGLES, 0, vertices.size() / 6);
since there are six floats per vertex, but it has the same result.

Am I buffering incorrectly or drawing incorrectly or is my problem somewhere else?

Answer

The problem is with your call to glBufferData():

glBufferData(GL_ARRAY_BUFFER, vertices.size(), &vertices[0], GL_STATIC_DRAW);

The second argument is the size in bytes, while you pass the number of floats in your vector. You need to multiply the size of the vector with the size of a float to get the size in bytes. For example:

glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(vertices[0]), &vertices[0], GL_STATIC_DRAW);