eBookReaderSwitch/thirdparty/freeglut/progs/demos/spaceball/spaceball.c

178 lines
3.6 KiB
C
Raw Normal View History

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