Last test... hopefully.
[gl-cairo-cube.git] / events.c
blob71342a27f69abc1fca38c802779436e915b5e703
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, July 2006, 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 now.\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, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
193 glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
195 glMatrixMode (GL_MODELVIEW);
196 glLoadIdentity ();
197 gluLookAt (0.0f, 0.0f, Z_NEAR,
198 0.0f, 0.0f, 0.0f,
199 0.0f, 1.0f, 0.0f);
200 glTranslatef (0.0f, 0.0f, -Z_NEAR);
202 /* end drawing to current GL-context */
203 gdk_gl_drawable_gl_end (pGlDrawable);
206 gboolean
207 configure_handler (GtkWidget* pWidget,
208 GdkEventConfigure* pEvent,
209 gpointer data)
211 GdkGLContext* pGlContext = gtk_widget_get_gl_context (pWidget);
212 GdkGLDrawable* pGlDrawable = gtk_widget_get_gl_drawable (pWidget);
213 GLsizei w = pWidget->allocation.width;
214 GLsizei h = pWidget->allocation.height;
216 /* make GL-context "current" */
217 if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))
218 return FALSE;
220 glViewport (0, 0, w, h);
221 glMatrixMode (GL_PROJECTION);
222 glLoadIdentity ();
223 gluPerspective (2.0f * FOVY_2, (GLfloat) w / (GLfloat) h, 0.1f, 50.0f);
225 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
227 glGenTextures (3, g_auiColorBuffer);
228 glBindTexture (GL_TEXTURE_RECTANGLE_ARB, g_auiColorBuffer[0]);
229 glTexImage2D (GL_TEXTURE_RECTANGLE_ARB,
231 GL_RGBA,
232 g_iWidth,
233 g_iHeight,
235 GL_BGRA,
236 GL_UNSIGNED_BYTE,
237 NULL);
239 glBindTexture (GL_TEXTURE_RECTANGLE_ARB, g_auiColorBuffer[1]);
240 glTexImage2D (GL_TEXTURE_RECTANGLE_ARB,
242 GL_RGBA,
243 g_iWidth,
244 g_iHeight,
246 GL_BGRA,
247 GL_UNSIGNED_BYTE,
248 NULL);
250 glBindTexture (GL_TEXTURE_RECTANGLE_ARB, g_auiColorBuffer[2]);
251 glTexImage2D (GL_TEXTURE_RECTANGLE_ARB,
253 GL_RGBA,
254 g_iWidth,
255 g_iHeight,
257 GL_BGRA,
258 GL_UNSIGNED_BYTE,
259 NULL);
261 /* end drawing to current GL-context */
262 gdk_gl_drawable_gl_end (pGlDrawable);
264 return TRUE;
267 gboolean
268 expose_handler (GtkWidget* pWidget,
269 GdkEventExpose* pEvent,
270 gpointer data)
272 GdkGLContext* pGlContext = gtk_widget_get_gl_context (pWidget);
273 GdkGLDrawable* pGlDrawable = gtk_widget_get_gl_drawable (pWidget);
274 static gint iFrames = 0;
275 static gdouble fLastTimeStamp = 0.0f;;
276 static gdouble fCurrentTimeStamp = 0.0f;;
277 static gdouble fLastFullSecond = 0.0f;;
278 gdouble fFrameTimeDelta = 0.0f;
279 gdouble fFullSecond = 0.0f;
280 GLfloat afVector[3];
281 GLfloat afMatrixBase[16];
282 GLfloat afFrontDiffuseMat[] = {1.0f * g_fAlpha, 1.0f * g_fAlpha, 1.0f * g_fAlpha, 1.0f * g_fAlpha};
283 GLfloat afBackDiffuseMat[] = {1.0f * g_fAlpha, 1.0f * g_fAlpha, 1.0f * g_fAlpha, 1.0f * g_fAlpha};
285 /* make GL-context "current" */
286 if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))
287 return FALSE;
289 glPushMatrix ();
290 glTranslatef (0.0f, 0.0f, 0.5f);
291 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
292 glGetFloatv (GL_MODELVIEW_MATRIX, afMatrixBase);
293 afVector[0] = afMatrixBase[0];
294 afVector[1] = afMatrixBase[4];
295 afVector[2] = afMatrixBase[8];
296 glRotatef (g_afAngle[1] * 0.5f, afVector[0], afVector[1], afVector[2]);
297 afVector[0] = afMatrixBase[1];
298 afVector[1] = afMatrixBase[5];
299 afVector[2] = afMatrixBase[9];
300 glRotatef (g_afAngle[0] * 0.5f, afVector[0], afVector[1], afVector[2]);
301 glScalef (g_fScale, g_fScale, g_fScale);
303 glMaterialfv (GL_FRONT, GL_DIFFUSE, afFrontDiffuseMat);
304 glMaterialfv (GL_BACK, GL_DIFFUSE, afBackDiffuseMat);
306 render_zini (g_pCairoContext[0], g_iWidth, g_iHeight);
307 advance (&g_lineOne.start);
308 advance (&g_lineOne.end);
309 advance (&g_lineTwo.start);
310 advance (&g_lineTwo.end);
311 render_curve (g_pCairoContext[1], g_iWidth, g_iHeight, &g_lineOne, &g_lineTwo);
312 render_flower (g_pCairoContext[2], g_iWidth, g_iHeight);
314 glBindTexture (GL_TEXTURE_RECTANGLE_ARB, g_auiColorBuffer[0]);
315 glTexImage2D (GL_TEXTURE_RECTANGLE_ARB,
317 GL_RGBA,
318 g_iWidth,
319 g_iHeight,
321 GL_BGRA,
322 GL_UNSIGNED_BYTE,
323 g_pucSurfaceData[0]);
325 glBindTexture (GL_TEXTURE_RECTANGLE_ARB, g_auiColorBuffer[1]);
326 glTexImage2D (GL_TEXTURE_RECTANGLE_ARB,
328 GL_RGBA,
329 g_iWidth,
330 g_iHeight,
332 GL_BGRA,
333 GL_UNSIGNED_BYTE,
334 g_pucSurfaceData[1]);
336 glBindTexture (GL_TEXTURE_RECTANGLE_ARB, g_auiColorBuffer[2]);
337 glTexImage2D (GL_TEXTURE_RECTANGLE_ARB,
339 GL_RGBA,
340 g_iWidth,
341 g_iHeight,
343 GL_BGRA,
344 GL_UNSIGNED_BYTE,
345 g_pucSurfaceData[2]);
347 glBindTexture (GL_TEXTURE_RECTANGLE_ARB, g_auiColorBuffer[0]);
348 glBegin (GL_QUADS);
349 glNormal3f (1.0f, 0.0f, 0.0f);
350 glTexCoord2f (0.0f, 0.0f);
351 glVertex3f (1.0f, 1.0f, 1.0f);
352 glTexCoord2f ((GLfloat) g_iWidth, 0.0f);
353 glVertex3f (1.0f, 1.0f, -1.0f);
354 glTexCoord2f ((GLfloat) g_iWidth, (GLfloat) g_iHeight);
355 glVertex3f (1.0f, -1.0f, -1.0f);
356 glTexCoord2f (0.0f, (GLfloat) g_iHeight);
357 glVertex3f (1.0f, -1.0f, 1.0f);
359 glNormal3f (0.0f, 1.0f, 0.0f);
360 glTexCoord2f (0.0f, (GLfloat) g_iHeight);
361 glVertex3f (1.0f, 1.0f, 1.0f);
362 glTexCoord2f (0.0f, 0.0f);
363 glVertex3f (1.0f, 1.0f, -1.0f);
364 glTexCoord2f ((GLfloat) g_iWidth, 0.0f);
365 glVertex3f (-1.0f, 1.0f, -1.0f);
366 glTexCoord2f ((GLfloat) g_iWidth, (GLfloat) g_iHeight);
367 glVertex3f (-1.0f, 1.0f, 1.0f);
368 glEnd ();
370 glBindTexture (GL_TEXTURE_RECTANGLE_ARB, g_auiColorBuffer[1]);
371 glBegin (GL_QUADS);
372 glNormal3f (0.0f, 0.0f, 1.0f);
373 glTexCoord2f (0.0f, 0.0f);
374 glVertex3f (1.0f, 1.0f, 1.0f);
375 glTexCoord2f ((GLfloat) g_iWidth, 0.0f);
376 glVertex3f (-1.0f, 1.0f, 1.0f);
377 glTexCoord2f ((GLfloat) g_iWidth, (GLfloat) g_iHeight);
378 glVertex3f (-1.0f, -1.0f, 1.0f);
379 glTexCoord2f (0.0f, (GLfloat) g_iHeight);
380 glVertex3f (1.0f, -1.0f, 1.0f);
382 glNormal3f (0.0f, -1.0f, 0.0f);
383 glTexCoord2f (0.0f, 0.0f);
384 glVertex3f (1.0f, -1.0f, 1.0f);
385 glTexCoord2f ((GLfloat) g_iWidth, 0.0f);
386 glVertex3f (1.0f, -1.0f, -1.0f);
387 glTexCoord2f ((GLfloat) g_iWidth, (GLfloat) g_iHeight);
388 glVertex3f (-1.0f, -1.0f, -1.0f);
389 glTexCoord2f (0.0f, (GLfloat) g_iHeight);
390 glVertex3f (-1.0f, -1.0f, 1.0f);
391 glEnd ();
393 glBindTexture (GL_TEXTURE_RECTANGLE_ARB, g_auiColorBuffer[2]);
394 glBegin (GL_QUADS);
395 glNormal3f (-1.0f, 0.0f, 0.0f);
396 glTexCoord2f (0.0f, 0.0f);
397 glVertex3f (-1.0f, 1.0f, 1.0f);
398 glTexCoord2f ((GLfloat) g_iWidth, 0.0f);
399 glVertex3f (-1.0f, 1.0f, -1.0f);
400 glTexCoord2f ((GLfloat) g_iWidth, (GLfloat) g_iHeight);
401 glVertex3f (-1.0f, -1.0f, -1.0f);
402 glTexCoord2f (0.0f, (GLfloat) g_iHeight);
403 glVertex3f (-1.0f, -1.0f, 1.0f);
405 glNormal3f (0.0f, 0.0f, -1.0f);
406 glTexCoord2f (0.0f, (GLfloat) g_iHeight);
407 glVertex3f (1.0f, 1.0f, -1.0f);
408 glTexCoord2f (0.0f, 0.0f);
409 glVertex3f (-1.0f, 1.0f, -1.0f);
410 glTexCoord2f ((GLfloat) g_iWidth, 0.0f);
411 glVertex3f (-1.0f, -1.0f, -1.0f);
412 glTexCoord2f ((GLfloat) g_iWidth, (GLfloat) g_iHeight);
413 glVertex3f (1.0f, -1.0f, -1.0f);
414 glEnd ();
416 glPopMatrix ();
418 if (gdk_gl_drawable_is_double_buffered (pGlDrawable))
419 gdk_gl_drawable_swap_buffers (pGlDrawable);
420 else
421 glFlush ();
423 /* end drawing to current GL-context */
424 gdk_gl_drawable_gl_end (pGlDrawable);
426 fCurrentTimeStamp = g_timer_elapsed (g_pTimerId, &g_ulMilliSeconds);
427 g_ulMilliSeconds /= 1000;
428 fFrameTimeDelta = fCurrentTimeStamp - fLastTimeStamp;
429 fFullSecond = fCurrentTimeStamp - fLastFullSecond;
431 if (fFullSecond < 1.0f)
432 iFrames++;
433 else
435 g_print ("fps: %d, last frame-time: %f\n", iFrames, fFrameTimeDelta);
436 iFrames = 0;
437 fLastFullSecond = fCurrentTimeStamp;
440 fLastTimeStamp = fCurrentTimeStamp;
442 return TRUE;
445 gboolean
446 key_press_handler (GtkWidget* pWidget,
447 GdkEventKey* pEvent,
448 GMainLoop* pLoop)
450 if (pEvent->type == GDK_KEY_PRESS)
452 switch (pEvent->keyval)
454 case GDK_q :
455 case GDK_Escape :
456 delete_handler (pWidget, NULL, NULL);
457 break;
459 case GDK_Page_Up :
460 if (g_fAlpha < 1.0f)
461 g_fAlpha += 0.05;
462 break;
464 case GDK_Page_Down :
465 if (g_fAlpha > 0.0f)
466 g_fAlpha -= 0.05;
467 break;
469 default :
470 break;
474 return TRUE;
477 gboolean
478 draw_handler (GtkWidget* pWidget)
480 gtk_widget_queue_draw (pWidget);
482 return TRUE;