From 3ea7566fadf5490c46e04cb3a2a6cc8e02ac05e6 Mon Sep 17 00:00:00 2001 From: Andy Spencer Date: Sat, 22 Jan 2011 20:13:05 +0000 Subject: [PATCH] Allow disabling operations in grits_object_draw 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 | 74 +++++++++++++++++++++++++++----------- src/objects/grits-object.h | 7 ++++ 2 files changed, 60 insertions(+), 21 deletions(-) diff --git a/src/objects/grits-object.c b/src/objects/grits-object.c index 12b4f8d..b321b6e 100644 --- a/src/objects/grits-object.c +++ b/src/objects/grits-object.c @@ -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) diff --git a/src/objects/grits-object.h b/src/objects/grits-object.h index 848319a..dcacd9d 100644 --- a/src/objects/grits-object.h +++ b/src/objects/grits-object.h @@ -30,6 +30,12 @@ #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 { -- 2.43.2