Пример #1
0
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);
}
Пример #2
0
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();
  }
}