8 void reshape(int x, int y);
9 void keypress(unsigned char key, int x, int y);
10 void mouse(int bn, int st, int x, int y);
11 void motion(int x, int y);
12 void sball_motion(int x, int y, int z);
13 void sball_rotate(int rx, int ry, int rz);
14 void sball_button(int bn, int state);
16 static void vcross(float *res, const float *a, const float *b);
17 static void qmul(float *a, const float *b);
18 static void qrotation(float *q, float angle, float x, float y, float z);
19 static void qrotate(float *q, float angle, float x, float y, float z);
20 static void mrotation_quat(float *m, const float *q);
23 float cam_theta, cam_phi = 25, cam_dist = 8;
27 float torus_pos[3], torus_rot[4] = {0, 0, 0, 1};
28 int teapot, torus, cone, sphere;
31 #ifndef GL_FRAMEBUFFER_SRGB
32 #define GL_FRAMEBUFFER_SRGB 0x8db9
35 #ifndef GL_MULTISAMPLE
36 #define GL_MULTISAMPLE 0x809d
39 int main(int argc, char **argv)
41 int i, test_aa = 0, test_srgb = 0;
42 unsigned int mode = GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE;
44 for(i=1; i<argc; i++) {
45 if(strcmp(argv[i], "-ms") == 0) {
47 } else if(strcmp(argv[i], "-srgb") == 0) {
52 if(test_aa) mode |= GLUT_MULTISAMPLE;
53 if(test_srgb) mode |= GLUT_SRGB;
55 glutInit(&argc, argv);
56 glutInitWindowSize(800, 600);
57 glutInitDisplayMode(mode);
58 glutCreateWindow("miniglut test");
60 glutDisplayFunc(display);
61 glutReshapeFunc(reshape);
62 glutKeyboardFunc(keypress);
64 glutMotionFunc(motion);
65 glutSpaceballMotionFunc(sball_motion);
66 glutSpaceballRotateFunc(sball_rotate);
67 glutSpaceballButtonFunc(sball_button);
69 glEnable(GL_DEPTH_TEST);
70 glEnable(GL_CULL_FACE);
71 glEnable(GL_LIGHTING);
75 glEnable(GL_MULTISAMPLE);
78 glEnable(GL_FRAMEBUFFER_SRGB);
81 torus = glGenLists(1);
82 glNewList(torus, GL_COMPILE);
83 glutSolidTorus(0.3, 1, 16, 24);
87 glNewList(cone, GL_COMPILE);
88 glutSolidCone(1.1, 2, 16, 2);
91 sphere = glGenLists(1);
92 glNewList(sphere, GL_COMPILE);
93 glutSolidSphere(0.4, 16, 8);
96 teapot = glGenLists(1);
97 glNewList(teapot, GL_COMPILE);
113 float lpos[] = {-1, 2, 3, 0};
114 float sbrot_xform[16];
116 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
118 glMatrixMode(GL_MODELVIEW);
120 glTranslatef(0, 0, -cam_dist);
121 glRotatef(cam_phi, 1, 0, 0);
122 glRotatef(cam_theta, 0, 1, 0);
124 glLightfv(GL_LIGHT0, GL_POSITION, lpos);
128 tm = glutGet(GLUT_ELAPSED_TIME);
129 glRotatef(tm / 10.0f, 1, 0, 0);
130 glRotatef(tm / 10.0f, 0, 1, 0);
138 glTranslatef(torus_pos[0] - 2.5, torus_pos[1], torus_pos[2]);
139 mrotation_quat(sbrot_xform, torus_rot);
140 glMultMatrixf(sbrot_xform);
145 glTranslatef(2.5, -1, 0);
146 glRotatef(-90, 1, 0, 0);
151 glTranslatef(0, -0.5, 2.5);
159 glVertex3f(-5, -1.3, 5);
160 glVertex3f(5, -1.3, 5);
161 glVertex3f(5, -1.3, -5);
162 glVertex3f(-5, -1.3, -5);
170 void reshape(int x, int y)
172 float vsz, aspect = (float)x / (float)y;
173 glViewport(0, 0, x, y);
174 glMatrixMode(GL_PROJECTION);
176 vsz = 0.4663f * ZNEAR;
177 glFrustum(-aspect * vsz, aspect * vsz, -vsz, vsz, 0.5, 500.0);
180 void keypress(unsigned char key, int x, int y)
183 static int prev_xsz, prev_ysz;
184 static long start_msec;
194 glutIdleFunc(anim ? idle : 0);
198 start_msec = glutGet(GLUT_ELAPSED_TIME);
201 long tm = glutGet(GLUT_ELAPSED_TIME) - start_msec;
202 long fps = (nframes * 100000) / tm;
203 printf("framerate: %ld.%ld fps\n", fps / 100, fps % 100);
209 if(!(glutGetModifiers() & GLUT_ACTIVE_ALT)) {
215 prev_xsz = glutGet(GLUT_WINDOW_WIDTH);
216 prev_ysz = glutGet(GLUT_WINDOW_HEIGHT);
219 glutReshapeWindow(prev_xsz, prev_ysz);
225 void mouse(int bn, int st, int x, int y)
227 int bidx = bn - GLUT_LEFT_BUTTON;
228 bnstate[bidx] = st == GLUT_DOWN;
233 void motion(int x, int y)
235 int dx = x - mouse_x;
236 int dy = y - mouse_y;
240 if(!(dx | dy)) return;
243 cam_theta += dx * 0.5;
245 if(cam_phi < -90) cam_phi = -90;
246 if(cam_phi > 90) cam_phi = 90;
250 cam_dist += dy * 0.1;
251 if(cam_dist < 0) cam_dist = 0;
256 void sball_motion(int x, int y, int z)
258 torus_pos[0] += x * 0.001f;
259 torus_pos[1] += y * 0.001f;
260 torus_pos[2] -= z * 0.001f;
264 static float rsqrt(float number)
268 static const float threehalfs = 1.5f;
273 i = 0x5f3759df - (i >> 1);
275 y *= threehalfs - (x2 * y * y);
276 y *= threehalfs - (x2 * y * y);
280 void sball_rotate(int rx, int ry, int rz)
283 float s = (float)rsqrt(rx * rx + ry * ry + rz * rz);
284 qrotate(torus_rot, 0.001f / s, rx * s, ry * s, -rz * s);
289 void sball_button(int bn, int state)
291 if(state == GLUT_DOWN) {
292 torus_pos[0] = torus_pos[1] = torus_pos[2] = 0;
293 torus_rot[0] = torus_rot[1] = torus_rot[2] = 0;
300 static void vcross(float *res, const float *a, const float *b)
302 res[0] = a[1] * b[2] - a[2] * b[1];
303 res[1] = a[2] * b[0] - a[0] * b[2];
304 res[2] = a[0] * b[1] - a[1] * b[0];
307 static void qmul(float *a, const float *b)
312 dot = a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
315 x = a[3] * b[0] + b[3] * a[0] + cross[0];
316 y = a[3] * b[1] + b[3] * a[1] + cross[1];
317 z = a[3] * b[2] + b[3] * a[2] + cross[2];
318 a[3] = a[3] * b[3] - dot;
324 void mglut_sincos(float angle, float *sptr, float *cptr);
325 float mglut_tan(float x);
327 static void qrotation(float *q, float angle, float x, float y, float z)
330 mglut_sincos(angle * 0.5f, &sa, &ca);
337 static void qrotate(float *q, float angle, float x, float y, float z)
340 qrotation(qrot, angle, x, y, z);
348 static void mrotation_quat(float *m, const float *q)
350 float xsq2 = 2.0f * q[0] * q[0];
351 float ysq2 = 2.0f * q[1] * q[1];
352 float zsq2 = 2.0f * q[2] * q[2];
353 float sx = 1.0f - ysq2 - zsq2;
354 float sy = 1.0f - xsq2 - zsq2;
355 float sz = 1.0f - xsq2 - ysq2;
357 m[3] = m[7] = m[11] = m[12] = m[13] = m[14] = 0.0f;
361 m[1] = 2.0f * q[0] * q[1] + 2.0f * q[3] * q[2];
362 m[2] = 2.0f * q[2] * q[0] - 2.0f * q[3] * q[1];
363 m[4] = 2.0f * q[0] * q[1] - 2.0f * q[3] * q[2];
365 m[6] = 2.0f * q[1] * q[2] + 2.0f * q[3] * q[0];
366 m[8] = 2.0f * q[2] * q[0] + 2.0f * q[3] * q[1];
367 m[9] = 2.0f * q[1] * q[2] - 2.0f * q[3] * q[0];