inital commit of gl-cairo-cube
[gl-cairo-cube.git] / main.c
blob4484c149bbcd6f0db58c886934bab420b6a5fa2a
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, July 2006
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 GtkWidget* g_pWindow = NULL;
33 GdkGLConfig* g_pGlConfig = NULL;
34 GtkWidget* g_pDrawingArea = NULL;
35 guint g_uiDrawHandlerId = 0;
36 gint g_iWindowWidth;
37 gint g_iWindowHeight;
38 GLfloat g_afAngle[3] = {0.0f, 0.0f, 0.0f};
39 gint g_iFrames = 0;
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];
49 gdouble g_fCurrentX;
50 gdouble g_fCurrentY;
51 gdouble g_fDeltaX;
52 gdouble g_fDeltaY;
53 gdouble g_fLastX;
54 gdouble g_fLastY;
55 gint g_iWidth = 1;
56 gint g_iHeight = 1;
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;
63 Line g_lineOne;
64 Line g_lineTwo;
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 |
119 GDK_GL_MODE_ALPHA |
120 GDK_GL_MODE_DEPTH |
121 GDK_GL_MODE_DOUBLE);
123 if (!g_pGlConfig)
125 g_print ("Could not setup GL-context!\n");
126 return 1;
129 /* create window and hook up event-handlers */
130 g_pWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
131 if (!g_pWindow)
133 g_print ("Could not create gtk+-window!\n");
134 return 2;
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),
143 "delete-event",
144 G_CALLBACK (delete_handler),
145 NULL);
146 g_signal_connect (G_OBJECT (g_pWindow),
147 "button-press-event",
148 G_CALLBACK (button_handler),
149 NULL);
150 g_signal_connect (G_OBJECT (g_pWindow),
151 "button-release-event",
152 G_CALLBACK (button_handler),
153 NULL);
154 g_signal_connect (G_OBJECT (g_pWindow),
155 "screen-changed",
156 G_CALLBACK (screen_changed_handler),
157 NULL);
158 g_signal_connect (G_OBJECT (g_pWindow),
159 "scroll-event",
160 G_CALLBACK (scroll_handler),
161 NULL);
162 g_signal_connect (G_OBJECT (g_pWindow),
163 "key-press-event",
164 G_CALLBACK (key_press_handler),
165 NULL);
167 g_pDrawingArea = gtk_drawing_area_new ();
168 if (!g_pDrawingArea)
170 g_print ("Could not create drawing-area!\n");
171 return 3;
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,
178 g_pGlConfig,
179 NULL,
180 TRUE,
181 GDK_GL_RGBA_TYPE);
183 g_signal_connect_after (G_OBJECT (g_pDrawingArea),
184 "realize",
185 G_CALLBACK (realize_handler),
186 NULL);
187 g_signal_connect (G_OBJECT (g_pDrawingArea),
188 "configure-event",
189 G_CALLBACK (configure_handler),
190 NULL);
191 g_signal_connect (G_OBJECT (g_pDrawingArea),
192 "expose-event",
193 G_CALLBACK (expose_handler),
194 NULL);
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],
214 CAIRO_FORMAT_ARGB32,
215 g_iWidth,
216 g_iHeight,
217 4 * g_iWidth);
218 g_pCairoSurface[1] = cairo_image_surface_create_for_data (g_pucSurfaceData[1],
219 CAIRO_FORMAT_ARGB32,
220 g_iWidth,
221 g_iHeight,
222 4 * g_iWidth);
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,
232 g_pDrawingArea);
234 /* register timer used by fps-counter */
235 g_pTimerId = g_timer_new ();
237 /* enter event-loop */
238 gtk_main ();
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]);
247 return 0;