First attempt at adding John Tsiombikas' spaceball support for X11. It compiles...
[freeglut] / progs / demos / spaceball / spaceball.c
1 /* Spaceball demo\r
2  *\r
3  * Written by John Tsiombikas <nuclear@member.fsf.org>\r
4  * (converted from the libspnav cube example)\r
5  *\r
6  * Use the spaceball to move and rotate the colored cube.\r
7  * Pressing any button will reset the cube at its original location.\r
8  *\r
9  * Press escape or q to exit.\r
10  */\r
11 \r
12 #include <stdio.h>\r
13 #include <stdlib.h>\r
14 #include <math.h>\r
15 #include <GL/freeglut.h>\r
16 #include "vmath.h"\r
17 \r
18 void draw_cube(void);\r
19 \r
20 /* callbacks */\r
21 void disp(void);\r
22 void reshape(int x, int y);\r
23 void keyb(unsigned char key, int x, int y);\r
24 void sbmot(int x, int y, int z);        /* spaceball translation */\r
25 void sbrot(int x, int y, int z);        /* spaceball rotation */\r
26 void sbbut(int bn, int state);          /* spaceball button */\r
27 \r
28 vec3_t pos = {0, 0, -6};\r
29 quat_t rot = {0, 0, 0, 1};\r
30 \r
31 int main(int argc, char **argv)\r
32 {\r
33         glutInit(&argc, argv);\r
34         glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);\r
35         glutCreateWindow("spaceball demo");\r
36 \r
37         glutDisplayFunc(disp);\r
38         glutReshapeFunc(reshape);\r
39         glutKeyboardFunc(keyb);\r
40         glutSpaceballMotionFunc(sbmot);\r
41         glutSpaceballRotateFunc(sbrot);\r
42         glutSpaceballButtonFunc(sbbut);\r
43 \r
44         glEnable(GL_CULL_FACE);\r
45 \r
46         glutMainLoop();\r
47         return 0;\r
48 }\r
49 \r
50 void disp(void)\r
51 {\r
52         mat4_t xform;\r
53 \r
54         quat_to_mat(xform, rot);\r
55 \r
56         glClear(GL_COLOR_BUFFER_BIT);\r
57 \r
58         glMatrixMode(GL_MODELVIEW);\r
59         glLoadIdentity();\r
60         glTranslatef(pos.x, pos.y, pos.z);\r
61         glMultTransposeMatrixf((float*)xform);\r
62 \r
63         draw_cube();\r
64 \r
65         glutSwapBuffers();\r
66 }\r
67 \r
68 void draw_cube(void)\r
69 {\r
70         glBegin(GL_QUADS);\r
71         /* face +Z */\r
72         glNormal3f(0, 0, 1);\r
73         glColor3f(1, 0, 0);\r
74         glVertex3f(-1, -1, 1);\r
75         glVertex3f(1, -1, 1);\r
76         glVertex3f(1, 1, 1);\r
77         glVertex3f(-1, 1, 1);\r
78         /* face +X */\r
79         glNormal3f(1, 0, 0);\r
80         glColor3f(0, 1, 0);\r
81         glVertex3f(1, -1, 1);\r
82         glVertex3f(1, -1, -1);\r
83         glVertex3f(1, 1, -1);\r
84         glVertex3f(1, 1, 1);\r
85         /* face -Z */\r
86         glNormal3f(0, 0, -1);\r
87         glColor3f(0, 0, 1);\r
88         glVertex3f(1, -1, -1);\r
89         glVertex3f(-1, -1, -1);\r
90         glVertex3f(-1, 1, -1);\r
91         glVertex3f(1, 1, -1);\r
92         /* face -X */\r
93         glNormal3f(-1, 0, 0);\r
94         glColor3f(1, 1, 0);\r
95         glVertex3f(-1, -1, -1);\r
96         glVertex3f(-1, -1, 1);\r
97         glVertex3f(-1, 1, 1);\r
98         glVertex3f(-1, 1, -1);\r
99         /* face +Y */\r
100         glNormal3f(0, 1, 0);\r
101         glColor3f(0, 1, 1);\r
102         glVertex3f(-1, 1, 1);\r
103         glVertex3f(1, 1, 1);\r
104         glVertex3f(1, 1, -1);\r
105         glVertex3f(-1, 1, -1);\r
106         /* face -Y */\r
107         glNormal3f(0, -1, 0);\r
108         glColor3f(1, 0, 1);\r
109         glVertex3f(-1, -1, -1);\r
110         glVertex3f(1, -1, -1);\r
111         glVertex3f(1, -1, 1);\r
112         glVertex3f(-1, -1, 1);\r
113         glEnd();\r
114 }\r
115 \r
116 /* 45deg fov */\r
117 #define FOV             (M_PI / 4.0)\r
118 \r
119 void reshape(int x, int y)\r
120 {\r
121         float aspect = (float)x / (float)y;\r
122         float halfy = tan(FOV / 2.0);\r
123         float halfx = halfy * aspect;\r
124 \r
125         glViewport(0, 0, x, y);\r
126 \r
127         glMatrixMode(GL_PROJECTION);\r
128         glLoadIdentity();\r
129         glFrustum(-halfx, halfx, -halfy, halfy, 1.0, 1000.0);\r
130 }\r
131 \r
132 void keyb(unsigned char key, int x, int y)\r
133 {\r
134         switch(key) {\r
135         case 'q':\r
136         case 'Q':\r
137         case 27:\r
138                 exit(0);\r
139 \r
140         case ' ':\r
141                 /* reset initial view */\r
142                 pos = v3_cons(0, 0, -6);\r
143                 rot = quat_cons(1, 0, 0, 0);\r
144                 glutPostRedisplay();\r
145 \r
146         default:\r
147                 break;\r
148         }\r
149 }\r
150 \r
151 void sbmot(int x, int y, int z)\r
152 {\r
153         pos.x += x * 0.001;\r
154         pos.y += y * 0.001;\r
155         pos.z -= z * 0.001;\r
156         glutPostRedisplay();\r
157 }\r
158 \r
159 void sbrot(int x, int y, int z)\r
160 {\r
161         float axis_len = sqrt(x * x + y * y + z * z);\r
162         rot = quat_rotate(rot, axis_len * 0.001, -x / axis_len, -y / axis_len, z / axis_len);\r
163         glutPostRedisplay();\r
164 }\r
165 \r
166 void sbbut(int bn, int state)\r
167 {\r
168         if(state == GLUT_DOWN) {\r
169                 pos = v3_cons(0, 0, -6);\r
170                 rot = quat_cons(1, 0, 0, 0);\r
171                 glutPostRedisplay();\r
172         }\r
173 }\r