]> Pileus Git - grits/commitdiff
Allow disabling operations in grits_object_draw
authorAndy Spencer <andy753421@gmail.com>
Sat, 22 Jan 2011 20:13:05 +0000 (20:13 +0000)
committerAndy Spencer <andy753421@gmail.com>
Sat, 22 Jan 2011 20:24:04 +0000 (20:24 +0000)
Objects now include a GRITS_SKIP_* bitmask used for disabling various
operations in grits_object_draw. The default is to perform all tests and
operations, however some of these are expensive. Objects which do not
need some operations or take care of it themselves can disable the tests
in grits_object_draw to save processing time.

For instance, saving the OpenGL state can be quite costly for simple
objects.

src/objects/grits-object.c
src/objects/grits-object.h

index 12b4f8d74168fe4dfbbbd1309648e7a9ca8ba974..b321b6e994493a3ff71e1abb732870f7cf5256d7 100644 (file)
@@ -57,38 +57,67 @@ void grits_object_draw(GritsObject *object, GritsOpenGL *opengl)
        if (object->hidden)
                return;
 
-       /* Skip out of range objects */
-       if (object->lod > 0) {
+       /* Support GritsTester */
+       if (!GRITS_IS_OPENGL(opengl)) {
+               g_debug("GritsObject: draw - drawing raw object");
+               klass->draw(object, opengl);
+               return;
+       }
+
+       /* Calculae distance for LOD and horizon tests */
+       GritsPoint *center = &object->center;
+       if ((!(object->skip & GRITS_SKIP_LOD) ||
+            !(object->skip & GRITS_SKIP_HORIZON)) &&
+           (center->elev != -EARTH_R)) {
                /* LOD test */
                gdouble eye[3], obj[3];
-               grits_viewer_get_location(GRITS_VIEWER(opengl), &eye[0], &eye[1], &eye[2]);
+               grits_viewer_get_location(GRITS_VIEWER(opengl),
+                               &eye[0], &eye[1], &eye[2]);
                gdouble elev = eye[2];
-               lle2xyz(eye[0], eye[1], eye[2], &eye[0], &eye[1], &eye[2]);
-               lle2xyz(object->center.lat, object->center.lon, object->center.elev,
-                       &obj[0], &obj[1], &obj[2]);
+               lle2xyz(eye[0], eye[1], eye[2],
+                               &eye[0], &eye[1], &eye[2]);
+               lle2xyz(center->lat, center->lon, center->elev,
+                               &obj[0], &obj[1], &obj[2]);
                gdouble dist = distd(obj, eye);
-               if (object->lod < dist)
-                       return;
-
-               /* Horizon testing */
-               gdouble c = EARTH_R+elev;
-               gdouble a = EARTH_R;
-               gdouble horizon = sqrt(c*c - a*a);
-               if (dist > horizon)
-                       return;
+
+               /* Level of detail test */
+               if (!(object->skip & GRITS_SKIP_LOD)
+                               && object->lod > 0) {
+                       if (object->lod < dist)
+                               return;
+               }
+
+               /* Horizon test */
+               if (!(object->skip & GRITS_SKIP_HORIZON)) {
+                       gdouble c = EARTH_R+elev;
+                       gdouble a = EARTH_R;
+                       gdouble horizon = sqrt(c*c - a*a);
+                       if (dist > horizon)
+                               return;
+               }
        }
 
        /* Save state, draw, restore state */
        g_mutex_lock(opengl->sphere_lock);
-       glPushAttrib(GL_ALL_ATTRIB_BITS);
-       glMatrixMode(GL_PROJECTION); glPushMatrix();
-       glMatrixMode(GL_MODELVIEW);  glPushMatrix();
+       if (!(object->skip & GRITS_SKIP_STATE)) {
+               glPushAttrib(GL_ALL_ATTRIB_BITS);
+               glMatrixMode(GL_PROJECTION); glPushMatrix();
+               glMatrixMode(GL_MODELVIEW);  glPushMatrix();
+       }
+
+       if (!(object->skip & GRITS_SKIP_CENTER))
+               grits_viewer_center_position(GRITS_VIEWER(opengl),
+                               object->center.lat,
+                               object->center.lon,
+                               object->center.elev);
 
        klass->draw(object, opengl);
 
-       glPopAttrib();
-       glMatrixMode(GL_PROJECTION); glPopMatrix();
-       glMatrixMode(GL_MODELVIEW);  glPopMatrix();
+       if (!(object->skip & GRITS_SKIP_STATE)) {
+               glPopAttrib();
+               glMatrixMode(GL_PROJECTION); glPopMatrix();
+               glMatrixMode(GL_MODELVIEW);  glPopMatrix();
+       }
        g_mutex_unlock(opengl->sphere_lock);
 }
 
@@ -102,6 +131,9 @@ void grits_object_queue_draw(GritsObject *object)
 G_DEFINE_ABSTRACT_TYPE(GritsObject, grits_object, G_TYPE_OBJECT);
 static void grits_object_init(GritsObject *object)
 {
+       object->center.lat  =  0;
+       object->center.lon  =  0;
+       object->center.elev = -EARTH_R;
 }
 
 static void grits_object_class_init(GritsObjectClass *klass)
index 848319a61c6f7a63417c16098f718902a2c21fe8..dcacd9dbe5fd459c3f5b6112222bd170c8e487b2 100644 (file)
 #define GRITS_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE   ((klass), GRITS_TYPE_OBJECT))
 #define GRITS_OBJECT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),   GRITS_TYPE_OBJECT, GritsObjectClass))
 
+/* Bitmask of things to skip while drawing the object */
+#define GRITS_SKIP_LOD     (1<<0)
+#define GRITS_SKIP_HORIZON (1<<1)
+#define GRITS_SKIP_CENTER  (1<<2)
+#define GRITS_SKIP_STATE   (1<<3)
+
 typedef struct _GritsObject      GritsObject;
 typedef struct _GritsObjectClass GritsObjectClass;
 
@@ -41,6 +47,7 @@ struct _GritsObject {
        GritsPoint   center; // Center of the object
        gboolean     hidden; // If true, the object will not be drawn
        gdouble      lod;    // Level of detail, used to hide small objects
+       guint32      skip;   // Bit mask of safe operations
 };
 
 struct _GritsObjectClass {