codice:
/*
* button.c:
* Simple toggle button example.
*
* written by Naofumi Yasufuku <naofumi@users.sourceforge.net>
*/
#include <stdlib.h>
#include <math.h>
#include <gtk.h>
#include <gtkgl.h>
#ifdef G_OS_WIN32
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
#endif
#include <GL/gl.h>
#include <GL/glu.h>
#define TIMEOUT_INTERVAL 10
static gboolean animate = TRUE;
static GLfloat angle = 0.0;
static GLfloat pos_y = 0.0;
static void
realize (GtkWidget *widget,
gpointer data)
{
GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);
static GLfloat ambient[] = { 0.0, 0.0, 0.0, 1.0 };
static GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
static GLfloat position[] = { 1.0, 1.0, 1.0, 0.0 };
static GLfloat lmodel_ambient[] = {0.2, 0.2, 0.2, 1.0};
static GLfloat local_view[] = {0.0};
/*** OpenGL BEGIN ***/
if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
return;
glLightfv (GL_LIGHT0, GL_AMBIENT, ambient);
glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuse);
glLightfv (GL_LIGHT0, GL_POSITION, position);
glLightModelfv (GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
glLightModelfv (GL_LIGHT_MODEL_LOCAL_VIEWER, local_view);
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0);
glEnable (GL_DEPTH_TEST);
glClearColor (1.0, 1.0, 1.0, 1.0);
glClearDepth (1.0);
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);
GLfloat w = widget->allocation.width;
GLfloat h = widget->allocation.height;
GLfloat aspect;
/*** OpenGL BEGIN ***/
if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
return FALSE;
glViewport (0, 0, w, h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
if (w > h)
{
aspect = w / h;
glFrustum (-aspect, aspect, -1.0, 1.0, 5.0, 60.0);
}
else
{
aspect = h / w;
glFrustum (-1.0, 1.0, -aspect, aspect, 5.0, 60.0);
}
glMatrixMode (GL_MODELVIEW);
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);
/* brass */
static GLfloat ambient[4] = { 0.329412, 0.223529, 0.027451, 1.0 };
static GLfloat diffuse[4] = { 0.780392, 0.568627, 0.113725, 1.0 };
static GLfloat specular[4] = { 0.992157, 0.941176, 0.807843, 1.0 };
static GLfloat shininess = 0.21794872 * 128.0;
/*** OpenGL BEGIN ***/
if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
return FALSE;
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity ();
glTranslatef (0.0, 0.0, -10.0);
glPushMatrix ();
glTranslatef (0.0, pos_y, 0.0);
glRotatef (angle, 0.0, 1.0, 0.0);
glMaterialfv (GL_FRONT, GL_AMBIENT, ambient);
glMaterialfv (GL_FRONT, GL_DIFFUSE, diffuse);
glMaterialfv (GL_FRONT, GL_SPECULAR, specular);
glMaterialf (GL_FRONT, GL_SHININESS, shininess);
gdk_gl_draw_torus (TRUE, 0.3, 0.6, 30, 30);
glPopMatrix ();
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;
}
static gboolean
timeout (GtkWidget *widget)
{
GLfloat t;
angle += 3.0;
if (angle >= 360.0)
angle -= 360.0;
t = angle * G_PI / 180.0;
if (t > G_PI)
t = 2.0 * G_PI - t;
pos_y = 2.0 * (sin (t) + 0.4 * sin (3.0*t)) - 1.0;
/* Invalidate the whole window. */
gdk_window_invalidate_rect (widget->window, &widget->allocation, FALSE);
/* Update synchronously (fast). */
gdk_window_process_updates (widget->window, FALSE);
return TRUE;
}
static guint timeout_id = 0;
static void
timeout_add (GtkWidget *widget)
{
if (timeout_id == 0)
{
timeout_id = gtk_timeout_add (TIMEOUT_INTERVAL,
(GtkFunction) timeout,
widget);
}
}
static void
timeout_remove (GtkWidget *widget)
{
if (timeout_id != 0)
{
gtk_timeout_remove (timeout_id);
timeout_id = 0;
}
}
static void
unrealize (GtkWidget *widget,
gpointer data)
{
timeout_remove (widget);
}
static gboolean
map_event (GtkWidget *widget,
GdkEvent *event,
gpointer data)
{
if (animate)
timeout_add (widget);
return TRUE;
}
static gboolean
unmap_event (GtkWidget *widget,
GdkEvent *event,
gpointer data)
{
timeout_remove (widget);
return TRUE;
}
static gboolean
visibility_notify_event (GtkWidget *widget,
GdkEventVisibility *event,
gpointer data)
{
if (animate)
{
if (event->state == GDK_VISIBILITY_FULLY_OBSCURED)
timeout_remove (widget);
else
timeout_add (widget);
}
return TRUE;
}
static void
toggle_animation (GtkWidget *widget)
{
animate = !animate;
if (animate)
{
timeout_add (widget);
}
else
{
timeout_remove (widget);
gdk_window_invalidate_rect (widget->window, &widget->allocation, FALSE);
}
}
static GtkWidget *
create_gl_toggle_button (GdkGLConfig *glconfig)
{
GtkWidget *vbox;
GtkWidget *drawing_area;
GtkWidget *label;
GtkWidget *button;
/*
* VBox.
*/
vbox = gtk_vbox_new (FALSE, 0);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
/*
* Drawing area for drawing OpenGL scene.
*/
drawing_area = gtk_drawing_area_new ();
gtk_widget_set_size_request (drawing_area, 200, 200);
/* Set OpenGL-capability to the widget. */
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), NULL);
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 (drawing_area), "unrealize",
G_CALLBACK (unrealize), NULL);
g_signal_connect (G_OBJECT (drawing_area), "map_event",
G_CALLBACK (map_event), NULL);
g_signal_connect (G_OBJECT (drawing_area), "unmap_event",
G_CALLBACK (unmap_event), NULL);
g_signal_connect (G_OBJECT (drawing_area), "visibility_notify_event",
G_CALLBACK (visibility_notify_event), NULL);
gtk_box_pack_start (GTK_BOX (vbox), drawing_area, TRUE, TRUE, 0);
gtk_widget_show (drawing_area);
/*
* Label.
*/
label = gtk_label_new ("Toggle Animation");
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 10);
gtk_widget_show (label);
/*
* Toggle button.
*/
button = gtk_toggle_button_new ();
g_signal_connect_swapped (G_OBJECT (button), "toggled",
G_CALLBACK (toggle_animation), drawing_area);
/* Add VBox. */
gtk_widget_show (vbox);
gtk_container_add (GTK_CONTAINER (button), vbox);
return button;
}
int
main (int argc,
char *argv[])
{
GdkGLConfig *glconfig;
GtkWidget *window;
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), "button");
/* 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);
/*
* Toggle button which contains an OpenGL scene.
*/
button = create_gl_toggle_button (glconfig);
gtk_widget_show (button);
gtk_container_add (GTK_CONTAINER (window), button);
/*
* Show window.
*/
gtk_widget_show (window);
/*
* Main loop.
*/
gtk_main ();
return 0;
}
ma ritorna questo errore: