void View::getMinMaxDistance(float* mindist, float* maxdist) { //Save min/max distance float vert[3], dist; glGetFloatv(GL_MODELVIEW_MATRIX, modelView); *maxdist = -HUGE_VAL; *mindist = HUGE_VAL; for (int i=0; i<2; i++) { vert[0] = i==0 ? min[0] : max[0]; for (int j=0; j<2; j++) { vert[1] = j==0 ? min[1] : max[1]; for (int k=0; k<2; k++) { vert[2] = k==0 ? min[2] : max[2]; dist = eyeDistance(modelView, vert); if (dist < *mindist) *mindist = dist; if (dist > *maxdist) *maxdist = dist; } } } if (*maxdist == *mindist) *maxdist += 0.0000001; //printf("DISTANCE MIN %f MAX %f\n", *mindist, *maxdist); }
void QuadSurfaces::update() { clock_t t1,t2,tt; t1 = tt = clock(); // Update and depth sort surfaces.. //Calculate distances from view plane float maxdist, mindist; view->getMinMaxDistance(&mindist, &maxdist); Geometry::update(); tt=clock(); if (geom.size() == 0) return; //Get element/quad count debug_print("Reloading and sorting %d quad surfaces...\n", geom.size()); total = 0; hiddencache.resize(geom.size()); surf_sort.clear(); int quadverts = 0; for (unsigned int i=0; i<geom.size(); i++) { int quads = (geom[i]->width-1) * (geom[i]->height-1); quadverts += quads * 4; total += geom[i]->count; //Actual vertices hiddencache[i] = !drawable(i); //Save flags debug_print("Surface %d, quads %d hidden? %s\n", i, quadverts/4, (hiddencache[i] ? "yes" : "no")); //Get corners of strip float* posmin = geom[i]->vertices[0]; float* posmax = geom[i]->vertices[geom[i]->count - 1]; float pos[3] = {posmin[0] + (posmax[0] - posmin[0]) * 0.5f, posmin[1] + (posmax[1] - posmin[1]) * 0.5f, posmin[2] + (posmax[2] - posmin[2]) * 0.5f }; //Calculate distance from viewing plane geom[i]->distance = eyeDistance(view->modelView, pos); if (geom[i]->distance < mindist) mindist = geom[i]->distance; if (geom[i]->distance > maxdist) maxdist = geom[i]->distance; //printf("%d) %f %f %f distance = %f\n", i, pos[0], pos[1], pos[2], geom[i]->distance); surf_sort.push_back(Distance(i, geom[i]->distance)); //Disable triangle sorting for these surfaces geom[i]->opaque = true; } if (total == 0) return; t2 = clock(); debug_print(" %.4lf seconds to calculate distances\n", (t2-t1)/(double)CLOCKS_PER_SEC); t1 = clock(); //Sort std::sort(surf_sort.begin(), surf_sort.end()); t2 = clock(); debug_print(" %.4lf seconds to sort\n", (t2-t1)/(double)CLOCKS_PER_SEC); t1 = clock(); //Only reload the vbo data when required //Not needed when objects hidden/shown but required if colours changed //To force, use Geometry->reset() which sets elements to -1 if (elements < 0 || elements != quadverts) { //Clear buffers close(); elements = quadverts; //Load & optimise the mesh data render(); //Send the data to the GPU via VBO loadBuffers(); } }