예제 #1
0
static gboolean on_motion_notify(GritsViewer *viewer, GdkEventMotion *event, gpointer _)
{
	gdouble x = viewer->drag_x - event->x;
	gdouble y = viewer->drag_y - event->y;
	gdouble lat, lon, elev, scale, rx, ry, rz;
	grits_viewer_get_location(GRITS_VIEWER(viewer), &lat, &lon, &elev);
	grits_viewer_get_rotation(GRITS_VIEWER(viewer), &rx,  &ry,  &rz);
	scale = (elev/EARTH_R/15) * (sin(deg2rad(ABS(rx)))*4+1);
	switch (viewer->drag_mode) {
	case GRITS_DRAG_PAN:  grits_viewer_pan(viewer, -y*scale, x*scale, 0); break;
	case GRITS_DRAG_ZOOM: grits_viewer_zoom(viewer, pow(2, -y/500)); break;
	case GRITS_DRAG_TILT: grits_viewer_rotate(viewer, y/10, 0, x/10); break;
	}
	viewer->drag_x = event->x;
	viewer->drag_y = event->y;
	return FALSE;
}
예제 #2
0
/****************
 * GObject code *
 ****************/
static void aweather_gui_parser_finished(GtkBuildable *_self, GtkBuilder *builder)
{
	g_debug("AWeatherGui: parser finished");
	AWeatherGui *self = AWEATHER_GUI(_self);
	self->builder = builder;

	/* Simple things */
	gchar *config   = g_build_filename(g_get_user_config_dir(), PACKAGE, "config.ini", NULL);
	gchar *defaults = g_build_filename(PKGDATADIR, "defaults.ini", NULL);
	self->prefs   = grits_prefs_new(config, defaults);
	self->plugins = grits_plugins_new(PLUGINSDIR, self->prefs);
	self->viewer  = GRITS_VIEWER(aweather_gui_get_widget(self, "main_viewer"));
	self->gtk_plugins = GTK_LIST_STORE(aweather_gui_get_object(self, "plugins"));
	grits_viewer_setup(self->viewer, self->plugins, self->prefs);
	g_free(config);
	g_free(defaults);

	/* Misc, helpers */
	site_setup(self);
	menu_setup(self);
	time_setup(self);
	prefs_setup(self);
	icons_setup(self);

	/* Default size */
	gint width  = grits_prefs_get_integer(self->prefs, "aweather/width",  NULL);
	gint height = grits_prefs_get_integer(self->prefs, "aweather/height", NULL);
	if (width && height)
		gtk_window_set_default_size(GTK_WINDOW(self), width, height);

	/* Connect signals */
	gtk_builder_connect_signals(self->builder, self);
	g_signal_connect(self, "key-press-event",
			G_CALLBACK(on_gui_key_press), self);
	g_signal_connect_swapped(self->viewer, "offline",
			G_CALLBACK(gtk_toggle_action_set_active),
			aweather_gui_get_object(self, "offline"));
	g_signal_connect_swapped(self->viewer, "refresh",
			G_CALLBACK(set_update_timeout), self);
	g_signal_connect_swapped(self->viewer, "realize",
			G_CALLBACK(aweather_gui_load_plugins), self);
}
예제 #3
0
/***********
 * Helpers *
 ***********/
