moved static variables and functions that should not have stuck behind in fg_joystick...
[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 #ifndef M_PI\r
19 #define M_PI    3.14159265358979323846264338327950\r
20 #endif\r
21 \r
22 void draw_cube(void);\r
23 \r
24 /* callbacks */\r
25 void disp(void);\r
26 void reshape(int x, int y);\r
27 void keyb(unsigned char key, int x, int y);\r
28 void sbmot(int x, int y, int z);  /* spaceball translation */\r
29 void sbrot(int x, int y, int z);  /* spaceball rotation */\r
30 void sbbut(int bn, int state);    /* spaceball button */\r
31 \r
32 vec3_t pos = {0, 0, -6};\r
33 quat_t rot = {0, 0, 0, 1};\r
34 \r
35 int main(int argc, char **argv)\r
36 {\r
37   glutInit(&argc, argv);\r
38   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);\r
39   glutCreateWindow("spaceball demo");\r
40 \r
41   glutDisplayFunc(disp);\r
42   glutReshapeFunc(reshape);\r
43   glutKeyboardFunc(keyb);\r
44   glutSpaceballMotionFunc(sbmot);\r
45   glutSpaceballRotateFunc(sbrot);\r
46   glutSpaceballButtonFunc(sbbut);\r
47 \r
48   glEnable(GL_CULL_FACE);\r
49 \r
50   glutMainLoop();\r
51   return 0;\r
52 }\r
53 \r
54 void disp(void)\r
55 {\r
56   mat4_t xform;\r
57 \r
58   quat_to_mat(xform, rot);\r
59 \r
60   glClear(GL_COLOR_BUFFER_BIT);\r
61 \r
62   glMatrixMode(GL_MODELVIEW);\r
63   glLoadIdentity();\r
64   glTranslatef(pos.x, pos.y, pos.z);\r
65   glMultMatrixf((float*)xform);\r
66 \r
67   draw_cube();\r
68 \r
69   glutSwapBuffers();\r
70 }\r
71 \r
72 void draw_cube(void)\r
73 {\r
74   glBegin(GL_QUADS);\r
75   /* face +Z */\r
76   glNormal3f(0, 0, 1);\r
77   glColor3f(1, 0, 0);\r
78   glVertex3f(-1, -1, 1);\r
79   glVertex3f(1, -1, 1);\r
80   glVertex3f(1, 1, 1);\r
81   glVertex3f(-1, 1, 1);\r
82   /* face +X */\r
83   glNormal3f(1, 0, 0);\r
84   glColor3f(0, 1, 0);\r
85   glVertex3f(1, -1, 1);\r
86   glVertex3f(1, -1, -1);\r
87   glVertex3f(1, 1, -1);\r
88   glVertex3f(1, 1, 1);\r
89   /* face -Z */\r
90   glNormal3f(0, 0, -1);\r
91   glColor3f(0, 0, 1);\r
92   glVertex3f(1, -1, -1);\r
93   glVertex3f(-1, -1, -1);\r
94   glVertex3f(-1, 1, -1);\r
95   glVertex3f(1, 1, -1);\r
96   /* face -X */\r
97   glNormal3f(-1, 0, 0);\r
98   glColor3f(1, 1, 0);\r
99   glVertex3f(-1, -1, -1);\r
100   glVertex3f(-1, -1, 1);\r
101   glVertex3f(-1, 1, 1);\r
102   glVertex3f(-1, 1, -1);\r
103   /* face +Y */\r
104   glNormal3f(0, 1, 0);\r
105   glColor3f(0, 1, 1);\r
106   glVertex3f(-1, 1, 1);\r
107   glVertex3f(1, 1, 1);\r
108   glVertex3f(1, 1, -1);\r
109   glVertex3f(-1, 1, -1);\r
110   /* face -Y */\r
111   glNormal3f(0, -1, 0);\r
112   glColor3f(1, 0, 1);\r
113   glVertex3f(-1, -1, -1);\r
114   glVertex3f(1, -1, -1);\r
115   glVertex3f(1, -1, 1);\r
116   glVertex3f(-1, -1, 1);\r
117   glEnd();\r
118 }\r
119 \r
120 /* 45deg fov */\r
121 #define FOV    (M_PI / 4.0)\r
122 \r
123 void reshape(int x, int y)\r
124 {\r
125   float aspect = (float)x / (float)y;\r
126   float halfy = (float)tan(FOV / 2.0);\r
127   float halfx = halfy * aspect;\r
128 \r
129   glViewport(0, 0, x, y);\r
130 \r
131   glMatrixMode(GL_PROJECTION);\r
132   glLoadIdentity();\r
133   glFrustum(-halfx, halfx, -halfy, halfy, 1.0, 1000.0);\r
134 }\r
135 \r
136 void keyb(unsigned char key, int x, int y)\r
137 {\r
138   switch(key) {\r
139   case 'q':\r
140   case 'Q':\r
141   case 27:\r
142     exit(0);\r
143 \r
144   case ' ':\r
145     /* reset initial view */\r
146     pos = v3_cons(0, 0, -6);\r
147     rot = quat_cons(1, 0, 0, 0);\r
148     glutPostRedisplay();\r
149 \r
150   default:\r
151     break;\r
152   }\r
153 }\r
154 \r
155 void sbmot(int x, int y, int z)\r
156 {\r
157   pos.x += x * 0.001f;\r
158   pos.y += y * 0.001f;\r
159   pos.z -= z * 0.001f;\r
160   glutPostRedisplay();\r
161 }\r
162 \r
163 void sbrot(int x, int y, int z)\r
164 {\r
165   float axis_len = (float)sqrt(x * x + y * y + z * z);\r
166   rot = quat_rotate(rot, axis_len * 0.001f, -x / axis_len, -y / axis_len, z / axis_len);\r
167   glutPostRedisplay();\r
168 }\r
169 \r
170 void sbbut(int bn, int state)\r
171 {\r
172   if(state == GLUT_DOWN) {\r
173     pos = v3_cons(0, 0, -6);\r
174     rot = quat_cons(1, 0, 0, 0);\r
175     glutPostRedisplay();\r
176   }\r
177 }\r