made sure the windows back-pixmap is NULL
[gl-cairo-cube.git] / events.c
blob4a7300266948b7ea51d463bc14077d914c757f9b
1 /*******************************************************************************
2 **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
3 ** 10 20 30 40 50 60 70 80
4 **
5 ** file:
6 ** events.c
7 **
8 ** author:
9 ** Mirco "MacSlow" Mueller <macslow@bangang.de>
11 ** copyright (C) Mirco Mueller, 2006/2007, placed under the terms of the GPL
13 *******************************************************************************/
15 #include "events.h"
16 #include "cairo-rendering.h"
18 #include <gdk/gdkkeysyms.h>
19 #include <GL/gl.h>
20 #include <GL/glu.h>
21 #include <GL/glut.h>
23 #include "globals.h"
25 GLfloat g_afAngle[3] = {260.0f, -58.0f, 0.0f};
26 GLfloat g_fScale = 1.2f;
27 GLfloat g_fAlpha = 1.0f;
28 gdouble g_fCurrentX;
29 gdouble g_fCurrentY;
30 gdouble g_fDeltaX;
31 gdouble g_fDeltaY;
32 gdouble g_fLastX;
33 gdouble g_fLastY;
34 gboolean g_bLMBPressed = FALSE;
35 gboolean g_bRMBPressed = FALSE;
36 GLuint g_auiColorBuffer[3];
38 gboolean
39 delete_handler (GtkWidget* pWidget,
40 GdkEvent* pEvent,
41 gpointer data)
43 glDeleteTextures (3, g_auiColorBuffer);
44 gtk_main_quit ();
45 return TRUE;
48 gboolean
49 button_handler (GtkWidget* pWidget,
50 GdkEventButton* pEvent,
51 gpointer data)
53 switch (pEvent->button)
55 case 1:
56 if (pEvent->type == GDK_BUTTON_PRESS)
58 g_fCurrentX = pEvent->x;
59 g_fCurrentY = pEvent->y;
60 g_fLastX = g_fCurrentX;
61 g_fLastY = g_fCurrentY;
62 g_bLMBPressed = TRUE;
64 else if (pEvent->type == GDK_BUTTON_RELEASE)
65 g_bLMBPressed = FALSE;
66 break;
68 case 3:
69 if (pEvent->type == GDK_BUTTON_PRESS)
71 g_fCurrentX = pEvent->x;
72 g_fCurrentY = pEvent->y;
73 g_fLastX = g_fCurrentX;
74 g_fLastY = g_fCurrentY;
75 g_bRMBPressed = TRUE;
77 else if (pEvent->type == GDK_BUTTON_RELEASE)
78 g_bRMBPressed = FALSE;
79 break;
82 return TRUE;
85 gboolean
86 scroll_handler (GtkWidget* pWidget,
87 GdkEventScroll* pEvent,
88 gpointer data)
90 switch (pEvent->direction)
92 case GDK_SCROLL_UP:
93 if (g_fAlpha < 1.0f)
94 g_fAlpha += 0.05f;
95 break;
97 case GDK_SCROLL_DOWN:
98 if (g_fAlpha > 0.0f)
99 g_fAlpha -= 0.05f;
100 break;
102 /* just silence gcc */
103 default:
104 break;
107 return TRUE;
110 gboolean
111 motion_notify_handler (GtkWidget* pWidget,
112 GdkEventMotion* pEvent,
113 gpointer data)
115 if (g_bLMBPressed)
117 g_fCurrentX = pEvent->x;
118 g_fCurrentY = pEvent->y;
119 g_fDeltaX = g_fLastX - g_fCurrentX;
120 g_fDeltaY = g_fLastY - g_fCurrentY;
121 g_fLastX = g_fCurrentX;
122 g_fLastY = g_fCurrentY;
124 g_afAngle[0] -= g_fDeltaX;
125 g_afAngle[1] -= g_fDeltaY;
126 gtk_widget_queue_draw (pWidget);
129 if (g_bRMBPressed)
131 g_fCurrentY = pEvent->y;
132 g_fDeltaY = g_fLastY - g_fCurrentY;
133 g_fLastY = g_fCurrentY;
135 g_fScale -= g_fDeltaY / 100.0f;
136 gtk_widget_queue_draw (pWidget);
139 return TRUE;
142 void
143 screen_changed_handler (GtkWidget* pWidget,
144 GdkScreen* pOldScreen,
145 gpointer data)
147 GdkScreen* pScreen = gtk_widget_get_screen (pWidget);
148 GdkColormap* pColormap = gdk_screen_get_rgba_colormap (pScreen);
150 if (!pColormap)
152 g_print ("Could not get a RGBA-colormap. Using plain RGB.\n");
153 pColormap = gdk_screen_get_rgb_colormap (pScreen);
156 gtk_widget_set_colormap (pWidget, pColormap);
159 void
160 realize_handler (GtkWidget* pWidget,
161 gpointer data)
163 GLfloat afLightDiffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};
164 GdkGLContext* pGlContext = gtk_widget_get_gl_context (pWidget);
165 GdkGLDrawable* pGlDrawable = gtk_widget_get_gl_drawable (pWidget);
167 /* make GL-context "current" */
168 if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))
169 return;
171 glColor4f (1.0f, 1.0f, 1.0f, 1.0f);
172 glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
173 glClearDepth (1.0f);
174 glDisable (GL_DEPTH_TEST);
175 glEnable (GL_NORMALIZE);
176 glEnable (GL_BLEND);
177 glBlendFunc (GL_ONE, GL_ONE);
178 glShadeModel (GL_FLAT);
179 glEnable (GL_TEXTURE_RECTANGLE_ARB);
180 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
181 glDisable (GL_CULL_FACE);
182 glLightModelf (GL_LIGHT_MODEL_TWO_SIDE, 0.0f);
183 glEnable (GL_LIGHTING);
184 glEnable (GL_LIGHT0);
185 glLightfv (GL_LIGHT0, GL_DIFFUSE, afLightDiffuse);
187 g_print ("OpenGL version: %s\n", glGetString (GL_VERSION));
188 g_print ("OpenGL vendor: %s\n", glGetString (GL_VENDOR));
189 g_print ("OpenGL renderer: %s\n", glGetString (GL_RENDERER));
191 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
192 glTexParameteri (GL_TEXTURE_RECTANGLE_ARB,
193 GL_TEXTURE_MIN_FILTER,
194 GL_LINEAR_MIPMAP_LINEAR);
195 glTexParameteri (GL_TEXTURE_RECTANGLE_ARB,
196 GL_TEXTURE_MAG_FILTER,
197 GL_LINEAR);
199 glMatrixMode (GL_MODELVIEW);
200 glLoadIdentity ();
201 gluLookAt (0.0f, 0.0f, Z_NEAR,
202 0.0f, 0.0f, 0.0f,
203 0.0f, 1.0f, 0.0f);
204 glTranslatef (0.0f, 0.0f, -Z_NEAR);
206 /* end drawing to current GL-context */
207 gdk_gl_drawable_gl_end (pGlDrawable);
210 gboolean
211 configure_handler (GtkWidget* pWidget,
212 GdkEventConfigure* pEvent,
213 gpointer data)
215 GdkGLContext* pGlContext = gtk_widget_get_gl_context (pWidget);
216 GdkGLDrawable* pGlDrawable = gtk_widget_get_gl_drawable (pWidget);
217 GLsizei w = pWidget->allocation.width;
218 GLsizei h = pWidget->allocation.height;
220 /* make GL-context "current" */
221 if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))
222 return FALSE;
224 glViewport (0, 0, w, h);
225 glMatrixMode (GL_PROJECTION);
226 glLoadIdentity ();
227 gluPerspective (2.0f * FOVY_2, (GLfloat) w / (GLfloat) h, 0.1f, 50.0f);
229 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
231 glGenTextures (3, g_auiColorBuffer);
232 glBindTexture (GL_TEXTURE_RECTANGLE_ARB, g_auiColorBuffer[0]);
233 glTexImage2D (GL_TEXTURE_RECTANGLE_ARB,
235 GL_RGBA,
236 g_iWidth,
237 g_iHeight,
239 GL_BGRA,
240 GL_UNSIGNED_BYTE,
241 NULL);
243 glBindTexture (GL_TEXTURE_RECTANGLE_ARB, g_auiColorBuffer[1]);
244 glTexImage2D (GL_TEXTURE_RECTANGLE_ARB,
246 GL_RGBA,
247 g_iWidth,
248 g_iHeight,
250 GL_BGRA,
251 GL_UNSIGNED_BYTE,
252 NULL);
254 glBindTexture (GL_TEXTURE_RECTANGLE_ARB, g_auiColorBuffer[2]);
255 glTexImage2D (GL_TEXTURE_RECTANGLE_ARB,
257 GL_RGBA,
258 g_iWidth,
259 g_iHeight,
261 GL_BGRA,
262 GL_UNSIGNED_BYTE,
263 NULL);
265 /* end drawing to current GL-context */
266 gdk_gl_drawable_gl_end (pGlDrawable);
268 return TRUE;
271 gboolean
272 expose_handler (GtkWidget* pWidget,
273 GdkEventExpose* pEvent,
274 gpointer data)
276 GdkGLContext* pGlContext = gtk_widget_get_gl_context (pWidget);
277 GdkGLDrawable* pGlDrawable = gtk_widget_get_gl_drawable (pWidget);
278 static gint iFrames = 0;
279 static gdouble fLastTimeStamp = 0.0f;;
280 static gdouble fCurrentTimeStamp = 0.0f;;
281 static gdouble fLastFullSecond = 0.0f;;
282 gdouble fFrameTimeDelta = 0.0f;
283 gdouble fFullSecond = 0.0f;
284 GLfloat afVector[3];
285 GLfloat afMatrixBase[16];
286 GLfloat afFrontDiffuseMat[] = {1.0f * g_fAlpha,
287 1.0f * g_fAlpha,
288 1.0f * g_fAlpha,
289 1.0f * g_fAlpha};
290 GLfloat afBackDiffuseMat[] = {1.0f * g_fAlpha,
291 1.0f * g_fAlpha,
292 1.0f * g_fAlpha,
293 1.0f * g_fAlpha};
295 /* make GL-context "current" */
296 if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))
297 return FALSE;
299 glPushMatrix ();
300 glTranslatef (0.0f, 0.0f, 0.5f);
301 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
302 glGetFloatv (GL_MODELVIEW_MATRIX, afMatrixBase);
303 afVector[0] = afMatrixBase[0];
304 afVector[1] = afMatrixBase[4];
305 afVector[2] = afMatrixBase[8];
306 glRotatef (g_afAngle[1] * 0.5f, afVector[0], afVector[1], afVector[2]);
307 afVector[0] = afMatrixBase[1];
308 afVector[1] = afMatrixBase[5];
309 afVector[2] = afMatrixBase[9];
310 glRotatef (g_afAngle[0] * 0.5f, afVector[0], afVector[1], afVector[2]);
311 glScalef (g_fScale, g_fScale, g_fScale);
313 glMaterialfv (GL_FRONT, GL_DIFFUSE, afFrontDiffuseMat);
314 glMaterialfv (GL_BACK, GL_DIFFUSE, afBackDiffuseMat);
316 render_zini (g_pCairoContext[0], g_iWidth, g_iHeight);
317 advance (&g_lineOne.start);
318 advance (&g_lineOne.end);
319 advance (&g_lineTwo.start);
320 advance (&g_lineTwo.end);
321 render_curve (g_pCairoContext[1],
322 g_iWidth,
323 g_iHeight,
324 &g_lineOne,
325 &g_lineTwo);
326 render_flower (g_pCairoContext[2], g_iWidth, g_iHeight);
328 glBindTexture (GL_TEXTURE_RECTANGLE_ARB, g_auiColorBuffer[0]);
329 glTexImage2D (GL_TEXTURE_RECTANGLE_ARB,
331 GL_RGBA,
332 g_iWidth,
333 g_iHeight,
335 GL_BGRA,
336 GL_UNSIGNED_BYTE,
337 g_pucSurfaceData[0]);
339 glBindTexture (GL_TEXTURE_RECTANGLE_ARB, g_auiColorBuffer[1]);
340 glTexImage2D (GL_TEXTURE_RECTANGLE_ARB,
342 GL_RGBA,
343 g_iWidth,
344 g_iHeight,
346 GL_BGRA,
347 GL_UNSIGNED_BYTE,
348 g_pucSurfaceData[1]);
350 glBindTexture (GL_TEXTURE_RECTANGLE_ARB, g_auiColorBuffer[2]);
351 glTexImage2D (GL_TEXTURE_RECTANGLE_ARB,
353 GL_RGBA,
354 g_iWidth,
355 g_iHeight,
357 GL_BGRA,
358 GL_UNSIGNED_BYTE,
359 g_pucSurfaceData[2]);
361 glBindTexture (GL_TEXTURE_RECTANGLE_ARB, g_auiColorBuffer[0]);
362 glBegin (GL_QUADS);
363 glNormal3f (1.0f, 0.0f, 0.0f);
364 glTexCoord2f (0.0f, 0.0f);
365 glVertex3f (1.0f, 1.0f, 1.0f);
366 glTexCoord2f ((GLfloat) g_iWidth, 0.0f);
367 glVertex3f (1.0f, 1.0f, -1.0f);
368 glTexCoord2f ((GLfloat) g_iWidth, (GLfloat) g_iHeight);
369 glVertex3f (1.0f, -1.0f, -1.0f);
370 glTexCoord2f (0.0f, (GLfloat) g_iHeight);
371 glVertex3f (1.0f, -1.0f, 1.0f);
373 glNormal3f (0.0f, 1.0f, 0.0f);
374 glTexCoord2f (0.0f, (GLfloat) g_iHeight);
375 glVertex3f (1.0f, 1.0f, 1.0f);
376 glTexCoord2f (0.0f, 0.0f);
377 glVertex3f (1.0f, 1.0f, -1.0f);
378 glTexCoord2f ((GLfloat) g_iWidth, 0.0f);
379 glVertex3f (-1.0f, 1.0f, -1.0f);
380 glTexCoord2f ((GLfloat) g_iWidth, (GLfloat) g_iHeight);
381 glVertex3f (-1.0f, 1.0f, 1.0f);
382 glEnd ();
384 glBindTexture (GL_TEXTURE_RECTANGLE_ARB, g_auiColorBuffer[1]);
385 glBegin (GL_QUADS);
386 glNormal3f (0.0f, 0.0f, 1.0f);
387 glTexCoord2f (0.0f, 0.0f);
388 glVertex3f (1.0f, 1.0f, 1.0f);
389 glTexCoord2f ((GLfloat) g_iWidth, 0.0f);
390 glVertex3f (-1.0f, 1.0f, 1.0f);
391 glTexCoord2f ((GLfloat) g_iWidth, (GLfloat) g_iHeight);
392 glVertex3f (-1.0f, -1.0f, 1.0f);
393 glTexCoord2f (0.0f, (GLfloat) g_iHeight);
394 glVertex3f (1.0f, -1.0f, 1.0f);
396 glNormal3f (0.0f, -1.0f, 0.0f);
397 glTexCoord2f (0.0f, 0.0f);
398 glVertex3f (1.0f, -1.0f, 1.0f);
399 glTexCoord2f ((GLfloat) g_iWidth, 0.0f);
400 glVertex3f (1.0f, -1.0f, -1.0f);
401 glTexCoord2f ((GLfloat) g_iWidth, (GLfloat) g_iHeight);
402 glVertex3f (-1.0f, -1.0f, -1.0f);
403 glTexCoord2f (0.0f, (GLfloat) g_iHeight);
404 glVertex3f (-1.0f, -1.0f, 1.0f);
405 glEnd ();
407 glBindTexture (GL_TEXTURE_RECTANGLE_ARB, g_auiColorBuffer[2]);
408 glBegin (GL_QUADS);
409 glNormal3f (-1.0f, 0.0f, 0.0f);
410 glTexCoord2f (0.0f, 0.0f);
411 glVertex3f (-1.0f, 1.0f, 1.0f);
412 glTexCoord2f ((GLfloat) g_iWidth, 0.0f);
413 glVertex3f (-1.0f, 1.0f, -1.0f);
414 glTexCoord2f ((GLfloat) g_iWidth, (GLfloat) g_iHeight);
415 glVertex3f (-1.0f, -1.0f, -1.0f);
416 glTexCoord2f (0.0f, (GLfloat) g_iHeight);
417 glVertex3f (-1.0f, -1.0f, 1.0f);
419 glNormal3f (0.0f, 0.0f, -1.0f);
420 glTexCoord2f (0.0f, (GLfloat) g_iHeight);
421 glVertex3f (1.0f, 1.0f, -1.0f);
422 glTexCoord2f (0.0f, 0.0f);
423 glVertex3f (-1.0f, 1.0f, -1.0f);
424 glTexCoord2f ((GLfloat) g_iWidth, 0.0f);
425 glVertex3f (-1.0f, -1.0f, -1.0f);
426 glTexCoord2f ((GLfloat) g_iWidth, (GLfloat) g_iHeight);
427 glVertex3f (1.0f, -1.0f, -1.0f);
428 glEnd ();
430 glPopMatrix ();
432 if (gdk_gl_drawable_is_double_buffered (pGlDrawable))
433 gdk_gl_drawable_swap_buffers (pGlDrawable);
434 else
435 glFlush ();
437 /* end drawing to current GL-context */
438 gdk_gl_drawable_gl_end (pGlDrawable);
440 fCurrentTimeStamp = g_timer_elapsed (g_pTimerId, &g_ulMilliSeconds);
441 g_ulMilliSeconds /= 1000;
442 fFrameTimeDelta = fCurrentTimeStamp - fLastTimeStamp;
443 fFullSecond = fCurrentTimeStamp - fLastFullSecond;
445 if (fFullSecond < 1.0f)
446 iFrames++;
447 else
449 g_print ("fps: %d, last frame-time: %f\n",
450 iFrames,
451 fFrameTimeDelta);
452 iFrames = 0;
453 fLastFullSecond = fCurrentTimeStamp;
456 fLastTimeStamp = fCurrentTimeStamp;
458 return TRUE;
461 gboolean
462 key_press_handler (GtkWidget* pWidget,
463 GdkEventKey* pEvent,
464 GMainLoop* pLoop)
466 if (pEvent->type == GDK_KEY_PRESS)
468 switch (pEvent->keyval)
470 case GDK_q :
471 case GDK_Escape :
472 delete_handler (pWidget, NULL, NULL);
473 break;
475 case GDK_Page_Up :
476 if (g_fAlpha < 1.0f)
477 g_fAlpha += 0.05;
478 break;
480 case GDK_Page_Down :
481 if (g_fAlpha > 0.0f)
482 g_fAlpha -= 0.05;
483 break;
485 default :
486 break;
490 return TRUE;
493 gboolean
494 draw_handler (GtkWidget* pWidget)
496 gtk_widget_queue_draw (pWidget);
498 return TRUE;