Created
October 25, 2013 13:25
-
-
Save ueokande/7154642 to your computer and use it in GitHub Desktop.
Test program for 3D controller using a SlimBlade.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* What's this ? | |
* ============= | |
* | |
* This is a test program for 3D controller using a `SlimBlade` produced | |
* by Kensinton. For detail of SlimBlade, see the following URL : | |
* http://www.kensington.com/kensington/us/us/p/1444/K72327US/slimblade™-wired-media-trackball.aspx | |
* | |
* You can rotate displaied 3D object by using your SlimBlade. If you | |
* don't have SlimBlade, you can use your mouse device and its wheel. | |
* Press ESC or Q to quit. | |
* | |
* How to compile | |
* ============== | |
* | |
* You can compile with C compiler such as GCC, Clang, and MSVC. You need | |
* to install OpenGL libraries (GL, GLU and glut), and link above shared | |
* libraries on compiling a source. A case of gcc, specify a shared | |
* library with -l options as following: | |
* gcc -lGL -lGLU -lglut slimbladegl.c | |
*/ | |
#include <string.h> | |
#include <GL/glut.h> | |
/* rotation matrix */ | |
float rotMatrix[16] = {1, 0, 0, 0, | |
0, 1, 0, 0, | |
0, 0, 1, 0, | |
0, 0, 0, 1}; | |
/* camera properties */ | |
const struct { | |
const float pos[3]; | |
const float to[3]; | |
const float up[3]; | |
} camera = { {2, 1, 2}, {-2, -1, -2}, {-1, 4, -1} }; | |
/* center of window */ | |
int midX = 0; | |
int midY = 0; | |
/* multiple rotation matrix (right multiplication) */ | |
void rotMultiMatrix(float delta, float x, float y, float z) | |
{ | |
float rot[16] = {}; | |
glPushMatrix(); | |
glMatrixMode(GL_MODELVIEW); | |
glLoadIdentity(); | |
glRotatef(delta, x, y, z); | |
glGetFloatv(GL_MODELVIEW_MATRIX, rot); | |
glPopMatrix(); | |
glPushMatrix(); | |
glMatrixMode(GL_MODELVIEW); | |
glLoadMatrixf(rot); | |
glMultMatrixf(rotMatrix); | |
glGetFloatv(GL_MODELVIEW_MATRIX, rotMatrix); | |
glPopMatrix(); | |
} | |
void yawing(float delta) | |
{ | |
float vec[] = {camera.up[0], camera.up[1], camera.up[2]}; | |
rotMultiMatrix(delta, vec[0], vec[1], vec[2]); | |
} | |
void rolling(float delta) | |
{ | |
float vec[] = {camera.to[0], camera.to[1], camera.to[2]}; | |
rotMultiMatrix(-delta, vec[0], vec[1], vec[2]); | |
} | |
void pitching(float delta) | |
{ | |
float vec[] = {camera.up[1] * camera.to[2] - camera.up[2] * camera.to[1], | |
camera.up[2] * camera.to[0] - camera.up[0] * camera.to[2], | |
camera.up[0] * camera.to[1] - camera.up[1] * camera.to[0]}; | |
rotMultiMatrix(delta, vec[0], vec[1], vec[2]); | |
} | |
void mouseEvent(int button, int state, int x, int y) | |
{ | |
static const int WHEEL_UP = 3; | |
static const int WHEEL_DOWN = 4; | |
if (button == WHEEL_UP && state == GLUT_DOWN) { | |
yawing(10.f); | |
} else if (button == WHEEL_DOWN && state == GLUT_DOWN) { | |
yawing(-10.f); | |
} | |
glutPostRedisplay(); | |
} | |
void displayEvent() | |
{ | |
static GLfloat diffuse[3] = {1.0f, 0.0f, 0.0f}; | |
static GLfloat ambient[3] = {0.25f, 0.25f, 0.25f}; | |
static GLfloat specular[3] = {1.0f, 1.0f, 1.0f}; | |
static GLfloat shininess[1] = {32.0f}; | |
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse); | |
glMaterialfv(GL_FRONT, GL_AMBIENT, ambient); | |
glMaterialfv(GL_FRONT, GL_SPECULAR, specular); | |
glMaterialfv(GL_FRONT, GL_SHININESS, shininess); | |
glEnable(GL_DEPTH_TEST); | |
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
glMatrixMode(GL_MODELVIEW); | |
glPushMatrix(); | |
glMultMatrixf(rotMatrix); | |
glutSolidTeapot(0.5); | |
glPopMatrix(); | |
glutSwapBuffers(); | |
} | |
void passiveMotionEvent(int x, int y) | |
{ | |
int movementX = midX - x; | |
int movementY = midY - y; | |
if (movementX == 0 && movementY == 0) { | |
return; | |
} | |
rolling(movementX * 0.05f); | |
pitching(movementY * 0.05f); | |
glutWarpPointer(midX, midY); | |
glutPostRedisplay(); | |
} | |
void keyEvent(unsigned char key, int x, int y) | |
{ | |
switch( key ) | |
{ | |
case '\033': | |
case 'q': | |
exit( 0 ); | |
break; | |
} | |
} | |
void reshapeEvent(int width, int height) | |
{ | |
midX = width / 2; | |
midY = height / 2; | |
static float lightPosition[4] = {0.25f, 1.0f, 0.25f, 0.0f}; | |
static float lightDiffuse[3] = {1.0f, 1.0f, 1.0f}; | |
static float lightAmbient[3] = {0.25f, 0.25f, 0.25f}; | |
static float lightSpecular[3] = {1.0f, 1.0f, 1.0f}; | |
glEnable(GL_LIGHTING); | |
glEnable(GL_LIGHT0); | |
glShadeModel(GL_SMOOTH); | |
glViewport(0, 0, width, height); | |
glMatrixMode(GL_PROJECTION); | |
glLoadIdentity(); | |
gluPerspective(45.0, (double)width / (double)height, 0.1, 100.0); | |
gluLookAt(camera.pos[0], camera.pos[1], camera.pos[2], | |
camera.to[0], camera.to[1], camera.to[2], | |
camera.up[0], camera.up[1], camera.up[2]); | |
glMatrixMode(GL_MODELVIEW); | |
glLoadIdentity(); | |
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); | |
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse); | |
glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient); | |
glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpecular); | |
} | |
int main(int argc, char *argv[]) | |
{ | |
glutInit(&argc, argv); | |
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE); | |
glutInitWindowSize(640, 480); | |
glutInitWindowPosition(0, 0); | |
glutCreateWindow("SlimBlade GL"); | |
glutSetCursor(GLUT_CURSOR_NONE); | |
glutReshapeFunc(reshapeEvent); | |
glutDisplayFunc(displayEvent); | |
glutKeyboardFunc(keyEvent); | |
glutMouseFunc(mouseEvent); | |
glutPassiveMotionFunc(passiveMotionEvent); | |
glutMainLoop(); | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment