made sure the windows back-pixmap is NULL
[gl-cairo-cube.git] / main.c
blob3ce75681c5e19271e92251055280652b015f656f
1 /*******************************************************************************
2 **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
3 ** 10 20 30 40 50 60 70 80
4 **
5 ** program:
6 ** gl-cairo-cube
7 **
8 ** author:
9 ** Mirco "MacSlow" Mueller <macslow@bangang.de>
11 ** copyright (C) Mirco Mueller, 2006/2007
13 ** notes:
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 *******************************************************************************/
24 #include <gtk/gtk.h>
25 #include <gtk/gtkgl.h>
26 #include <GL/glut.h>
28 #include "geometry.h"
29 #include "events.h"
30 #include "cairo-rendering.h"
32 GTimer* g_pTimerId = NULL;
33 gint g_iWidth = 1;
34 gint g_iHeight = 1;
35 cairo_t* g_pCairoContext[3];
36 guchar* g_pucSurfaceData[3];
37 gulong g_ulMilliSeconds = 0L;
38 Line g_lineOne;
39 Line g_lineTwo;
41 int
42 main (int argc,
43 char** argv)
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 |
102 GDK_GL_MODE_ALPHA |
103 GDK_GL_MODE_DEPTH |
104 GDK_GL_MODE_DOUBLE);
106 if (!pGlConfig)
108 g_print ("Could not setup GL-context!\n");
109 return 1;
112 /* create window and hook up event-handlers */
113 pWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
114 if (!pWindow)
116 g_print ("Could not create gtk+-window!\n");
117 return 2;
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),
126 "delete-event",
127 G_CALLBACK (delete_handler),
128 NULL);
129 g_signal_connect (G_OBJECT (pWindow),
130 "button-press-event",
131 G_CALLBACK (button_handler),
132 NULL);
133 g_signal_connect (G_OBJECT (pWindow),
134 "button-release-event",
135 G_CALLBACK (button_handler),
136 NULL);
137 g_signal_connect (G_OBJECT (pWindow),
138 "screen-changed",
139 G_CALLBACK (screen_changed_handler),
140 NULL);
141 g_signal_connect (G_OBJECT (pWindow),
142 "scroll-event",
143 G_CALLBACK (scroll_handler),
144 NULL);
145 g_signal_connect (G_OBJECT (pWindow),
146 "key-press-event",
147 G_CALLBACK (key_press_handler),
148 NULL);
150 pDrawingArea = gtk_drawing_area_new ();
151 if (!pDrawingArea)
153 g_print ("Could not create drawing-area!\n");
154 return 3;
157 g_iWidth = 512;
158 g_iHeight = 512;
159 gtk_widget_set_size_request (pDrawingArea, g_iWidth, g_iHeight);
160 gtk_widget_set_gl_capability (pDrawingArea,
161 pGlConfig,
162 NULL,
163 TRUE,
164 GDK_GL_RGBA_TYPE);
166 g_signal_connect_after (G_OBJECT (pDrawingArea),
167 "realize",
168 G_CALLBACK (realize_handler),
169 NULL);
170 g_signal_connect (G_OBJECT (pDrawingArea),
171 "configure-event",
172 G_CALLBACK (configure_handler),
173 NULL);
174 g_signal_connect (G_OBJECT (pDrawingArea),
175 "expose-event",
176 G_CALLBACK (expose_handler),
177 NULL);
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],
201 CAIRO_FORMAT_ARGB32,
202 g_iWidth,
203 g_iHeight,
204 4 * g_iWidth);
206 pCairoSurface[1] = cairo_image_surface_create_for_data
207 (g_pucSurfaceData[1],
208 CAIRO_FORMAT_ARGB32,
209 g_iWidth,
210 g_iHeight,
211 4 * g_iWidth);
213 pCairoSurface[2] = cairo_image_surface_create_for_data
214 (g_pucSurfaceData[2],
215 CAIRO_FORMAT_ARGB32,
216 g_iWidth,
217 g_iHeight,
218 4 * g_iWidth);
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,
228 pDrawingArea);
230 /* register timer used by fps-counter */
231 g_pTimerId = g_timer_new ();
233 /* enter event-loop */
234 gtk_main ();
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]);
244 return 0;