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, July 2006
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 GtkWidget
* g_pWindow
= NULL
;
33 GdkGLConfig
* g_pGlConfig
= NULL
;
34 GtkWidget
* g_pDrawingArea
= NULL
;
35 guint g_uiDrawHandlerId
= 0;
38 GLfloat g_afAngle
[3] = {0.0f
, 0.0f
, 0.0f
};
40 GLfloat g_fScale
= 1.0f
;
41 GTimer
* g_pTimerId
= NULL
;
42 gboolean g_bKeepRunning
= TRUE
;
43 gdouble g_fLastTimeStamp
= 0.0f
;
44 gdouble g_fCurrentTimeStamp
= 0.0f
;
45 gdouble g_fLastFullSecond
= 0.0f
;
46 gboolean g_bLMBPressed
= FALSE
;
47 gboolean g_bRMBPressed
= FALSE
;
48 GLuint g_auiColorBuffer
[2];
57 GLfloat g_fAlpha
= 1.0f
;
58 gboolean g_bInitialized
= FALSE
;
59 cairo_surface_t
* g_pCairoSurface
[2];
60 cairo_t
* g_pCairoContext
[2];
61 guchar
* g_pucSurfaceData
[2];
62 gulong g_ulMilliSeconds
= 0L;
66 int main (int argc
, char** argv
)
68 g_lineOne
.start
.fX
= 0.1f
;
69 g_lineOne
.start
.fY
= 0.2f
;
70 g_lineOne
.start
.bGrowX
= TRUE
;
71 g_lineOne
.start
.bGrowY
= TRUE
;
72 g_lineOne
.start
.fStepX
= 0.025f
;
73 g_lineOne
.start
.fStepY
= 0.02f
;
74 g_lineOne
.start
.fLowerLimitX
= 0.1f
;
75 g_lineOne
.start
.fUpperLimitX
= 0.9f
;
76 g_lineOne
.start
.fLowerLimitY
= 0.1f
;
77 g_lineOne
.start
.fUpperLimitY
= 0.9f
;
79 g_lineOne
.end
.fX
= 0.5f
;
80 g_lineOne
.end
.fY
= 0.7f
;
81 g_lineOne
.end
.bGrowX
= TRUE
;
82 g_lineOne
.end
.bGrowY
= FALSE
;
83 g_lineOne
.end
.fStepX
= 0.025f
;
84 g_lineOne
.end
.fStepY
= 0.01f
;
85 g_lineOne
.end
.fLowerLimitX
= 0.1f
;
86 g_lineOne
.end
.fUpperLimitX
= 0.9f
;
87 g_lineOne
.end
.fLowerLimitY
= 0.1f
;
88 g_lineOne
.end
.fUpperLimitY
= 0.9f
;
90 g_lineTwo
.start
.fX
= 0.75f
;
91 g_lineTwo
.start
.fY
= 0.1f
;
92 g_lineTwo
.start
.bGrowX
= FALSE
;
93 g_lineTwo
.start
.bGrowY
= TRUE
;
94 g_lineTwo
.start
.fStepX
= 0.01f
;
95 g_lineTwo
.start
.fStepY
= 0.025f
;
96 g_lineTwo
.start
.fLowerLimitX
= 0.1f
;
97 g_lineTwo
.start
.fUpperLimitX
= 0.9f
;
98 g_lineTwo
.start
.fLowerLimitY
= 0.1f
;
99 g_lineTwo
.start
.fUpperLimitY
= 0.9f
;
101 g_lineTwo
.end
.fX
= 0.8f
;
102 g_lineTwo
.end
.fY
= 0.8f
;
103 g_lineTwo
.end
.bGrowX
= FALSE
;
104 g_lineTwo
.end
.bGrowY
= FALSE
;
105 g_lineTwo
.end
.fStepX
= 0.01f
;
106 g_lineTwo
.end
.fStepY
= 0.01f
;
107 g_lineTwo
.end
.fLowerLimitX
= 0.1f
;
108 g_lineTwo
.end
.fUpperLimitX
= 0.9f
;
109 g_lineTwo
.end
.fLowerLimitY
= 0.1f
;
110 g_lineTwo
.end
.fUpperLimitY
= 0.9f
;
112 /* init gtk+, GL and glut */
113 gtk_init (&argc
,&argv
);
114 gtk_gl_init (&argc
,&argv
);
115 glutInit (&argc
, argv
);
117 /* setup GL-context */
118 g_pGlConfig
= gdk_gl_config_new_by_mode (GDK_GL_MODE_RGB
|
125 g_print ("Could not setup GL-context!\n");
129 /* create window and hook up event-handlers */
130 g_pWindow
= gtk_window_new (GTK_WINDOW_TOPLEVEL
);
133 g_print ("Could not create gtk+-window!\n");
137 gtk_widget_add_events (g_pWindow
,
138 GDK_POINTER_MOTION_MASK
|
139 GDK_BUTTON_PRESS_MASK
|
140 GDK_BUTTON_RELEASE_MASK
);
142 g_signal_connect (G_OBJECT (g_pWindow
),
144 G_CALLBACK (delete_handler
),
146 g_signal_connect (G_OBJECT (g_pWindow
),
147 "button-press-event",
148 G_CALLBACK (button_handler
),
150 g_signal_connect (G_OBJECT (g_pWindow
),
151 "button-release-event",
152 G_CALLBACK (button_handler
),
154 g_signal_connect (G_OBJECT (g_pWindow
),
156 G_CALLBACK (screen_changed_handler
),
158 g_signal_connect (G_OBJECT (g_pWindow
),
160 G_CALLBACK (scroll_handler
),
162 g_signal_connect (G_OBJECT (g_pWindow
),
164 G_CALLBACK (key_press_handler
),
167 g_pDrawingArea
= gtk_drawing_area_new ();
170 g_print ("Could not create drawing-area!\n");
174 g_iWindowWidth
= g_iWidth
= 512;
175 g_iWindowHeight
= g_iHeight
= 512;
176 gtk_widget_set_size_request (g_pDrawingArea
, g_iWindowWidth
, g_iWindowHeight
);
177 gtk_widget_set_gl_capability (g_pDrawingArea
,
183 g_signal_connect_after (G_OBJECT (g_pDrawingArea
),
185 G_CALLBACK (realize_handler
),
187 g_signal_connect (G_OBJECT (g_pDrawingArea
),
189 G_CALLBACK (configure_handler
),
191 g_signal_connect (G_OBJECT (g_pDrawingArea
),
193 G_CALLBACK (expose_handler
),
195 g_signal_connect (G_OBJECT (g_pWindow
),
196 "motion-notify-event",
197 G_CALLBACK (motion_notify_handler
),
198 (gpointer
) g_pDrawingArea
);
200 gtk_container_add (GTK_CONTAINER (g_pWindow
), g_pDrawingArea
);
201 gtk_widget_show (g_pDrawingArea
);
202 gtk_window_set_resizable (GTK_WINDOW (g_pWindow
), FALSE
);
203 gtk_widget_set_app_paintable (g_pWindow
, TRUE
);
204 gtk_window_set_decorated (GTK_WINDOW (g_pWindow
), FALSE
);
205 screen_changed_handler (g_pWindow
, NULL
, NULL
);
206 gtk_widget_show (g_pWindow
);
208 /* create cairo-surface/context to act as OpenGL-texture */
209 g_pucSurfaceData
[0] = g_malloc0 (4 * g_iWidth
* g_iHeight
);
210 g_pucSurfaceData
[1] = g_malloc0 (4 * g_iWidth
* g_iHeight
);
211 if (g_pucSurfaceData
[0] && g_pucSurfaceData
[1])
213 g_pCairoSurface
[0] = cairo_image_surface_create_for_data (g_pucSurfaceData
[0],
218 g_pCairoSurface
[1] = cairo_image_surface_create_for_data (g_pucSurfaceData
[1],
224 g_pCairoContext
[0] = cairo_create (g_pCairoSurface
[0]);
225 g_pCairoContext
[1] = cairo_create (g_pCairoSurface
[1]);
226 g_bInitialized
= TRUE
;
229 /* force a refresh-rate of 20 Hz */
230 g_uiDrawHandlerId
= g_timeout_add (50,
231 (GSourceFunc
) draw_handler
,
234 /* register timer used by fps-counter */
235 g_pTimerId
= g_timer_new ();
237 /* enter event-loop */
240 /* clear resources before exit */
241 glDeleteTextures (2, g_auiColorBuffer
);
242 if (g_pucSurfaceData
[0])
243 g_free (g_pucSurfaceData
[0]);
244 if (g_pucSurfaceData
[1])
245 g_free (g_pucSurfaceData
[1]);