+static gboolean on_motion_notify(GritsOpenGL *opengl, GdkEventMotion *event, gpointer _)
+{
+ gdouble height = GTK_WIDGET(opengl)->allocation.height;
+ gdouble gl_x = event->x;
+ gdouble gl_y = height - event->y;
+
+ /* Configure view */
+ gint viewport[4];
+ gdouble projection[16];
+ glGetIntegerv(GL_VIEWPORT, viewport);
+ glGetDoublev(GL_PROJECTION_MATRIX, projection);
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ gluPickMatrix(gl_x, gl_y, 2, 2, viewport);
+ glMultMatrixd(projection);
+
+ /* Prepare for picking */
+ guint buffer[100][4] = {};
+ glSelectBuffer(G_N_ELEMENTS(buffer), (guint*)buffer);
+ glRenderMode(GL_SELECT);
+ glInitNames();
+
+ /* Run picking */
+ g_mutex_lock(opengl->objects_lock);
+ GPtrArray *objects = _objects_to_array(opengl);
+ for (guint i = 0; i < objects->len; i++) {
+ glPushName(i);
+ GritsObject *object = objects->pdata[i];
+ object->state.picked = FALSE;
+ grits_object_pick(object, opengl);
+ glPopName();
+ }
+ int hits = glRenderMode(GL_RENDER);
+ g_debug("GritsOpenGL: on_motion_notify - hits=%d ev=%.0lf,%.0lf",
+ hits, gl_x, gl_y);
+ for (int i = 0; i < hits; i++) {
+ //g_debug("\tHit: %d", i);
+ //g_debug("\t\tcount: %d", buffer[i][0]);
+ //g_debug("\t\tz1: %f", (float)buffer[i][1]/0x7fffffff);
+ //g_debug("\t\tz2: %f", (float)buffer[i][2]/0x7fffffff);
+ //g_debug("\t\tname: %p", (gpointer)buffer[i][3]);
+ guint index = buffer[i][3];
+ GritsObject *object = objects->pdata[index];
+ object->state.picked = TRUE;
+ }
+ for (guint i = 0; i < objects->len; i++) {
+ GritsObject *object = objects->pdata[i];
+ grits_object_set_pointer(object, object->state.picked);
+ }
+ g_ptr_array_free(objects, TRUE);
+ g_mutex_unlock(opengl->objects_lock);
+
+ /* Test unproject */
+ gdouble lat, lon, elev;
+ grits_viewer_unproject(GRITS_VIEWER(opengl),
+ gl_x, gl_y, -1, &lat, &lon, &elev);
+
+ /* Cleanup */
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+
+ return FALSE;
+}
+