1 /*******************************************************************************
2 **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
3 ** 10 20 30 40 50 60 70 80
9 ** Mirco "MacSlow" Mueller <macslow@bangang.de>
11 ** copyright (C) Mirco Mueller, 2006/2007
14 ** Simple example demonstrating how one could use cairo for generating
15 ** dynamic texture-mapping with OpenGL. Intended to be run on a composited
16 ** desktop (e.g. compiz, xcompmgr) with proper a OpenGL-implementation. I put
17 ** this program under the terms of the "GNU General Public License". If you
18 ** don't know what that means take a look a here...
20 ** http://www.gnu.org/licenses/licenses.html#GPL
22 *******************************************************************************/
25 #include <gtk/gtkgl.h>
30 #include "cairo-rendering.h"
32 GTimer
* g_pTimerId
= NULL
;
35 cairo_t
* g_pCairoContext
[3];
36 guchar
* g_pucSurfaceData
[3];
37 gulong g_ulMilliSeconds
= 0L;
45 GtkWidget
* pWindow
= NULL
;
46 GdkGLConfig
* pGlConfig
= NULL
;
47 GtkWidget
* pDrawingArea
= NULL
;
48 guint uiDrawHandlerId
= 0;
49 cairo_surface_t
* pCairoSurface
[2];
51 g_lineOne
.start
.fX
= 0.1f
;
52 g_lineOne
.start
.fY
= 0.2f
;
53 g_lineOne
.start
.bGrowX
= TRUE
;
54 g_lineOne
.start
.bGrowY
= TRUE
;
55 g_lineOne
.start
.fStepX
= 0.025f
;
56 g_lineOne
.start
.fStepY
= 0.02f
;
57 g_lineOne
.start
.fLowerLimitX
= 0.1f
;
58 g_lineOne
.start
.fUpperLimitX
= 0.9f
;
59 g_lineOne
.start
.fLowerLimitY
= 0.1f
;
60 g_lineOne
.start
.fUpperLimitY
= 0.9f
;
62 g_lineOne
.end
.fX
= 0.5f
;
63 g_lineOne
.end
.fY
= 0.7f
;
64 g_lineOne
.end
.bGrowX
= TRUE
;
65 g_lineOne
.end
.bGrowY
= FALSE
;
66 g_lineOne
.end
.fStepX
= 0.025f
;
67 g_lineOne
.end
.fStepY
= 0.01f
;
68 g_lineOne
.end
.fLowerLimitX
= 0.1f
;
69 g_lineOne
.end
.fUpperLimitX
= 0.9f
;
70 g_lineOne
.end
.fLowerLimitY
= 0.1f
;
71 g_lineOne
.end
.fUpperLimitY
= 0.9f
;
73 g_lineTwo
.start
.fX
= 0.75f
;
74 g_lineTwo
.start
.fY
= 0.1f
;
75 g_lineTwo
.start
.bGrowX
= FALSE
;
76 g_lineTwo
.start
.bGrowY
= TRUE
;
77 g_lineTwo
.start
.fStepX
= 0.01f
;
78 g_lineTwo
.start
.fStepY
= 0.025f
;
79 g_lineTwo
.start
.fLowerLimitX
= 0.1f
;
80 g_lineTwo
.start
.fUpperLimitX
= 0.9f
;
81 g_lineTwo
.start
.fLowerLimitY
= 0.1f
;
82 g_lineTwo
.start
.fUpperLimitY
= 0.9f
;
84 g_lineTwo
.end
.fX
= 0.8f
;
85 g_lineTwo
.end
.fY
= 0.8f
;
86 g_lineTwo
.end
.bGrowX
= FALSE
;
87 g_lineTwo
.end
.bGrowY
= FALSE
;
88 g_lineTwo
.end
.fStepX
= 0.01f
;
89 g_lineTwo
.end
.fStepY
= 0.01f
;
90 g_lineTwo
.end
.fLowerLimitX
= 0.1f
;
91 g_lineTwo
.end
.fUpperLimitX
= 0.9f
;
92 g_lineTwo
.end
.fLowerLimitY
= 0.1f
;
93 g_lineTwo
.end
.fUpperLimitY
= 0.9f
;
95 /* init gtk+, GL and glut */
96 gtk_init (&argc
, &argv
);
97 gtk_gl_init (&argc
, &argv
);
98 glutInit (&argc
, argv
);
100 /* setup GL-context */
101 pGlConfig
= gdk_gl_config_new_by_mode (GDK_GL_MODE_RGB
|
108 g_print ("Could not setup GL-context!\n");
112 /* create window and hook up event-handlers */
113 pWindow
= gtk_window_new (GTK_WINDOW_TOPLEVEL
);
116 g_print ("Could not create gtk+-window!\n");
120 gtk_widget_add_events (pWindow
,
121 GDK_POINTER_MOTION_MASK
|
122 GDK_BUTTON_PRESS_MASK
|
123 GDK_BUTTON_RELEASE_MASK
);
125 g_signal_connect (G_OBJECT (pWindow
),
127 G_CALLBACK (delete_handler
),
129 g_signal_connect (G_OBJECT (pWindow
),
130 "button-press-event",
131 G_CALLBACK (button_handler
),
133 g_signal_connect (G_OBJECT (pWindow
),
134 "button-release-event",
135 G_CALLBACK (button_handler
),
137 g_signal_connect (G_OBJECT (pWindow
),
139 G_CALLBACK (screen_changed_handler
),
141 g_signal_connect (G_OBJECT (pWindow
),
143 G_CALLBACK (scroll_handler
),
145 g_signal_connect (G_OBJECT (pWindow
),
147 G_CALLBACK (key_press_handler
),
150 pDrawingArea
= gtk_drawing_area_new ();
153 g_print ("Could not create drawing-area!\n");
159 gtk_widget_set_size_request (pDrawingArea
, g_iWidth
, g_iHeight
);
160 gtk_widget_set_gl_capability (pDrawingArea
,
166 g_signal_connect_after (G_OBJECT (pDrawingArea
),
168 G_CALLBACK (realize_handler
),
170 g_signal_connect (G_OBJECT (pDrawingArea
),
172 G_CALLBACK (configure_handler
),
174 g_signal_connect (G_OBJECT (pDrawingArea
),
176 G_CALLBACK (expose_handler
),
178 g_signal_connect (G_OBJECT (pWindow
),
179 "motion-notify-event",
180 G_CALLBACK (motion_notify_handler
),
181 (gpointer
) pDrawingArea
);
183 gtk_container_add (GTK_CONTAINER (pWindow
), pDrawingArea
);
184 gtk_widget_show (pDrawingArea
);
185 gtk_window_set_resizable (GTK_WINDOW (pWindow
), FALSE
);
186 gtk_widget_set_app_paintable (pWindow
, TRUE
);
187 gtk_window_set_decorated (GTK_WINDOW (pWindow
), FALSE
);
188 screen_changed_handler (pWindow
, NULL
, NULL
);
189 gtk_widget_realize (pWindow
);
190 gdk_window_set_back_pixmap (pWindow
->window
, NULL
, FALSE
);
191 gtk_widget_show (pWindow
);
193 /* create cairo-surface/context to act as OpenGL-texture */
194 g_pucSurfaceData
[0] = g_malloc0 (4 * g_iWidth
* g_iHeight
);
195 g_pucSurfaceData
[1] = g_malloc0 (4 * g_iWidth
* g_iHeight
);
196 g_pucSurfaceData
[2] = g_malloc0 (4 * g_iWidth
* g_iHeight
);
197 if (g_pucSurfaceData
[0] && g_pucSurfaceData
[1] && g_pucSurfaceData
[2])
199 pCairoSurface
[0] = cairo_image_surface_create_for_data
200 (g_pucSurfaceData
[0],
206 pCairoSurface
[1] = cairo_image_surface_create_for_data
207 (g_pucSurfaceData
[1],
213 pCairoSurface
[2] = cairo_image_surface_create_for_data
214 (g_pucSurfaceData
[2],
220 g_pCairoContext
[0] = cairo_create (pCairoSurface
[0]);
221 g_pCairoContext
[1] = cairo_create (pCairoSurface
[1]);
222 g_pCairoContext
[2] = cairo_create (pCairoSurface
[2]);
225 /* force a refresh-rate of 20 Hz */
226 uiDrawHandlerId
= g_timeout_add (50,
227 (GSourceFunc
) draw_handler
,
230 /* register timer used by fps-counter */
231 g_pTimerId
= g_timer_new ();
233 /* enter event-loop */
236 /* clear resources before exit */
237 if (g_pucSurfaceData
[0])
238 g_free (g_pucSurfaceData
[0]);
239 if (g_pucSurfaceData
[1])
240 g_free (g_pucSurfaceData
[1]);
241 if (g_pucSurfaceData
[2])
242 g_free (g_pucSurfaceData
[2]);