8eefe5fc8015349391173c79f18e67c201f21c85
[familia.git] / src / ui / drawing_area.c
1 #include <gtk/gtk.h>
2 #include <gtk/gtkgl.h>
3 #include <GL/gl.h>
4 #include <GL/glu.h>
5
6 #include "../debug.h"
7 #include "drawing_area.h"
8 #include "../math/3d.h"
9 #include "../graphics/constants.h"
10 #include "../graphics/individual.h"
11 #include "../graphics/family.h"
12 #include "../storage/storage.h"
13
14 extern GLdouble camera_pos_x;
15 extern GLdouble camera_pos_y;
16 extern GLdouble camera_pos_z;
17
18 GtkDrawingArea * drawing_area = NULL;
19
20 /**
21  * The "draw" signal handler. All the OpenGL re-drawing should
22  * be done here. This is repeatedly called as the painting routine
23  * every time the 'draw' event is signalled.
24  */
25 gboolean drawing_area_draw(GtkWidget *widget, cairo_t *cr, gpointer user_data)
26 {
27         unsigned int i;
28         unsigned int individuals_no;
29         unsigned int families_no;
30         struct familia_storage * storage;
31         struct position * pos;
32
33         /*** OpenGL BEGIN ***/
34         if (!gtk_widget_begin_gl (widget)) {
35                 return FALSE;
36         }
37
38         glMatrixMode (GL_MODELVIEW);
39         glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
40         glLoadIdentity ();
41
42         gluLookAt (camera_pos_x, camera_pos_y, camera_pos_z, 0.0, 0.0, -100.0, 0.0, 1.0, 0.0);
43
44         storage = familia_storage_get_current();
45         individuals_no = storage->individuals_no;
46
47         for (i = 0; i < individuals_no; i++) {
48                 pos = calculate_individual_position(storage->individuals[i]);
49
50         glPushMatrix ();
51                 glTranslatef(
52                         (pos != NULL) ? pos->x : 0,
53                         (pos != NULL) ? pos->y : 0,
54                         (pos != NULL) ? pos->z : -10
55                 );
56                 glColor3f (1.0, 1.0, 1.0);
57                 graphics_render_individual();
58         glPopMatrix ();
59
60                 if (pos != NULL) {
61                         free(pos);
62                         pos = NULL;
63                 }
64         }
65
66         families_no = storage->families_no;
67
68         for (i = 0; i < families_no; i++) {
69         glPushMatrix ();
70                 glTranslatef(i * (GR_FAM_RADIUS + 1), -3, -10);
71                 glColor3f (1.0, 1.0, 1.0);
72                 graphics_render_family();
73         glPopMatrix ();
74         }
75
76         gtk_widget_end_gl (widget, TRUE);
77         /*** OpenGL END ***/
78
79         return TRUE;
80 }
81
82 /**
83  * The "configure_event" signal handler. Any processing required when
84  * the OpenGL-capable drawing area is re-configured should be done here.
85  * Almost always it will be used to resize the OpenGL viewport when
86  * the window is resized.
87  */
88 gboolean drawing_area_configure_event (GtkWidget *widget,
89                                         GdkEventConfigure *event, gpointer data)
90 {
91         GtkAllocation allocation;
92
93         /* OpenGL widget width */
94         GLfloat w;
95         /* OpenGL widget height */
96         GLfloat h;
97         /* Aspect ratio */
98         GLfloat aspect = 0;
99
100         gtk_widget_get_allocation (widget, &allocation);
101         w = allocation.width;
102         h = allocation.height;
103
104         aspect = w / h;
105         /*** OpenGL BEGIN ***/
106         if (!gtk_widget_begin_gl (widget))
107                 return FALSE;
108
109         glViewport (0, 0, w, h);
110
111         glMatrixMode (GL_PROJECTION);
112         glLoadIdentity ();
113         gluPerspective (60.0, aspect, 0.1, 60.0);
114         glMatrixMode(GL_MODELVIEW);
115
116         gtk_widget_end_gl (widget, FALSE);
117         /*** OpenGL END ***/
118
119         return TRUE;
120 }
121
122 /**
123  * The "realize" signal handler. All the OpenGL initialization
124  * should be performed here, such as default background colour,
125  * certain states etc.
126  */
127 void drawing_area_realize (GtkWidget *widget, gpointer data)
128 {
129         /*** OpenGL BEGIN ***/
130         if (!gtk_widget_begin_gl (widget)) {
131                 return;
132         }
133
134         glClearColor (0.0, 0.0, 0.0, 0.0);
135         glShadeModel (GL_FLAT);
136
137         gtk_widget_end_gl (widget, FALSE);
138         /*** OpenGL END ***/
139
140         return;
141 }
142
143 /**
144  * The "unrealize" signal handler. Any processing required when
145  * the OpenGL-capable window is unrealized should be done here.
146  */
147 void drawing_area_unrealize (GtkWidget *widget, gpointer data)
148 {
149         /* Code */
150 }