Exemple #1
0
static void
on_cam_renderer_param_widget_changed (GtkuParamWidget *pw, const char *param,
        void *user_data)
{
    cam_renderer_t *cr = (cam_renderer_t*) user_data;

    // delete the old texture object if it exists.  make sure that we've
    // selected the correct OpenGL context
    if (cr->texture) {
        if (cr->render_place == RENDER_IN_WIDGET) {
            gtku_gl_drawing_area_set_context (cr->gl_area);
        } else {
            gtku_gl_drawing_area_set_context (cr->renderer->viewer->gl_area);
        }

        glutil_texture_free (cr->texture);
        cr->texture = NULL;
    }

    cr->render_place = gtku_param_widget_get_enum (pw, PARAM_RENDER_IN);
    if (cr->render_place == RENDER_IN_WIDGET) {
        gtk_widget_show (GTK_WIDGET (cr->gl_area));
    } else {
        gtk_widget_hide (GTK_WIDGET (cr->gl_area));
    }

    cr->is_uploaded = 0;
    viewer_request_redraw (cr->renderer->viewer);
}
Exemple #2
0
static gboolean 
on_scroll_notify (GtkWidget *widget, GdkEventScroll *event, void *user_data)
{
    Viewer *self = (Viewer*) user_data;

    gtku_gl_drawing_area_set_context (self->gl_area);
    double ray_start[3];
    double ray_dir[3];
    _window_coord_to_ray (event->x, widget->allocation.height - event->y, ray_start, ray_dir);
    
    // give picking handler first dibs
    int consumed = 0;
    if (self->picking_handler && !self->picking_handler->picking)
        self->picking_handler = NULL;
    if (self->picking_handler && self->picking_handler->enabled && self->picking_handler->mouse_scroll) {
        consumed = self->picking_handler->mouse_scroll(self, self->picking_handler, ray_start, ray_dir, event);
        update_status_bar(self);
    }

    // try all the other handlers in order of priority
    for (unsigned int eidx = 0; !consumed && eidx < g_ptr_array_size(self->event_handlers); eidx++) {
        EventHandler *handler = g_ptr_array_index(self->event_handlers, eidx);
        
        if (handler != self->picking_handler && handler->enabled && handler->mouse_scroll)
            if (handler->mouse_scroll(self, handler, ray_start, ray_dir, event))
                break;
    }

    return TRUE;
}
Exemple #3
0
static gboolean 
on_motion_notify (GtkWidget *widget, GdkEventMotion *event, void *user_data)
{
    Viewer *self = (Viewer*) user_data;

    gtku_gl_drawing_area_set_context (self->gl_area);
    double ray_start[3];
    double ray_dir[3];
    _window_coord_to_ray (event->x, widget->allocation.height - event->y, ray_start, ray_dir);
    
    // is anyone hovering?
    if (self->picking_handler == NULL || !self->picking_handler->picking) {

        // find a new hover?
        double best_distance = HUGE;
        EventHandler *best_handler = NULL;
        
        for (unsigned int eidx = 0; eidx < g_ptr_array_size(self->event_handlers); eidx++) {
            EventHandler *handler = g_ptr_array_index(self->event_handlers, eidx);
            
            handler->hovering = 0;

            if (handler->enabled && handler->hover_query) {
                double this_distance = handler->hover_query(self, handler, ray_start, ray_dir);
                if (this_distance < best_distance && this_distance >= 0) {
                    best_distance = this_distance;
                    best_handler = handler;
                }
            }
        }

        // notify the new handler
        if (best_handler)
            best_handler->hovering = 1;

        viewer_request_redraw(self);
    }

    // give picking handler first dibs
    int consumed = 0;
    if (self->picking_handler && !self->picking_handler->picking)
        self->picking_handler = NULL;
    if (self->picking_handler && self->picking_handler->enabled && self->picking_handler->mouse_motion) {
        consumed = self->picking_handler->mouse_motion(self, self->picking_handler, ray_start, ray_dir, event);
        update_status_bar(self);
    }

    // try all the other handlers in order of priority
    for (unsigned int eidx = 0; !consumed && eidx < g_ptr_array_size(self->event_handlers); eidx++) {
        EventHandler *handler = g_ptr_array_index(self->event_handlers, eidx);
        
        if (handler != self->picking_handler && handler->enabled && handler->mouse_motion)
            if (handler->mouse_motion(self, handler, ray_start, ray_dir, event))
                break;
    }

    return TRUE;
}
static void
gtku_gl_drawing_area_size_allocate (GtkWidget * widget,
        GtkAllocation * allocation)
{
    GtkuGLDrawingArea * self = GTKU_GL_DRAWING_AREA (widget);

    /* chain up */
    GTK_WIDGET_CLASS (gtku_gl_drawing_area_parent_class)->size_allocate (widget,
            allocation);

    /* Resize the OpenGL area to match the allocation size. */
    if (gtku_gl_drawing_area_set_context (self) == 0)
        glViewport (0, 0, allocation->width, allocation->height);
}
Exemple #5
0
static gboolean
on_gl_area_expose (GtkWidget * widget, GdkEventExpose * event, void* user_data)
{
    cam_renderer_t *cr = (cam_renderer_t*) user_data;

    gtku_gl_drawing_area_set_context (cr->gl_area);

    glClearColor (0.0, 0.0, 0.0, 1.0);
    glClear (GL_COLOR_BUFFER_BIT);
    
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();

    glOrtho (0, 1, 1, 0, -1, 1);
    glMatrixMode (GL_MODELVIEW);

    cam_renderer_draw (cr);

    gtku_gl_drawing_area_swap_buffers (cr->gl_area);
    return TRUE;
}
/* Called when the pipe has data on it, as written by the vblank-monitoring
 * thread. */
