/* * share-lists.c: * Simple display list sharing example. * * written by Naofumi Yasufuku */ #include #include #include #ifdef G_OS_WIN32 #define WIN32_LEAN_AND_MEAN 1 #include #endif #include #include static GLfloat red[] = {1.0, 0.0, 0.0, 1.0}; static GLfloat yellow[] = {1.0, 1.0, 0.0, 1.0}; static GLfloat green[] = {0.0, 1.0, 0.0, 1.0}; static void init_gl (GLfloat *light_diffuse) { static GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0}; glLightfv (GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv (GL_LIGHT0, GL_POSITION, light_position); glEnable (GL_LIGHTING); glEnable (GL_LIGHT0); glEnable (GL_DEPTH_TEST); glClearColor (1.0, 1.0, 1.0, 1.0); glClearDepth (1.0); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective (40.0, 1.0, 1.0, 10.0); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); gluLookAt (0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); glTranslatef (0.0, 0.0, -3.0); } static void realize_main (GtkWidget *widget, GLfloat *light_diffuse) { GdkGLContext *glcontext = gtk_widget_get_gl_context (widget); GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget); GLUquadricObj *qobj; /*** OpenGL BEGIN ***/ if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) return; /* Create display list #1 */ qobj = gluNewQuadric (); gluQuadricDrawStyle (qobj, GLU_FILL); glNewList (1, GL_COMPILE); gluSphere (qobj, 1.0, 20, 20); glEndList (); /* Initialize rendering context */ init_gl (light_diffuse); gdk_gl_drawable_gl_end (gldrawable); /*** OpenGL END ***/ } static void realize_sub (GtkWidget *widget, GLfloat *light_diffuse) { GdkGLContext *glcontext = gtk_widget_get_gl_context (widget); GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget); /*** OpenGL BEGIN ***/ if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) return; /* Initialize rendering context */ init_gl (light_diffuse); gdk_gl_drawable_gl_end (gldrawable); /*** OpenGL END ***/ } static gboolean configure_event (GtkWidget *widget, GdkEventConfigure *event, gpointer data) { GdkGLContext *glcontext = gtk_widget_get_gl_context (widget); GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget); /*** OpenGL BEGIN ***/ if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) return FALSE; glViewport (0, 0, widget->allocation.width, widget->allocation.height); gdk_gl_drawable_gl_end (gldrawable); /*** OpenGL END ***/ return TRUE; } static gboolean expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer data) { GdkGLContext *glcontext = gtk_widget_get_gl_context (widget); GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget); /*** OpenGL BEGIN ***/ if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) return FALSE; glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glCallList (1); if (gdk_gl_drawable_is_double_buffered (gldrawable)) gdk_gl_drawable_swap_buffers (gldrawable); else glFlush (); gdk_gl_drawable_gl_end (gldrawable); /*** OpenGL END ***/ return TRUE; } int main (int argc, char *argv[]) { GdkGLConfig *glconfig; GdkGLContext *glcontext; GtkWidget *window; GtkWidget *vbox; GtkWidget *drawing_area; GtkWidget *button; /* * Init GTK. */ gtk_init (&argc, &argv); /* * Init GtkGLExt. */ gtk_gl_init (&argc, &argv); /* * Configure OpenGL-capable visual. */ /* 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_window_set_title (GTK_WINDOW (window), "share-lists"); /* 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), 10); g_signal_connect (G_OBJECT (window), "delete_event", G_CALLBACK (gtk_main_quit), NULL); /* * VBox. */ vbox = gtk_vbox_new (FALSE, 10); gtk_container_add (GTK_CONTAINER (window), vbox); gtk_widget_show (vbox); /* * OpenGL drawing area #1 (main: creates display lists). */ drawing_area = gtk_drawing_area_new (); gtk_widget_set_size_request (drawing_area, 120, 120); gtk_widget_set_gl_capability (drawing_area, glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE); g_signal_connect_after (G_OBJECT (drawing_area), "realize", G_CALLBACK (realize_main), red); 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); gtk_box_pack_start (GTK_BOX (vbox), drawing_area, TRUE, TRUE, 0); gtk_widget_show (drawing_area); /* * Get OpenGL rendering context. */ gtk_widget_realize (drawing_area); glcontext = gtk_widget_get_gl_context (drawing_area); /* * OpenGL drawing area #2 (sub: shares display lists). */ drawing_area = gtk_drawing_area_new (); gtk_widget_set_size_request (drawing_area, 120, 120); gtk_widget_set_gl_capability (drawing_area, glconfig, glcontext, /* share_list */ TRUE, GDK_GL_RGBA_TYPE); g_signal_connect_after (G_OBJECT (drawing_area), "realize", G_CALLBACK (realize_sub), yellow); 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); gtk_box_pack_start (GTK_BOX (vbox), drawing_area, TRUE, TRUE, 0); gtk_widget_show (drawing_area); /* * OpenGL drawing area #3 (sub: shares display lists). */ drawing_area = gtk_drawing_area_new (); gtk_widget_set_size_request (drawing_area, 120, 120); gtk_widget_set_gl_capability (drawing_area, glconfig, glcontext, /* share_list */ TRUE, GDK_GL_RGBA_TYPE); g_signal_connect_after (G_OBJECT (drawing_area), "realize", G_CALLBACK (realize_sub), green); 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); gtk_box_pack_start (GTK_BOX (vbox), drawing_area, TRUE, TRUE, 0); gtk_widget_show (drawing_area); /* * Simple quit button. */ button = gtk_button_new_with_label ("Quit"); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (gtk_main_quit), NULL); gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); gtk_widget_show (button); /* * Show window. */ gtk_widget_show (window); /* * Main loop. */ gtk_main (); return 0; }