Skip to main content

  | मौसम…

411 समाचार
Public archive edition · Attributed source reporting with original dates · AI drafts are excluded

411 REFERENCE · Wikibooks

OpenGL Programming/Bounding box

Reference material by Wikibooks contributors. This retains its source identity and is not 411 news reporting.

Concept Bounding volume We analyze the object: Minimum coordinates in X, Y and Z Maximum coordinates in X, Y and Z We compute the size necessary for the object: max-min in X, Y and Z We compute the center of the object: (min+max)/2 in X, Y and Z We compute of cube around the object: We prepare a cube of size 1 (1x1x1), centered on the origin We scale it by the size of the object We center it on the object To draw the cube: We draw the front face using 1 looping line We draw the back face using 1 looping line We draw 4 orthogonal lines to join both faces Code void draw_bbox(struct mesh* mesh) { if (mesh->vertices.size() == 0) return; // Cube 1x1x1, centered on origin GLfloat vertices[] = { -0.5, -0.5, -0.5, 1.0, 0.5, -0.5, -0.5, 1.0, 0.5, 0.5, -0.5, 1.0, -0.5, 0.5, -0.5, 1.0, -0.5, -0.5, 0.5, 1.0, 0.5, -0.5, 0.5, 1.0, 0.5, 0.5, 0.5, 1.0, -0.5, 0.5, 0.5, 1.0, }; GLuint vbo_vertices; glGenBuffers(1, &vbo_vertices); glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); GLushort elements[] = { 0, 1, 2, 3, 4, 5, 6, 7, 0, 4, 1, 5, 2, 6, 3, 7 }; GLuint ibo_elements; glGenBuffers(1, &ibo_elements); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_elements); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); GLfloat min_x, max_x, min_y, max_y, min_z, max_z; min_x = max_x = mesh->vertices[0].x; min_y = max_y = mesh->vertices[0].y; min_z = max_z = mesh->vertices[0].z; for (int i = 0; i < mesh->vertices.size(); i++) { if (mesh->vertices[i].x < min_x) min_x = mesh->vertices[i].x; if (mesh->vertices[i].x > max_x) max_x = mesh->vertices[i].x; if (mesh->vertices[i].y < min_y) min_y = mesh->vertices[i].y; if (mesh->vertices[i].y > max_y) max_y = mesh->vertices[i].y; if (mesh->vertices[i].z < min_z) min_z = mesh->vertices[i].z; if (mesh->vertices[i].z > max_z) max_z = mesh->vertices[i].z; } glm::vec3 size = glm::vec3(max_x-min_x, max_y-min_y, max_z-min_z); glm::vec3 center = glm::vec3((min_x+max_x)/2, (min_y+max_y)/2, (min_z+max_z)/2); glm::mat4 transform = glm::translate(glm::mat4(1), center) * glm::scale(glm::mat4(1), size); /* Apply object's transformation matrix */ glm::mat4 m = mesh->object2world * transform; glUniformMatrix4fv(uniform_m, 1, GL_FALSE, glm::value_ptr(m)); glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices); glEnableVertexAttribArray(attribute_v_coord); glVertexAttribPointer( attribute_v_coord, // attribute 4, // number of elements per vertex, here (x,y,z,w) GL_FLOAT, // the type of each element GL_FALSE, // take our values as-is 0, // no extra data between each position 0 // offset of first element ); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_elements); glDrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, 0); glDrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, (GLvoid*)(4*sizeof(GLushort))); glDrawElements(GL_LINES, 8, GL_UNSIGNED_SHORT, (GLvoid*)(8*sizeof(GLushort))); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glDisableVertexAttribArray(attribute_v_coord); glBindBuffer(GL_ARRAY_BUFFER, 0); glDeleteBuffers(1, &vbo_vertices); glDeleteBuffers(1, &ibo_elements); } Intersection with surfaces As seen in Scientific tutorial 05, you can improve situations where lines and surfaces are mixing, by using: /* main */ glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(1, 0); Keep GL_POLYGON_OFFSET_FILL enabled even after you draw the lines, it needs to be enabled when drawing the surfaces as well. thumb|Bounding box for a sphere You can also increase the line thickness if need be: glLineWidth(2);