static void _set_visuals(GritsOpenGL *opengl)
{
	double lat, lon, elev, rx, ry, rz;
	grits_viewer_get_location(GRITS_VIEWER(opengl), &lat, &lon, &elev);
	grits_viewer_get_rotation(GRITS_VIEWER(opengl), &rx, &ry, &rz);

	/* Set projection and clipping planes */
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	double width  = GTK_WIDGET(opengl)->allocation.width;
	double height = GTK_WIDGET(opengl)->allocation.height;
	double ang    = atan(height/FOV_DIST);
	double atmos  = 100000;
	double near   = MAX(elev*0.75 - atmos, 50); // View 100km of atmosphere
	double far    = elev + 2*EARTH_R + atmos;   // on both sides of the earth

	grits_viewer_get_location(GRITS_VIEWER(opengl), &lat, &lon, &elev);
	glViewport(0, 0, width, height);
	gluPerspective(rad2deg(ang)*2, width/height, near, far);

	/* Setup camera and lighting */
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	/* Camera 1 */
	glRotatef(rx, 1, 0, 0);
	glRotatef(rz, 0, 0, 1);

	/* Lighting */
#ifdef ROAM_DEBUG
	float light_ambient[]  = {0.7f, 0.7f, 0.7f, 1.0f};
	float light_diffuse[]  = {2.0f, 2.0f, 2.0f, 1.0f};
#else
	float light_ambient[]  = {0.2f, 0.2f, 0.2f, 1.0f};
	float light_diffuse[]  = {0.8f, 0.8f, 0.8f, 1.0f};
#endif
	float light_position[] = {-13*EARTH_R, 1*EARTH_R, 3*EARTH_R, 1.0f};
	glLightfv(GL_LIGHT0, GL_AMBIENT,  light_ambient);
	glLightfv(GL_LIGHT0, GL_DIFFUSE,  light_diffuse);
	glLightfv(GL_LIGHT0, GL_POSITION, light_position);
	glEnable(GL_LIGHT0);
	glEnable(GL_LIGHTING);

	float material_ambient[]  = {1.0, 1.0, 1.0, 1.0};
	float material_diffuse[]  = {1.0, 1.0, 1.0, 1.0};
	float material_specular[] = {0.0, 0.0, 0.0, 1.0};
	float material_emission[] = {0.0, 0.0, 0.0, 1.0};
	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT,  material_ambient);
	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,  material_diffuse);
	glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material_specular);
	glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, material_emission);
	glDisable(GL_TEXTURE_2D);
	glDisable(GL_COLOR_MATERIAL);

	/* Camera 2 */
	glTranslatef(0, 0, -elev2rad(elev));
	glRotatef(lat, 1, 0, 0);
	glRotatef(-lon, 0, 1, 0);

	glDisable(GL_ALPHA_TEST);

	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glEnable(GL_BLEND);

#ifndef ROAM_DEBUG
	glCullFace(GL_BACK);
	glEnable(GL_CULL_FACE);

	glClearDepth(1.0);
	glDepthFunc(GL_LEQUAL);
	glEnable(GL_DEPTH_TEST);
