First attempt at adding John Tsiombikas' spaceball support for X11. It compiles...
[freeglut] / progs / demos / spaceball / spaceball.c
diff --git a/progs/demos/spaceball/spaceball.c b/progs/demos/spaceball/spaceball.c
new file mode 100644 (file)
index 0000000..ebdbc40
--- /dev/null
@@ -0,0 +1,173 @@
+/* Spaceball demo\r
+ *\r
+ * Written by John Tsiombikas <nuclear@member.fsf.org>\r
+ * (converted from the libspnav cube example)\r
+ *\r
+ * Use the spaceball to move and rotate the colored cube.\r
+ * Pressing any button will reset the cube at its original location.\r
+ *\r
+ * Press escape or q to exit.\r
+ */\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <math.h>\r
+#include <GL/freeglut.h>\r
+#include "vmath.h"\r
+\r
+void draw_cube(void);\r
+\r
+/* callbacks */\r
+void disp(void);\r
+void reshape(int x, int y);\r
+void keyb(unsigned char key, int x, int y);\r
+void sbmot(int x, int y, int z);       /* spaceball translation */\r
+void sbrot(int x, int y, int z);       /* spaceball rotation */\r
+void sbbut(int bn, int state);         /* spaceball button */\r
+\r
+vec3_t pos = {0, 0, -6};\r
+quat_t rot = {0, 0, 0, 1};\r
+\r
+int main(int argc, char **argv)\r
+{\r
+       glutInit(&argc, argv);\r
+       glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);\r
+       glutCreateWindow("spaceball demo");\r
+\r
+       glutDisplayFunc(disp);\r
+       glutReshapeFunc(reshape);\r
+       glutKeyboardFunc(keyb);\r
+       glutSpaceballMotionFunc(sbmot);\r
+       glutSpaceballRotateFunc(sbrot);\r
+       glutSpaceballButtonFunc(sbbut);\r
+\r
+       glEnable(GL_CULL_FACE);\r
+\r
+       glutMainLoop();\r
+       return 0;\r
+}\r
+\r
+void disp(void)\r
+{\r
+       mat4_t xform;\r
+\r
+       quat_to_mat(xform, rot);\r
+\r
+       glClear(GL_COLOR_BUFFER_BIT);\r
+\r
+       glMatrixMode(GL_MODELVIEW);\r
+       glLoadIdentity();\r
+       glTranslatef(pos.x, pos.y, pos.z);\r
+       glMultTransposeMatrixf((float*)xform);\r
+\r
+       draw_cube();\r
+\r
+       glutSwapBuffers();\r
+}\r
+\r
+void draw_cube(void)\r
+{\r
+       glBegin(GL_QUADS);\r
+       /* face +Z */\r
+       glNormal3f(0, 0, 1);\r
+       glColor3f(1, 0, 0);\r
+       glVertex3f(-1, -1, 1);\r
+       glVertex3f(1, -1, 1);\r
+       glVertex3f(1, 1, 1);\r
+       glVertex3f(-1, 1, 1);\r
+       /* face +X */\r
+       glNormal3f(1, 0, 0);\r
+       glColor3f(0, 1, 0);\r
+       glVertex3f(1, -1, 1);\r
+       glVertex3f(1, -1, -1);\r
+       glVertex3f(1, 1, -1);\r
+       glVertex3f(1, 1, 1);\r
+       /* face -Z */\r
+       glNormal3f(0, 0, -1);\r
+       glColor3f(0, 0, 1);\r
+       glVertex3f(1, -1, -1);\r
+       glVertex3f(-1, -1, -1);\r
+       glVertex3f(-1, 1, -1);\r
+       glVertex3f(1, 1, -1);\r
+       /* face -X */\r
+       glNormal3f(-1, 0, 0);\r
+       glColor3f(1, 1, 0);\r
+       glVertex3f(-1, -1, -1);\r
+       glVertex3f(-1, -1, 1);\r
+       glVertex3f(-1, 1, 1);\r
+       glVertex3f(-1, 1, -1);\r
+       /* face +Y */\r
+       glNormal3f(0, 1, 0);\r
+       glColor3f(0, 1, 1);\r
+       glVertex3f(-1, 1, 1);\r
+       glVertex3f(1, 1, 1);\r
+       glVertex3f(1, 1, -1);\r
+       glVertex3f(-1, 1, -1);\r
+       /* face -Y */\r
+       glNormal3f(0, -1, 0);\r
+       glColor3f(1, 0, 1);\r
+       glVertex3f(-1, -1, -1);\r
+       glVertex3f(1, -1, -1);\r
+       glVertex3f(1, -1, 1);\r
+       glVertex3f(-1, -1, 1);\r
+       glEnd();\r
+}\r
+\r
+/* 45deg fov */\r
+#define FOV            (M_PI / 4.0)\r
+\r
+void reshape(int x, int y)\r
+{\r
+       float aspect = (float)x / (float)y;\r
+       float halfy = tan(FOV / 2.0);\r
+       float halfx = halfy * aspect;\r
+\r
+       glViewport(0, 0, x, y);\r
+\r
+       glMatrixMode(GL_PROJECTION);\r
+       glLoadIdentity();\r
+       glFrustum(-halfx, halfx, -halfy, halfy, 1.0, 1000.0);\r
+}\r
+\r
+void keyb(unsigned char key, int x, int y)\r
+{\r
+       switch(key) {\r
+       case 'q':\r
+       case 'Q':\r
+       case 27:\r
+               exit(0);\r
+\r
+       case ' ':\r
+               /* reset initial view */\r
+               pos = v3_cons(0, 0, -6);\r
+               rot = quat_cons(1, 0, 0, 0);\r
+               glutPostRedisplay();\r
+\r
+       default:\r
+               break;\r
+       }\r
+}\r
+\r
+void sbmot(int x, int y, int z)\r
+{\r
+       pos.x += x * 0.001;\r
+       pos.y += y * 0.001;\r
+       pos.z -= z * 0.001;\r
+       glutPostRedisplay();\r
+}\r
+\r
+void sbrot(int x, int y, int z)\r
+{\r
+       float axis_len = sqrt(x * x + y * y + z * z);\r
+       rot = quat_rotate(rot, axis_len * 0.001, -x / axis_len, -y / axis_len, z / axis_len);\r
+       glutPostRedisplay();\r
+}\r
+\r
+void sbbut(int bn, int state)\r
+{\r
+       if(state == GLUT_DOWN) {\r
+               pos = v3_cons(0, 0, -6);\r
+               rot = quat_cons(1, 0, 0, 0);\r
+               glutPostRedisplay();\r
+       }\r
+}\r