drawing_area 캡쳐 ? (pixmap과 pixbuf 사용)

sshim07의 이미지

안녕하세요!
우울증에 걸릴 지경까지 도달하고 있는 중입니다.
며칠을 헤맸더니 이제는 어떻게 해야 할 지 갈피조차

못 잡고 있는 것 같습니다. 많은 조언 부탁 드리겠습니다.

gtk에 opengl 까지 확장된 gtkglext로 프로그램 중입니다.
drawing_area에 Plot된 것을 Pixmap과 Pixbuf를 이용하여
jpg 파일로 저장하려고 하는데, drawing_area에 있는 내용을 Pixmap에
전달할때 정상적으로 동작하지 않습니다.

읽어오는 싯점이 잘못 되었는지 아님, On-screen(?}, Off-screen(?)
문제점인지...

아래 코드는 제가 허접하게 작성한 것입니다...

#include
#include
#include
#include
#include
#include
#include

GtkWidget *window;
GtkWidget *drawing_area;

GdkGLDrawable *gldrawable;
static GdkGLConfig *glconfig = NULL;
static GdkGLContext *glcontext = NULL;
static GdkPixmap *pixmap = NULL;

static gboolean configure_event (GtkWidget *widget, GdkEventConfigure *event, gpointer data)
{
/* Create an OpenGL off-screen rendering area. */
if (pixmap != NULL) g_object_unref (G_OBJECT (pixmap));

pixmap = gdk_pixmap_new (widget->window, widget->allocation.width, widget->allocation.height, -1);

return TRUE;
}

static gboolean expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer data)
{

static gboolean is_initialized = FALSE;
static char label[100], label2[100], label3[100], ref_label2[20], scale_div_label2[20], ref_label1[20], scale_div_label1[20], RBW_label1[20], RBW_label2[20], VBW_label1[20], VBW_label2[20];
int for_cnt, temp_cnt, button_y, menu_num;

/* Set OpenGL-capability to the pixmap*/
gldrawable = GDK_GL_DRAWABLE (gdk_pixmap_set_gl_capability (pixmap, glconfig, NULL));

glcontext = gtk_widget_get_gl_context (widget);
gldrawable = gtk_widget_get_gl_drawable (widget);

if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) return FALSE;

if (!is_initialized)
{
init ();
is_initialized = TRUE;
}

grid_start_y = (measure_mode == MEAS_OFF) ? grid_start_y_measoff : grid_start_y_etc;

// Clean drawing board
glClear (GL_COLOR_BUFFER_BIT);

// display list call
glCallList(1);

glCallList(6);

test_graph();

// 화면 아래 보이기
bottom_info_display();

// Pixmap에서 Pixbuf로 데이타 이동 ////////////////////////
GdkPixbuf *pixbuf;
GError *error = NULL;

pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, NULL, 0, 0, 0, 0, 676, 542);

gdk_pixbuf_save(pixbuf, "s1.jpg", "jpeg", &error, "quality", "100", NULL);

//////////////////////////////////////////////////////////////////////

if (gdk_gl_drawable_is_double_buffered (gldrawable)) gdk_gl_drawable_swap_buffers (gldrawable);
else glFlush ();

gdk_gl_drawable_gl_end (gldrawable);

return TRUE;
}

int main (int argc, char *argv[])
{
//GdkGLConfig *glconfig;
int for_cnt;
gchar path[256];
gchar *home;
gchar label[100];

/* Init GTK.*/
gtk_init (&argc, &argv);

/* Init GtkGLExt.*/
gtk_gl_init (&argc, &argv);

gtk_widget_push_visual(gdk_rgb_get_visual());
gtk_widget_push_colormap(gdk_rgb_get_cmap());
gtk_widget_pop_visual();
gtk_widget_pop_colormap();

home = getenv("HOME");
/* if (home && strlen(home) < 128) {
sprintf(path, "%s/.aprc", home);
gtk_rc_parse(path);
} else {*/
sprintf(path, "%s/.gtkrc", home);
gtk_rc_parse(path);
// }
g_printf("%s\n", path);

/* Try double-buffered visual */
glconfig = gdk_gl_config_new_by_mode (GDK_GL_MODE_RGB |
GDK_GL_MODE_DEPTH |
GDK_GL_MODE_DOUBLE);


if (glconfig == NULL) {
g_print ("*** Cannot find the double-buffered visual.\n");
g_print ("*** Trying single-buffered visual.\n");

/* Try single-buffered visual */
glconfig = gdk_gl_config_new_by_mode (GDK_GL_MODE_RGB);// |
//GDK_GL_MODE_DEPTH);
if (glconfig == NULL){
g_print ("*** No appropriate OpenGL-capable visual found.\n");
exit (1);
}
}

/* * Top-level window.*/
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_set_size_request (window, 800, 600);
gtk_window_set_title (GTK_WINDOW (window), "test");

/* Get automatically redrawn if any of their children changed allocation. */
gtk_container_set_reallocate_redraws (GTK_CONTAINER (window), TRUE);
/* Set border width. */
gtk_container_set_border_width (GTK_CONTAINER (window), 0);

g_signal_connect (G_OBJECT (window), "delete_event",
G_CALLBACK (gtk_main_quit), NULL);


/* * drawing_area, fixed*/
drawing_area = gtk_drawing_area_new ();
gtk_widget_set_size_request (drawing_area, 676, 542);
// gtk_widget_set_colormap (drawing_area, gdk_gl_config_get_colormap (glconfig));


/* Set OpenGL-capability to the widget. */
gtk_widget_set_gl_capability (drawing_area, glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE);

butt1 = gtk_button_new();
butt2 = gtk_button_new();

g_signal_connect (G_OBJECT (drawing_area), "configure_event",
G_CALLBACK (configure_event), NULL);
g_signal_connect (G_OBJECT (drawing_area), "expose_event",
G_CALLBACK (expose_event), NULL);

g_signal_connect (G_OBJECT (window), "key_press_event",
G_CALLBACK (key_press_event), NULL);

g_signal_connect_swapped(G_OBJECT(butt1), "clicked",
G_CALLBACK(button_click_act),1);
g_signal_connect_swapped(G_OBJECT(butt2), "clicked",
G_CALLBACK(button_click_act),2);

gtk_idle_add((G_CALLBACK(idle)),0);

fixed = gtk_fixed_new();
gtk_container_add(GTK_CONTAINER(window), fixed);
gtk_widget_show(fixed);

gtk_fixed_put(GTK_FIXED(fixed), drawing_area, 0, 40 );
gtk_widget_show(drawing_area);

//상단 오른쪽 버튼
gtk_widget_set_usize(butt1, 115, 66);
gtk_widget_set_usize(butt2, 115, 66);
gtk_widget_show(butt1);
gtk_widget_show(butt2);

//윈도우 위치 지정
gtk_widget_set_uposition(window, 0, 0);
gtk_widget_show(window);

/* Main loop.*/
gtk_main ();

return 0;
}