#endif

	glEnable(GL_LINE_SMOOTH);

	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
	//glShadeModel(GL_FLAT);

	g_mutex_lock(opengl->sphere_lock);
	roam_sphere_update_view(opengl->sphere);
	g_mutex_unlock(opengl->sphere_lock);
}
예제 #4
0
void grits_object_pickdraw(GritsObject *object, GritsOpenGL *opengl, gboolean pick)
{
	GritsObjectClass *klass = GRITS_OBJECT_GET_CLASS(object);

	if (!klass->draw) {
		g_warning("GritsObject: draw - Unimplemented");
		return;
	}

	/* Skip hidden objects */
	if (object->hidden)
		return;

	/* Skip object with no signals when picking */
	for (int i = 0; pick; i++) {
		if (i == NUM_SIGNALS)
			return;
		if (g_signal_has_handler_pending(object, signals[i], 0, FALSE))
			break;
	}

	/* Support GritsTester */
	if (!GRITS_IS_OPENGL(opengl)) {
		g_debug("GritsObject: draw - drawing raw object");
		klass->draw(object, opengl);
		return;
	}

	/* Calculate 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]);
		gdouble elev = eye[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);

		/* 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);
	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);

	if (pick && klass->pick)
		klass->pick(object, opengl);
	else
		klass->draw(object, opengl);

	if (!(object->skip & GRITS_SKIP_STATE)) {
		glPopAttrib();
		glMatrixMode(GL_PROJECTION); glPopMatrix();
		glMatrixMode(GL_MODELVIEW);  glPopMatrix();
	}
	g_mutex_unlock(&opengl->sphere_lock);
}
예제 #5
0
파일: env.c 프로젝트: Andy753421/grits
/* Info */
static void info_expose(GritsCallback *compass, GritsOpenGL *opengl, gpointer _env)
{
	GtkAllocation alloc;
	gtk_widget_get_allocation(GTK_WIDGET(opengl), &alloc);

	/* Create cairo  surface */
	guint            tex     = 0;
	const gchar     *label0  = "Location: %7.3lf°, %8.3lf°, %4.0fm";
	const gchar     *label1  = "Cursor:   %7.3lf°, %8.3lf°, %4.0fm";
	gdouble          width   = 300;
	gdouble          height  = 200;
	cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
	cairo_t         *cairo   = cairo_create(surface);

	/* Text */
	gdouble lat, lon, elev;
	grits_viewer_get_location(GRITS_VIEWER(opengl), &lat, &lon, &elev);
	gchar *text0 = g_strdup_printf(label0, lat, lon, elev);
	gchar *text1 = g_strdup_printf(label1, lat, lon, elev);

	/* Draw outline */
	cairo_set_line_width(cairo, 3);
	cairo_set_source_rgba(cairo, 0, 0, 0, 0.75);
	cairo_move_to(cairo, 2, 20); cairo_text_path(cairo, text0);
	cairo_move_to(cairo, 2, 40); cairo_text_path(cairo, text1);
	cairo_stroke(cairo);

	/* Draw filler */
	cairo_set_source_rgba(cairo, 1, 1, 1, 1);
	cairo_move_to(cairo, 2, 20); cairo_show_text(cairo, text0);
	cairo_move_to(cairo, 2, 40); cairo_show_text(cairo, text1);

	/* Setup pango */
	PangoLayout          *layout = pango_cairo_create_layout(cairo);
	PangoFontDescription *font   = pango_font_description_from_string("Mono 9");
	pango_layout_set_font_description(layout, font);
	pango_font_description_free(font);
	pango_layout_set_text(layout, text0, -1);
	pango_cairo_update_layout(cairo, layout);
	cairo_set_line_join(cairo, CAIRO_LINE_JOIN_ROUND);
	cairo_move_to(cairo, 2, 40);
	pango_cairo_layout_path(cairo, layout);
	for (float w = 0.2; w <= 0.8; w+=0.2) {
		cairo_set_line_width(cairo, (1-w)*8);
		cairo_set_source_rgba(cairo, 0, 0, 0, w);
		cairo_stroke_preserve(cairo);
	}
	cairo_set_source_rgba(cairo, 1, 1, 1, 1);
	pango_cairo_show_layout(cairo, layout);

	/* Load GL texture */
	glEnable(GL_TEXTURE_2D);
	glGenTextures(1, &tex);
	glBindTexture(GL_TEXTURE_2D, tex);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glPixelStorei(GL_PACK_ALIGNMENT, 1);
	glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height,
	        0, GL_BGRA, GL_UNSIGNED_BYTE, cairo_image_surface_get_data(surface));
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

	/* Draw surface */
	glDisable(GL_LIGHTING);
	glDisable(GL_COLOR_MATERIAL);
	glDisable(GL_DEPTH_TEST);
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, tex);
	glDisable(GL_CULL_FACE);
	glTranslatef(alloc.width - width, alloc.height - height, 0);
	glBegin(GL_QUADS);
	glTexCoord2f(1, 0); glVertex3f(width, 0     , 0); // 0 - 3    0
	glTexCoord2f(1, 1); glVertex3f(width, height, 0); // 1 - |    |
	glTexCoord2f(0, 1); glVertex3f(0    , height, 0); // 2 - |    |
	glTexCoord2f(0, 0); glVertex3f(0    , 0     , 0); // 3 - 2----1
	glEnd();
}