+ /* Render/pick objects */
+ 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);
+
+ /* Process hits */
+ 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;
+ *top = object;
+ }
+
+ /* Notify objects of pointer movements */
+ for (guint i = 0; i < objects->len; i++) {
+ GritsObject *object = objects->pdata[i];
+ grits_object_set_pointer(object, event, object->state.picked);
+ }
+
+ return hits;
+}
+
+static gboolean run_mouse_move(GritsOpenGL *opengl, GdkEventMotion *event)
+{
+ GtkAllocation alloc;
+ gtk_widget_get_allocation(GTK_WIDGET(opengl), &alloc);
+
+ gdouble gl_x = event->x;
+ gdouble gl_y = alloc.height - event->y;
+ gdouble delta = opengl->pickmode ? 200 : 2;
+
+ if (opengl->pickmode) {
+ gtk_gl_begin(GTK_WIDGET(opengl));
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ }
+
+ /* Save matricies */
+ gdouble projection[16];
+ gint viewport[4]; // x=0,y=0,w,h
+ glGetDoublev(GL_PROJECTION_MATRIX, projection);
+ glGetIntegerv(GL_VIEWPORT, viewport);
+ glMatrixMode(GL_MODELVIEW); glPushMatrix();
+ glMatrixMode(GL_PROJECTION); glPushMatrix();
+
+ g_mutex_lock(&opengl->objects_lock);
+
+ GritsObject *top = NULL;
+ GPtrArray *ortho = _objects_to_array(opengl, TRUE);
+ GPtrArray *world = _objects_to_array(opengl, FALSE);
+
+ /* Run perspective picking */
+ glMatrixMode(GL_PROJECTION); glLoadIdentity();
+ gluPickMatrix(gl_x, gl_y, delta, delta, viewport);
+ glMultMatrixd(projection);
+ gint world_hits = run_picking(opengl, (GdkEvent*)event, world, &top);
+
+ /* Run ortho picking */
+ glMatrixMode(GL_PROJECTION); glLoadIdentity();
+ gluPickMatrix(gl_x, gl_y, delta, delta, viewport);
+ glMatrixMode(GL_MODELVIEW); glLoadIdentity();
+ glOrtho(0, viewport[2], viewport[3], 0, 1000, -1000);
+ gint ortho_hits = run_picking(opengl, (GdkEvent*)event, ortho, &top);
+
+ /* Update cursor */
+ static GdkCursor *cursor = NULL;
+ static GdkWindow *window = NULL;
+ if (!window || !cursor) {
+ cursor = gdk_cursor_new(GDK_FLEUR);
+ window = gtk_widget_get_window(GTK_WIDGET(opengl));
+ }
+ GdkCursor *topcursor = top && top->cursor ? top->cursor : cursor;
+ gdk_window_set_cursor(window, topcursor);
+
+ g_debug("GritsOpenGL: run_mouse_move - hits=%d/%d,%d/%d ev=%.0lf,%.0lf",
+ world_hits, world->len, ortho_hits, ortho->len, gl_x, gl_y);
+
+ g_ptr_array_free(world, TRUE);
+ g_ptr_array_free(ortho, 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();
+ glMatrixMode(GL_MODELVIEW); glPopMatrix();
+
+ if (opengl->pickmode)
+ gtk_gl_end(GTK_WIDGET(opengl));