Getting the "spaceball" demo to build properly in Windows
[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 #if defined(WIN32)\r
66   /* This is STRICTLY a place-holder until we get this working properly for windows.\r
67    * I do not pretend that this is equivalent to the non-Windows equivalent.  I just\r
68    * want the thing to build without errors.\r
69    */\r
70   glMultMatrixf((float*)xform);\r
71 #else\r
72   glMultTransposeMatrixf((float*)xform);\r
73 #endif\r
74 \r
75   draw_cube();\r
76 \r
77   glutSwapBuffers();\r
78 }\r
79 \r
80 void draw_cube(void)\r
81 {\r
82   glBegin(GL_QUADS);\r
83   /* face +Z */\r
84   glNormal3f(0, 0, 1);\r
85   glColor3f(1, 0, 0);\r
86   glVertex3f(-1, -1, 1);\r
87   glVertex3f(1, -1, 1);\r
88   glVertex3f(1, 1, 1);\r
89   glVertex3f(-1, 1, 1);\r
90   /* face +X */\r
91   glNormal3f(1, 0, 0);\r
92   glColor3f(0, 1, 0);\r
93   glVertex3f(1, -1, 1);\r
94   glVertex3f(1, -1, -1);\r
95   glVertex3f(1, 1, -1);\r
96   glVertex3f(1, 1, 1);\r
97   /* face -Z */\r
98   glNormal3f(0, 0, -1);\r
99   glColor3f(0, 0, 1);\r
100   glVertex3f(1, -1, -1);\r
101   glVertex3f(-1, -1, -1);\r
102   glVertex3f(-1, 1, -1);\r
103   glVertex3f(1, 1, -1);\r
104   /* face -X */\r
105   glNormal3f(-1, 0, 0);\r
106   glColor3f(1, 1, 0);\r
107   glVertex3f(-1, -1, -1);\r
108   glVertex3f(-1, -1, 1);\r
109   glVertex3f(-1, 1, 1);\r
110   glVertex3f(-1, 1, -1);\r
111   /* face +Y */\r
112   glNormal3f(0, 1, 0);\r
113   glColor3f(0, 1, 1);\r
114   glVertex3f(-1, 1, 1);\r
115   glVertex3f(1, 1, 1);\r
116   glVertex3f(1, 1, -1);\r
117   glVertex3f(-1, 1, -1);\r
118   /* face -Y */\r
119   glNormal3f(0, -1, 0);\r
120   glColor3f(1, 0, 1);\r
121   glVertex3f(-1, -1, -1);\r
122   glVertex3f(1, -1, -1);\r
123   glVertex3f(1, -1, 1);\r
124   glVertex3f(-1, -1, 1);\r
125   glEnd();\r
126 }\r
127 \r
128 /* 45deg fov */\r
129 #define FOV    (M_PI / 4.0)\r
130 \r
131 void reshape(int x, int y)\r
132 {\r
133   float aspect = (float)x / (float)y;\r
134   float halfy = (float)tan(FOV / 2.0);\r
135   float halfx = halfy * aspect;\r
136 \r
137   glViewport(0, 0, x, y);\r
138 \r
139   glMatrixMode(GL_PROJECTION);\r
140   glLoadIdentity();\r
141   glFrustum(-halfx, halfx, -halfy, halfy, 1.0, 1000.0);\r
142 }\r
143 \r
144 void keyb(unsigned char key, int x, int y)\r
145 {\r
146   switch(key) {\r
147   case 'q':\r
148   case 'Q':\r
149   case 27:\r
150     exit(0);\r
151 \r
152   case ' ':\r
153     /* reset initial view */\r
154     pos = v3_cons(0, 0, -6);\r
155     rot = quat_cons(1, 0, 0, 0);\r
156     glutPostRedisplay();\r
157 \r
158   default:\r
159     break;\r
160   }\r
161 }\r
162 \r
163 void sbmot(int x, int y, int z)\r
164 {\r
165   pos.x += x * 0.001f;\r
166   pos.y += y * 0.001f;\r
167   pos.z -= z * 0.001f;\r
168   glutPostRedisplay();\r
169 }\r
170 \r
171 void sbrot(int x, int y, int z)\r
172 {\r
173   float axis_len = (float)sqrt(x * x + y * y + z * z);\r
174   rot = quat_rotate(rot, axis_len * 0.001f, -x / axis_len, -y / axis_len, z / axis_len);\r
175   glutPostRedisplay();\r
176 }\r
177 \r
178 void sbbut(int bn, int state)\r
179 {\r
180   if(state == GLUT_DOWN) {\r
181     pos = v3_cons(0, 0, -6);\r
182     rot = quat_cons(1, 0, 0, 0);\r
183     glutPostRedisplay();\r
184   }\r
185 }\r