0
\$\begingroup\$

I am currently trying to set up a little debug view as I am planning to implement occlusion queries later. For those, I have written code to determine the "extreme coordinates" of the VAO I want to run the occlusion query for. The coordinates I then want to use to build a cube (bounding volume) that contains the shape to be tested. At the moment, I am using a simple triangle as test shape.

As far as I have tested, the extreme coordinates seem correct. Based on those coordinates, I went on to build the points needed for a cube. Of course I do not feel like fiddling around with 36 values, so instead, I'd like to draw the cube using indices with only 8 points.

So far so good, but I have ran into an issue: Only about 1/3 of the cube is being drawn.

Here my code to setup vertices:

//The coordinates for the triangle shape
verticesVector.push_back(-0.4f);
verticesVector.push_back(0.1f);
verticesVector.push_back(0.0f);
verticesVector.push_back(0.4f);
verticesVector.push_back(0.1f);
verticesVector.push_back(0.0f);
verticesVector.push_back(0.0f);
verticesVector.push_back(0.7f);
verticesVector.push_back(0.3f);

//The colors for the triangle shape
colorsVector.push_back(1.0f);
colorsVector.push_back(0.0f);
colorsVector.push_back(0.0f);
colorsVector.push_back(0.0f);
colorsVector.push_back(1.0f);
colorsVector.push_back(0.0f);
colorsVector.push_back(0.0f);
colorsVector.push_back(0.0f);
colorsVector.push_back(1.0f);

glGenVertexArrays(1, &vertexArrayObject);
glGenBuffers(1, &vertexBuffer);
glGenBuffers(1, &colorBuffer);
glBindVertexArray(vertexArrayObject);

glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), &verticesVector.front(), GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), &colorsVector.front(), GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);

//Finding the extremes of the shape
float minx = std::numeric_limits<float>::max();
float miny = std::numeric_limits<float>::max();
float minz = std::numeric_limits<float>::max();
float maxx = std::numeric_limits<float>::lowest();
float maxy = std::numeric_limits<float>::lowest();
float maxz = std::numeric_limits<float>::lowest();
for (size_t i = 0; i < verticesVector.size(); i += 3)
{
    if (verticesVector[i] < minx) minx = verticesVector[i];
    if (verticesVector[i+1] < miny) miny = verticesVector[i+1];
    if (verticesVector[i+2] < minz) minz = verticesVector[i+2];

    if (verticesVector[i] > maxx) maxx = verticesVector[i];
    if (verticesVector[i+1] > maxy) maxy = verticesVector[i+1];
    if (verticesVector[i+2] > maxz) maxz = verticesVector[i+2];
}

//The indices (or elements) for the debug bounding volume
//front
cubeElements[0] = 0;
cubeElements[1] = 1;
cubeElements[2] = 2;
cubeElements[3] = 2;
cubeElements[4] = 3;
cubeElements[5] = 0;
//top
cubeElements[6] = 3;
cubeElements[7] = 2;
cubeElements[8] = 6;
cubeElements[9] = 6;
cubeElements[10] = 7;
cubeElements[11] = 3;
//back
cubeElements[12] = 7;
cubeElements[13] = 6;
cubeElements[14] = 5;
cubeElements[15] = 5;
cubeElements[16] = 4;
cubeElements[17] = 7;
//bottom
cubeElements[18] = 4;
cubeElements[18] = 5;
cubeElements[20] = 1;
cubeElements[21] = 1;
cubeElements[22] = 0;
cubeElements[23] = 4;
//left
cubeElements[24] = 4;
cubeElements[25] = 0;
cubeElements[26] = 3;
cubeElements[27] = 3;
cubeElements[28] = 7;
cubeElements[29] = 4;
//right
cubeElements[30] = 1;
cubeElements[31] = 5;
cubeElements[32] = 6;
cubeElements[33] = 6;
cubeElements[34] = 2;
cubeElements[35] = 1;

//The actual vertices made from extreme coordinates
//lower left here
boundingVertices.push_back(minx);
boundingVertices.push_back(miny);
boundingVertices.push_back(minz);

//lower right here
boundingVertices.push_back(maxx);
boundingVertices.push_back(miny);
boundingVertices.push_back(minz);

//upper right here
boundingVertices.push_back(maxx);
boundingVertices.push_back(maxy);
boundingVertices.push_back(minz);

//upper left here
boundingVertices.push_back(minx);
boundingVertices.push_back(maxy);
boundingVertices.push_back(minz);

//lower left there
boundingVertices.push_back(minx);
boundingVertices.push_back(miny);
boundingVertices.push_back(maxz);

//lower right there
boundingVertices.push_back(maxx);
boundingVertices.push_back(miny);
boundingVertices.push_back(maxz);

//upper right there
boundingVertices.push_back(maxx);
boundingVertices.push_back(maxy);
boundingVertices.push_back(maxz);

//upper left there
boundingVertices.push_back(minx);
boundingVertices.push_back(maxy);
boundingVertices.push_back(maxz);

//Generate VAO for debug view of bounding volume
glGenVertexArrays(1, &boundingAO);
glGenBuffers(1, &boundingVB);
glGenBuffers(1, &boundingCB);
glBindVertexArray(boundingAO);
glBindBuffer(GL_ARRAY_BUFFER, boundingVB);
glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(float), &boundingVertices.front(), GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

glGenBuffers(1, &elementsBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementsBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 36 * sizeof(float), cubeElements, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

Here is how I am drawing the shapes:

glBindVertexArray(boundingAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementsBuffer);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0);

glBindVertexArray(vertexArrayObject);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);

I understand, of course, that this is an awful lot of code still, but that is mostly because of the vertices.

Here is an image of how the whole thing currently looks:

Current state

My question finally is:

What am I doing wrong here, how come only half is drawn?

To clarify: The coloured triangle is the shape that is supposed to be enclosed in the (white) cube.

\$\endgroup\$
  • \$\begingroup\$ Are you sure that the missing faces of the cube aren't culled due to back-face culling? (ie being drawn backwards?) \$\endgroup\$ – Yattabyte Oct 11 '15 at 18:35
  • \$\begingroup\$ @Yattabyte I literally just now turned my computer off, I don't know for sure, but I am quite certain I put a glDisable for culling in the code somewhere. I'll look once I get back. \$\endgroup\$ – JackWhiteIII Oct 11 '15 at 18:41
  • \$\begingroup\$ @Yattabyte I did disable culling. I have no idea what is wrong. \$\endgroup\$ – JackWhiteIII Oct 12 '15 at 11:41
  • \$\begingroup\$ @Yattabyte I also swapped the winding order of all vertices, without effect. \$\endgroup\$ – JackWhiteIII Oct 12 '15 at 11:55
1
\$\begingroup\$

I am answering my own question because I have found the mistake (and a smaller one).

When I am sending the vertex data for the cube to OpenGL, I am doing the following:

glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(float), &boundingVertices.front(), GL_STATIC_DRAW);

This means I am sending 8 floats to OpenGL, which is very wrong as that number is not even divisible by 3 (x, y and z coordinates).

The correct number of bytes I want to send to OpenGL is thus 8 * 3 * sizeof(float)(8 vertices composed of 3 coordinates equals 24 floats).

Very simple mistake with huge impact.

The second discrepancy was that I was sending a wrong byte count of indices to OpenGL. I was sending 36 floats, but of course I actually meant to send 36 unsigned shorts.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.