static gboolean
swap_func (GIOChannel * source, GIOCondition cond, gpointer data)
{
    GtkWidget * widget = GTK_WIDGET (data);
    GtkuGLDrawingArea * self = GTKU_GL_DRAWING_AREA (data);
    GtkuGLDrawingAreaPrivate * priv = GTKU_GL_DRAWING_AREA_GET_PRIVATE (self);

    if (priv->swap_requested) {
        if (gtku_gl_drawing_area_set_context (self) == 0)
            glXSwapBuffers (priv->dpy, GDK_WINDOW_XID (widget->window));
        priv->swap_requested = 0;
    }

    /* Clear out the pipe of vblank events */
    char buf[32];
    while (1) {
        int num = read (priv->pipe[0], buf, sizeof (buf));
        if (num <= 0)
            break;
    }

    return TRUE;
}
Exemple #7
0
static void 
start_recording (Viewer *self)
{
    if (self->is_recording) {
        err ("viewer: already recording!!\n");
        return;
    }

#ifndef USE_ZMOV
    assert (self->fb_area == NULL);
#endif
    assert (self->movie_buffer == NULL);

    int window_width = GTK_WIDGET (self->gl_area)->allocation.width;
    int window_height = GTK_WIDGET (self->gl_area)->allocation.height;

    self->movie_width = window_width - (window_width % 4);
    self->movie_height = window_height;
    self->movie_stride = self->movie_width * 3;
    self->movie_buffer = (uint8_t*) malloc (self->movie_stride * self->movie_height);
    self->movie_desired_fps = 1000.0 / gtk_spin_button_get_value (GTK_SPIN_BUTTON (self->fps_spin));
    self->movie_actual_fps = self->movie_desired_fps;
    self->movie_frame_last_utime = 0;

/*
    int wwidth, wheight;
    gtk_window_get_size(GTK_WINDOW(self->window), &wwidth, &wheight);
    printf("%5d, %5d\n", self->movie_width, self->movie_height);
    gtk_widget_set_size_request(GTK_WIDGET(self->gl_area), self->movie_width, self->movie_height);
    gtk_window_set_default_size(GTK_WINDOW(self->window), wwidth, wheight);
    gtk_widget_set_size_request(GTK_WIDGET(self->gl_area), self->movie_width, self->movie_height);
    gtk_window_set_resizable(GTK_WINDOW(self->window), FALSE);
*/

#ifdef USE_ZMOV

    self->movie_path = get_unique_filename(NULL, "viewer", 1, "ppms.gz");
    self->movie_gzf = gzopen(self->movie_path, "w");
    gzsetparams(self->movie_gzf, Z_BEST_SPEED, Z_DEFAULT_STRATEGY);

    if (self->movie_gzf == NULL)
        goto abort_recording;
    
    viewer_set_status_bar_message (self, "Recording to: %s", self->movie_path);

#else
    self->fb_area = fb_gl_drawing_area_new (FALSE, mov_width, mov_height, GL_BGR);
    if (!self->fb_area) {
        err ("Couldn't create FramebufferObject offscreen plugin\n");
        gtk_toggle_tool_button_set_active (
                GTK_TOGGLE_TOOL_BUTTON (self->record_button), FALSE);
        free (self->mov_bgr_buf);
        return;
    }

    assert(self->ezavi == NULL);

    ezavi_params_t avi_params = {
        .path = NULL,
        .file_prefix = "viewer",
        .date_in_file = 1,
        .codec = "raw",
        .width = mov_width,
        .height = mov_height,
        .src_stride = mov_width * 3,
        .frame_rate = 30,
        .split_point = 4000000000UL
    };

    self->ezavi = ezavi_new (&avi_params);
    if (!self->ezavi) { 
        err ("Couldn't create AVI file\n");
        goto abort_recording;
    }

    g_signal_connect (G_OBJECT(self->fb_area), "buffer-ready",
            G_CALLBACK (on_fb_ready), self->ezavi);

    viewer_set_status_bar_message (self, "Recording to: %s",
            ezavi_get_filename (self->ezavi));

#endif

    self->render_timer_id = g_timeout_add (1000 /
            gtk_spin_button_get_value (GTK_SPIN_BUTTON (self->fps_spin)),
            (GSourceFunc) on_render_timer, self);
    self->is_recording = 1;
    return;

abort_recording:
#ifndef USE_ZMOV
    g_object_unref (self->fb_area);
#endif
    gtk_toggle_tool_button_set_active (
            GTK_TOGGLE_TOOL_BUTTON (self->record_button),
            FALSE);
    free (self->mov_bgr_buf);
}

