Gtk_gl_init (&ARGC, &ARGV);
Initialize Gtkglext
Surface = cairo_image_surface_create_from_png (image);
context = cairo_create (surface);
Create a Cairo Surface,context
G_signal_connect (G_object (Drawing_area), "Expose-event", G_callback (Expose), NULL);
Registering a drawing event function
Gl_context = Gtk_widget_get_gl_context (widget);
gl_drawable = gtk_widget_get_gl_drawable (widget);
Get gl_context,gl_drawable
Gdk_gl_drawable_gl_begin (gl_drawable, Gl_context); Glbindtexture (gl_texture_rectangle_arb, texture);
Glteximage2d (Gl_texture_rectangle_arb, 0, Gl_rgba, width, height, 0, Gl_bgra, Gl_unsigned_byte, surface_data[0]);
Gdk_gl_drawable_gl_end (gl_drawable);
Making control drawing operations
/* un deslizador de planos OpenGL texturados con Cairo * * Juan Manuel mouriz <jmouriz@gmail.com> * * #include ;gtk/gtk.h> #include <gtk/gtkgl.h> #include <GL/gl.h> #include <math.h> #define IMAGE "COVERS/1.
PNG "#define SPEED 1000/60 typedef enum {back =-1, FORWARD = 1, left =-1, right = 1} direction_t;
Static Gtkwidget *drawing_area;
static gfloat angle;
static gfloat offset;
static Gluint texture;
static direction_t direction;
Gint width;
Gint height;
Guchar *surface_data[1]; /* Función de apoyo que reemplaza gluperspective con glfrustum/void Perspective (gldouble Fovy, gldouble aspect, GLdoub
Le near, gldouble far) {gldouble top;
Gldouble Bottom;
Gldouble left;
Gldouble right;
top = near * TAN (m_pi/180.0f * fovy/2.0f);
bottom =-top;
right = aspect * TOP;
left =-right;
Glfrustum (left, right, bottom, top, near, far);
}/* Transformación para la animación de rotación/void transform_rotation (void) { Glrotatef (angle * direction, 0, 1, 0); }/* Transformación para la animación de desplazamiento/void transform_translation (void) {GLTRANSLATEF (offset * d
Irection, 0.0f, 0.0f); }/* Actualización delárea de dibujo/void update (void) {Gdk_window_invalidate_rect (Drawing_area->window,
;d rawing_area->allocation, FALSE);
Gdk_window_process_updates (Drawing_area->window, FALSE);
}/* Función de rotación * * Gboolean rotate (gpointer data) {Gboolean stop;
stop = FALSE;
Angle + 10.0f;
Stop ^= angle > 45.0f;
Update ();
return!stop;
}/* Función de desplazamiento * * Gboolean translate (gpointer data) {Gboolean stop;
stop = FALSE;
offset = 0.05f;
Stop ^= offset > 0.5f;
Update ();
return!stop;
}/* Comienzo de la rotación */void Start_rotation (void) {angle = 0.0f;
G_timeout_add (SPEED, rotate, NULL);
}/* Comienzo del Desplazamiento */void Start_translation (void) {offset = 0.0f; G_timeout_add (SPEED, TranSlate, NULL); }/* Manejadores de señales para los botones de control/void Go_left (Gtkwidget *widget, gpointer data) {direction
= left;
Start_rotation ();
} void Go_right (Gtkwidget *widget, gpointer data) {direction = right;
Start_rotation ();
} void Go_back (Gtkwidget *widget, gpointer data) {direction = back;
Start_translation ();
} void Go_forward (Gtkwidget *widget, gpointer data) {direction = forward;
Start_translation ();
} void Go_center (Gtkwidget *widget, gpointer data) {angle = 0.0f;
offset = 0.0f;
Update ();
}/* Dibujar un plano/void Draw_cover (float offset, float angle, float near, Gboolean animate) {Glpushmatrix ();
Gltranslatef (offset, 0.0f, near);
Glrotatef (angle, 0, 1, 0);
if (animate) transform_rotation ();
Glbegin (gl_quads);
Gltexcoord2i (width, height);
GLVERTEX2F (0.5f, -0.5f);
Gltexcoord2i (width, -0.5f);
GLVERTEX2F (0.5f, 0.5f);
Gltexcoord2i ( -0.5f, -0.5f); GlverTEX2F ( -0.5f, 0.5f);
Gltexcoord2i ( -0.5f, height);
GLVERTEX2F ( -0.5f, -0.5f);
Glend ();
Glpopmatrix ();
}/* Dibujar una pila de planos/void Draw_covers_stack (void) {float x;
int i;
Glpushmatrix ();
Transform_translation ();
for (x = 1.0f; x > 0.2f; x = 0.1f) draw_cover (x, -45.0f, 0.0f, FALSE);
for (x = -1.0f x < -0.2f x + 0.1f) draw_cover (x, 45.0f, 0.0f, FALSE);
Draw_cover (0.0f, 0.0f, 0.25f, TRUE);
Glpopmatrix (); } void Draw (void) {Glclear Gl_color_buffer_bit |
Gl_depth_buffer_bit);
Glpushmatrix ();
Gltranslatef (0.0f, -0.45f, 0.0f);
Glpushmatrix ();
/* Dibujar la reflección * * GLSCALEF (1.0,-1.0, 1.0);
Gltranslatef (0.0f, 1.05f, 0.0f);
Glenable (gl_normalize);
Glcullface (Gl_front);
Glenable (Gl_blend);
Glblendfunc (Gl_src_alpha, Gl_one_minus_src_alpha);
GLCOLOR4F (1.0, 1.0, 1.0, 0.40);
Draw_covers_stack ();
Gldisable (Gl_blend);
Gldisable (gl_normalize);
Glcullface (Gl_back); GlpopmatriX ();
/* Dibujar * * Draw_covers_stack ();
Glpopmatrix ();
}/* Barra de control de desplazamiento/gtkwidget * Build_translation_control (void) {Gtkwidget *box;
Gtkwidget *button;
Gtkwidget *label;
box = gtk_hbox_new (TRUE, 0);
if (!box) g_assert_not_reached ();
Label = Gtk_label_new ("<b>Desplazamiento</b>");
if (!label) g_assert_not_reached ();
Gtk_misc_set_alignment (Gtk_misc (label), 0.0, 0.5);
Gtk_label_set_use_markup (Gtk_label (label), TRUE);
Gtk_container_add (Gtk_container (box), label);
Gtk_widget_show (label);
button = Gtk_button_new_with_label ("Izquierda");
if (!button) g_assert_not_reached ();
G_signal_connect (g_object button), "clicked", G_callback (Go_back), NULL);
Gtk_container_add (box), button (Gtk_container);
Gtk_widget_show (button);
button = Gtk_button_new_with_label ("Centro");
if (!button) g_assert_not_reached (); G_signal_connect (g_object button), "clicked", G_callback (go_center), NULL);
Gtk_container_add (box), button (Gtk_container);
Gtk_widget_show (button);
button = Gtk_button_new_with_label ("Derecha");
if (!button) g_assert_not_reached ();
G_signal_connect (g_object button), "clicked", G_callback (Go_forward), NULL);
Gtk_container_add (box), button (Gtk_container);
Gtk_widget_show (button);
return box;
}/* Barra de control de rotación/gtkwidget * Build_rotation_control (void) {Gtkwidget *box;
Gtkwidget *button;
Gtkwidget *label;
box = gtk_hbox_new (TRUE, 0);
if (!box) g_assert_not_reached ();
Label = Gtk_label_new ("<b>Rotación</b>");
if (!label) g_assert_not_reached ();
Gtk_misc_set_alignment (Gtk_misc (label), 0.0, 0.5);
Gtk_label_set_use_markup (Gtk_label (label), TRUE);
Gtk_container_add (Gtk_container (box), label);
Gtk_widget_show (label);
button = Gtk_button_new_with_label ("Izquierda");
if (!button) g_assert_not_reached (); G_signal_connect (g_objECT (Button), "clicked", G_callback (Go_left), NULL);
Gtk_container_add (box), button (Gtk_container);
Gtk_widget_show (button);
button = Gtk_button_new_with_label ("Centro");
if (!button) g_assert_not_reached ();
G_signal_connect (g_object button), "clicked", G_callback (Go_center), NULL);
Gtk_container_add (box), button (Gtk_container);
Gtk_widget_show (button);
button = Gtk_button_new_with_label ("Derecha");
if (!button) g_assert_not_reached ();
G_signal_connect (g_object button), "clicked", G_callback (Go_right), NULL);
Gtk_container_add (box), button (Gtk_container);
Gtk_widget_show (button);
return box;
}/* Barra de control/gtkwidget * Build_control (void) {Gtkwidget *box;
Gtkwidget *control;
box = gtk_vbox_new (FALSE, 0);
if (!box) g_assert_not_reached ();
Control = Build_rotation_control ();
if (!control) g_assert_not_reached ();
Gtk_container_add (Gtk_container (box), control); Gtk_widget_show (CONtrol);
Control = Build_translation_control ();
if (!control) g_assert_not_reached ();
Gtk_container_add (Gtk_container (box), control);
Gtk_widget_show (Control);
return box; }/* Manejadores de señales */gboolean Delete (Gtkwidget *widget, gdkevent *event, gpointer data) {Gldeletetextures
(1, &texture);
Gtk_main_quit ();
return TRUE;
} void realize (Gtkwidget *widget, gpointer data) {//glfloat light[4];
Gdkglcontext *gl_context;
Gdkgldrawable *gl_drawable;
Gboolean Can_begin;
Gl_context = Gtk_widget_get_gl_context (widget);
gl_drawable = gtk_widget_get_gl_drawable (widget);
Can_begin = Gdk_gl_drawable_gl_begin (gl_drawable, Gl_context);
Light[0] = 1.0f;
LIGHT[1] = 1.0f;
LIGHT[2] = 1.0f;
LIGHT[3] = 1.0f;
if (!can_begin) g_assert_not_reached ();
Glenable (Gl_texture_rectangle_arb);
Glenable (gl_lighting);
Glenable (GL_LIGHT0);
Glenable (GL_LIGHT1);
GLLIGHTFV (Gl_light0, gl_diffuse, light); GltexeNVi (gl_texture_env, Gl_texture_env_mode, gl_modulate);
Gltexparameteri (Gl_texture_rectangle_arb, Gl_texture_min_filter, gl_linear_mipmap_linear);
Gltexparameteri (Gl_texture_rectangle_arb, Gl_texture_mag_filter, gl_linear);
Gdk_gl_drawable_gl_end (gl_drawable);
} Gboolean Configure (Gtkwidget *widget, gdkeventconfigure *event, gpointer data) {Gdkglcontext *gl_context;
Gdkgldrawable *gl_drawable;
Glsizei width;
Glsizei height;
Gboolean Can_begin;
Gl_context = Gtk_widget_get_gl_context (widget);
gl_drawable = gtk_widget_get_gl_drawable (widget);
width = widget->allocation.width;
Height = widget->allocation.height;
Can_begin = Gdk_gl_drawable_gl_begin (gl_drawable, Gl_context);
if (!can_begin) g_assert_not_reached ();
Glviewport (0, 0, width, height);
Glmatrixmode (gl_projection);
Glloadidentity ();
Perspective (60.0f, (glfloat) Width/(glfloat) height, 1.0f, 5.0f);
Glmatrixmode (Gl_modelview);
Glloadidentity (); Gltranslatef (00f, 0.25f, -2.0f);
Glgentextures (1, &texture);
/* Glbindtexture (Gl_texture_rectangle_arb, texture);
Glteximage2d (Gl_texture_rectangle_arb, 0, Gl_rgba, width, height, 0, Gl_bgra, Gl_unsigned_byte, surface_data[0]);
* * Gdk_gl_drawable_gl_end (gl_drawable);
return TRUE;
} Gboolean Expose (Gtkwidget *widget, Gdkeventexpose *event, gpointer data) {Gdkglcontext *gl_context;
Gdkgldrawable *gl_drawable;
Gboolean Can_begin;
Gboolean is_double_buffered;
Gl_context = Gtk_widget_get_gl_context (widget);
gl_drawable = gtk_widget_get_gl_drawable (widget);
is_double_buffered = gdk_gl_drawable_is_double_buffered (gl_drawable);
Can_begin = Gdk_gl_drawable_gl_begin (gl_drawable, Gl_context);
if (!can_begin) g_assert_not_reached ();
Glbindtexture (gl_texture_rectangle_arb, texture);
Glteximage2d (Gl_texture_rectangle_arb, 0, Gl_rgba, width, height, 0, Gl_bgra, Gl_unsigned_byte, surface_data[0]);
Draw (); if (is_double_buffered) Gdk_gl_drawaBle_swap_buffers (gl_drawable);
else Glflush ();
Gdk_gl_drawable_gl_end (gl_drawable);
return TRUE;
}/* Inicio/int main (int argc, char *argv[]) {Gtkwidget *window;
Gtkwidget *box;
Gtkwidget *label;
Gtkwidget *control;
Gdkglconfig *gl_config;
cairo_surface_t *surface;
cairo_t *context;
Gboolean gl_capability;
Gtk_init (&ARGC, &ARGV);
Gtk_gl_init (&ARGC, &ARGV); Gl_config = Gdk_gl_config_new_by_mode (Gdk_gl_mode_rgb | Gdk_gl_mode_alpha | gdk_gl_mode_depth |
gdk_gl_mode_double);
if (!gl_config) g_assert_not_reached ();
window = Gtk_window_new (gtk_window_toplevel);
if (!window) g_assert_not_reached ();
Gtk_window_set_title (Gtk_window (window), "Desplazamiento de Planos animado"); Gtk_widget_add_events (window, Gdk_pointer_motion_mask | Gdk_button_press_mask |
Gdk_button_release_mask);
G_signal_connect (G_object (window), "Delete-event", G_callback (delete), NULL);
box = gtk_vbox_new (FALSE, 0); If(!box) g_assert_not_reached ();
Gtk_container_add (Gtk_container (window), box);
Gtk_widget_show (box);
Label = Gtk_label_new ("<span size= ' 18000 ' weight= ' heavy ' >desplazamiento de planos animado</span>");
if (!label) g_assert_not_reached ();
Gtk_label_set_use_markup (Gtk_label (label), TRUE);
Gtk_box_pack_start (Gtk_box (box), label, False, False, 0);
Gtk_widget_show (label);
Drawing_area = Gtk_drawing_area_new ();
if (!drawing_area) g_assert_not_reached ();
Gtk_container_add (Gtk_container (box), Drawing_area);
Gtk_widget_show (Drawing_area);
Control = Build_control ();
if (!control) g_assert_not_reached ();
Gtk_box_pack_start (Gtk_box (box), control, False, False, 0);
Gtk_widget_show (Control); /* Cargar la imagen en un contexto Cairo y obtener los bytes para usar como textura de los planos * * surface = Cairo_ima
Ge_surface_create_from_png (IMAGE);
if (!surface) g_assert_not_reached (); width = Cairo_imAge_surface_get_width (surface);
Height = cairo_image_surface_get_height (surface);
Gtk_widget_set_size_request (Drawing_area, width, height);
gl_capability = Gtk_widget_set_gl_capability (Drawing_area, Gl_config, NULL, TRUE, Gdk_gl_rgba_type);
if (!gl_capability) g_assert_not_reached ();
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), NULL);
G_signal_connect (G_object (Drawing_area), "Expose-event", G_callback (Expose), NULL);
gtk_widget_set_app_paintable (window, TRUE);
Gtk_widget_realize (window);
Gdk_window_set_back_pixmap (Window->window, NULL, FALSE);
Gtk_widget_show (window);
Surface_data[0] = g_malloc0 (4 * width * height);
if (!surface_data[0]) g_assert_not_reached ();
context = cairo_create (surface);
if (!context) g_assert_not_reached (); Surface_data[0] = Cairo_image_surface_get_data (surface);
if (!context) g_assert_not_reached ();
Gtk_main ();
if (Surface_data[0]) G_free (surface_data[0]);
return 0;
}