static void 
stop_recording (Viewer *self)
{
#ifndef USE_ZMOV
    if (!self->fb_area)
        return;
#endif

    free(self->movie_buffer);
    self->movie_buffer = NULL;

    dbg ("\nRecording stopped\n");
    viewer_set_status_bar_message (self, "Recording stopped");

#ifdef USE_ZMOV
    gzclose(self->movie_gzf);
    self->movie_gzf = NULL;
    free(self->movie_path);
    self->movie_draw_pending = 0;
#else
    fb_gl_drawing_area_flush (self->fb_area);
    ezavi_finish (self->ezavi);
    ezavi_destroy (self->ezavi);
    self->ezavi = NULL;
    g_object_unref (self->fb_area);
    self->fb_area = NULL;
#endif

    g_source_remove (self->render_timer_id);

    self->is_recording = 0;
    gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (self->record_button),
                                       FALSE);
//    gtk_window_set_resizable(GTK_WINDOW(self->window), TRUE);
}

static void update_status_bar(Viewer *viewer)
{
    char buf[1024];
    
    if (viewer->picking_handler && !viewer->picking_handler->picking)
        viewer->picking_handler = NULL;

    int vp[4] = {0,0,0,0};
    if (viewer->gl_area &&
            gtku_gl_drawing_area_set_context (viewer->gl_area) == 0) {
        glGetIntegerv(GL_VIEWPORT, vp);
    }
    int width = vp[2], height = vp[3];

    if (viewer->picking_handler)
        snprintf(buf, sizeof (buf), "%s%d x %d [%s]  %s", 
                (viewer->simulation_flag?"[SIM ENABLED] ":""), width, height, 
                 viewer->picking_handler->name,  viewer->status_bar_message);
    else
        snprintf(buf, sizeof (buf), "%s%d x %d [Idle] %s", 
                (viewer->simulation_flag?"[SIM ENABLED] ":""), width, height,
                 viewer->status_bar_message);

    gtk_statusbar_push(GTK_STATUSBAR(viewer->status_bar), 
                       gtk_statusbar_get_context_id(
                           GTK_STATUSBAR(viewer->status_bar),"info"), buf);
}
Exemple #8
0
static gboolean
on_gl_expose (GtkWidget *widget, GdkEventExpose *event, void *user_data)
{
    Viewer * self = (Viewer *) user_data;

    // if not enough time has elapsed since our last redraw, we
    // schedule a redraw in the future (if one isn't already pending).
    int64_t now = timestamp_now();
    double dt = (now - self->last_draw_utime) / 1000000.0;
    if (dt < (1.0/MAX_REDRAW_HZ)) {
        if (!self->redraw_timer_pending) {
            int delay_ms = (now - self->last_draw_utime)/1000 + 1;
            g_timeout_add(delay_ms, on_redraw_timer, self);
            self->redraw_timer_pending = 1;
        }
        return TRUE;
    }
    self->last_draw_utime = now;

    // If we're making a movie, don't draw any faster than the
    // requested movie FPS rate.
    if (self->movie_gzf && !self->movie_draw_pending)
        return TRUE;

    // set this to 1 in order to cause viewer to exit cleanly after a
    // few hundred frames: useful for generating gprof output.
    g_draws++;
    if (0) {
        int thresh = 300;

        // for profiling PROFILE
        if (g_draws%50 == 0)
            printf("draws: %5i / %i\n", g_draws, thresh);
        if (g_draws == thresh) {
            printf("Profiling is enabled: exiting now\n");
            exit(0);
        }
    }
    
    // we're going to actually draw.
    
    gtku_gl_drawing_area_set_context (self->gl_area);
    render_scene (self);
    gtku_gl_drawing_area_swap_buffers (self->gl_area);
    
    // write a movie frame?
    if (self->movie_draw_pending) {
        assert(self->movie_gzf);

        glReadPixels (0, 0, self->movie_width, self->movie_height, GL_RGB, GL_UNSIGNED_BYTE, self->movie_buffer); 
        
        gzprintf(self->movie_gzf, "P6 %d %d %d\n", self->movie_width, self->movie_height, 255);
        
        for (int h = self->movie_height - 1; h >= 0; h--) {
            int offset = self->movie_stride * h;
            gzwrite(self->movie_gzf, &self->movie_buffer[offset], self->movie_stride);
        }

        self->movie_draw_pending = 0;
        int64_t now = timestamp_now();
        double dt;
        if (self->movie_frame_last_utime == 0)
            dt = 1.0 / self->movie_desired_fps;
        else
            dt = (now - self->movie_frame_last_utime)/1000000.0;
        double fps = 1.0 / dt;
        self->movie_frame_last_utime = now;
        double alpha = 0.8; // higher = lower-pass
        self->movie_actual_fps = alpha * self->movie_actual_fps + (1 - alpha) * fps;
        self->movie_frames++;

        printf("%20s %6d (%5.2f fps)\r", self->movie_path, self->movie_frames, self->movie_actual_fps);
        fflush(NULL);
    }

    return TRUE;
}