📄 stereo.cpp
字号:
glShadeModel(GL_SMOOTH);
/* Turn lighting on */
glEnable(GL_LIGHTING);
}
/*
Deal with plain key strokes
*/
void HandleKeyboard(unsigned char key,int x, int y)
{
switch (key) {
case ESC: /* Quit */
case 'Q':
case 'q':
exit(0);
break;
case 'c': /* Toggle constructs */
case 'C':
showconstruct = !showconstruct;
break;
case 'h': /* Go home */
case 'H':
CameraHome(0);
break;
case '[': /* Roll anti clockwise */
RotateCamera(0,0,-1);
break;
case ']': /* Roll clockwise */
RotateCamera(0,0,1);
break;
case 'i': /* Translate camera up */
case 'I':
TranslateCamera(0,1);
break;
case 'k': /* Translate camera down */
case 'K':
TranslateCamera(0,-1);
break;
case 'j': /* Translate camera left */
case 'J':
TranslateCamera(-1,0);
break;
case 'l': /* Translate camera right */
case 'L':
TranslateCamera(1,0);
break;
case 'w': /* Write the image to disk */
case 'W':
windowdump = !windowdump;
break;
case 'r':
case 'R':
record = !record;
break;
}
}
/*
Deal with special key strokes
*/
void HandleSpecialKeyboard(int key,int x, int y)
{
switch (key) {
case GLUT_KEY_LEFT:
RotateCamera(-1,0,0);
break;
case GLUT_KEY_RIGHT:
RotateCamera(1,0,0);
break;
case GLUT_KEY_UP:
RotateCamera(0,1,0);
break;
case GLUT_KEY_DOWN:
RotateCamera(0,-1,0);
break;
}
}
/*
Rotate (ix,iy) or roll (iz) the camera about the focal point
ix,iy,iz are flags, 0 do nothing, +- 1 rotates in opposite directions
Correctly updating all camera attributes
*/
void RotateCamera(int ix,int iy,int iz)
{
XYZ vp,vu,vd;
XYZ right;
XYZ newvp,newr;
double radius,dd,radians;
double dx,dy,dz;
vu = camera.vu;
Normalise(&vu);
vp = camera.vp;
vd = camera.vd;
Normalise(&vd);
CROSSPROD(vd,vu,right);
Normalise(&right);
radians = dtheta * PI / 180.0;
/* Handle the roll */
if (iz != 0) {
camera.vu.x += iz * right.x * radians;
camera.vu.y += iz * right.y * radians;
camera.vu.z += iz * right.z * radians;
Normalise(&camera.vu);
return;
}
/* Distance from the rotate point */
dx = camera.vp.x - camera.pr.x;
dy = camera.vp.y - camera.pr.y;
dz = camera.vp.z - camera.pr.z;
radius = sqrt(dx*dx + dy*dy + dz*dz);
/* Determine the new view point */
dd = radius * radians;
newvp.x = vp.x + dd * ix * right.x + dd * iy * vu.x - camera.pr.x;
newvp.y = vp.y + dd * ix * right.y + dd * iy * vu.y - camera.pr.y;
newvp.z = vp.z + dd * ix * right.z + dd * iy * vu.z - camera.pr.z;
Normalise(&newvp);
camera.vp.x = camera.pr.x + radius * newvp.x;
camera.vp.y = camera.pr.y + radius * newvp.y;
camera.vp.z = camera.pr.z + radius * newvp.z;
/* Determine the new right vector */
newr.x = camera.vp.x + right.x - camera.pr.x;
newr.y = camera.vp.y + right.y - camera.pr.y;
newr.z = camera.vp.z + right.z - camera.pr.z;
Normalise(&newr);
newr.x = camera.pr.x + radius * newr.x - camera.vp.x;
newr.y = camera.pr.y + radius * newr.y - camera.vp.y;
newr.z = camera.pr.z + radius * newr.z - camera.vp.z;
camera.vd.x = camera.pr.x - camera.vp.x;
camera.vd.y = camera.pr.y - camera.vp.y;
camera.vd.z = camera.pr.z - camera.vp.z;
Normalise(&camera.vd);
/* Determine the new up vector */
CROSSPROD(newr,camera.vd,camera.vu);
Normalise(&camera.vu);
if (debug)
fprintf(stderr,"Camera position: (%g,%g,%g)\n",
camera.vp.x,camera.vp.y,camera.vp.z);
}
/*
Translate (pan) the camera view point
In response to i,j,k,l keys
Also move the camera rotate location in parallel
*/
void TranslateCamera(int ix,int iy)
{
XYZ vp,vu,vd;
XYZ right;
XYZ newvp,newr;
double radians,delta;
vu = camera.vu;
Normalise(&vu);
vp = camera.vp;
vd = camera.vd;
Normalise(&vd);
CROSSPROD(vd,vu,right);
Normalise(&right);
radians = dtheta * PI / 180.0;
delta = dtheta * camera.focallength / 90.0;
camera.vp.x += iy * vu.x * delta;
camera.vp.y += iy * vu.y * delta;
camera.vp.z += iy * vu.z * delta;
camera.pr.x += iy * vu.x * delta;
camera.pr.y += iy * vu.y * delta;
camera.pr.z += iy * vu.z * delta;
camera.vp.x += ix * right.x * delta;
camera.vp.y += ix * right.y * delta;
camera.vp.z += ix * right.z * delta;
camera.pr.x += ix * right.x * delta;
camera.pr.y += ix * right.y * delta;
camera.pr.z += ix * right.z * delta;
}
/*
Handle mouse events
Right button events are passed to menu handlers
*/
void HandleMouse(int button,int state,int x,int y)
{
if (state == GLUT_DOWN) {
if (button == GLUT_LEFT_BUTTON) {
currentbutton = GLUT_LEFT_BUTTON;
} else if (button == GLUT_MIDDLE_BUTTON) {
currentbutton = GLUT_MIDDLE_BUTTON;
}
}
}
/*
Handle the main menu
*/
void HandleMainMenu(int whichone)
{
switch (whichone) {
case 1:
showconstruct = !showconstruct;
break;
case 9:
exit(0);
break;
}
}
/*
Handle the speed menu
The rotate speed is in degrees
*/
void HandleSpeedMenu(int whichone)
{
switch (whichone) {
case 1: rotatespeed = 0.0; break;
case 2: rotatespeed = 0.3; break;
case 3: rotatespeed = 1; break;
case 4: rotatespeed = 3; break;
case 5: rotatespeed = 10; break;
}
}
/*
Handle the camera spin menu
*/
void HandleSpinMenu(int whichone)
{
switch (whichone) {
case 1: dtheta = 1; break;
case 2: dtheta = 2; break;
case 3: dtheta = 3; break;
case 4: dtheta = 5; break;
}
}
/*
How to handle visibility
*/
void HandleVisibility(int visible)
{
if (visible == GLUT_VISIBLE)
glutIdleFunc(HandleIdle);
else
glutIdleFunc(NULL);
}
/*
What to do on an idle event
*/
void HandleIdle(void)
{
glutPostRedisplay();
}
/*
Handle a window reshape/resize
*/
void HandleReshape(int w,int h)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0,0,(GLsizei)w,(GLsizei)h);
camera.screenwidth = w;
camera.screenheight = h;
}
/*
Display the program usage information
*/
void GiveUsage(char *cmd)
{
fprintf(stderr,"Usage: %s [-h] [-f] [-s] [-c] [-q n]\n",cmd);
fprintf(stderr," -h this text\n");
fprintf(stderr," -f full screen\n");
fprintf(stderr," -s stereo\n");
fprintf(stderr," -c show construction lines\n");
fprintf(stderr,"Key Strokes\n");
fprintf(stderr," arrow keys rotate left/right/up/down\n");
fprintf(stderr," left mouse rotate\n");
fprintf(stderr,"middle mouse roll\n");
fprintf(stderr," c toggle construction lines\n");
fprintf(stderr," i translate up\n");
fprintf(stderr," k translate down\n");
fprintf(stderr," j translate left\n");
fprintf(stderr," l translate right\n");
fprintf(stderr," [ roll clockwise\n");
fprintf(stderr," ] roll anti clockwise\n");
fprintf(stderr," q quit\n");
exit(-1);
}
void Normalise(XYZ *p)
{
double length;
length = sqrt(p->x * p->x + p->y * p->y + p->z * p->z);
if (length != 0) {
p->x /= length;
p->y /= length;
p->z /= length;
} else {
p->x = 0;
p->y = 0;
p->z = 0;
}
}
XYZ CalcNormal(XYZ p,XYZ p1,XYZ p2)
{
XYZ n,pa,pb;
pa.x = p1.x - p.x;
pa.y = p1.y - p.y;
pa.z = p1.z - p.z;
pb.x = p2.x - p.x;
pb.y = p2.y - p.y;
pb.z = p2.z - p.z;
Normalise(&pa);
Normalise(&pb);
n.x = pa.y * pb.z - pa.z * pb.y;
n.y = pa.z * pb.x - pa.x * pb.z;
n.z = pa.x * pb.y - pa.y * pb.x;
Normalise(&n);
return(n);
}
/*
Move the camera to the home position
*/
void CameraHome(int mode)
{
camera.aperture = 50;
camera.focallength = 70;
camera.eyesep = camera.focallength / 20;
camera.pr = origin;
/*
camera.vp.x = camera.focallength;
camera.vp.y = 0;
camera.vp.z = 0;
camera.vd.x = -1;
camera.vd.y = 0;
camera.vd.z = 0;
*/
/* Special camera position so the beam crosses the view */
camera.vp.x = 39;
camera.vp.y = 53;
camera.vp.z = 22;
camera.vd.x = -camera.vp.x;
camera.vd.y = -camera.vp.y;
camera.vd.z = -camera.vp.z;
camera.vu.x = 0;
camera.vu.y = 1;
camera.vu.z = 0;
}
/*
Handle mouse motion
*/
void HandleMouseMotion(int x,int y)
{
static int xlast=-1,ylast=-1;
int dx,dy;
dx = x - xlast;
dy = y - ylast;
if (dx < 0) dx = -1;
else if (dx > 0) dx = 1;
if (dy < 0) dy = -1;
else if (dy > 0) dy = 1;
if (currentbutton == GLUT_LEFT_BUTTON)
RotateCamera(-dx,dy,0);
else if (currentbutton == GLUT_MIDDLE_BUTTON)
RotateCamera(0,0,dx);
xlast = x;
ylast = y;
}
/*
Write the current view to a PPM file
Do the right thing for stereo, ie: two images
*/
int WindowDump(int width,int height,int stereo)
{
int i,j;
FILE *fptr;
static int counter = 0;
char fname[32];
char *image;
/* Allocate our buffer for the image */
if ((image = (char*)malloc(3*width*height*sizeof(char))) == NULL) {
fprintf(stderr,"WindowDump - Failed to allocate memory for image\n");
return(FALSE);
}
/* Open the file */
sprintf(fname,"L_%04d.ppm",counter);
if ((fptr = fopen(fname,"w")) == NULL) {
fprintf(stderr,"WindowDump - Failed to open file for window dump\n");
return(FALSE);
}
/* Copy the image into our buffer */
glReadBuffer(GL_BACK_LEFT);
glReadPixels(0,0,width,height,GL_RGB,GL_UNSIGNED_BYTE,image);
/* Write the PPM file */
fprintf(fptr,"P3\n%d %d\n255\n",width,height);
for (j=height-1;j>=0;j--) {
for (i=0;i<width;i++) {
fputc(image[3*j*width+3*i+0],fptr);
fputc(image[3*j*width+3*i+1],fptr);
fputc(image[3*j*width+3*i+2],fptr);
}
}
fclose(fptr);
if (stereo) {
/* Open the file */
sprintf(fname,"R_%04d.ppm",counter);
if ((fptr = fopen(fname,"w")) == NULL) {
fprintf(stderr,"WindowDump - Failed to open file for window dump\n");
return(FALSE);
}
/* Copy the image into our buffer */
glReadBuffer(GL_BACK_RIGHT);
glReadPixels(0,0,width,height,GL_RGB,GL_UNSIGNED_BYTE,image);
/* Write the PPM file */
fprintf(fptr,"P3\n%d %d\n255\n",width,height);
for (j=height-1;j>=0;j--) {
for (i=0;i<width;i++) {
fputc(image[3*j*width+3*i+0],fptr);
fputc(image[3*j*width+3*i+1],fptr);
fputc(image[3*j*width+3*i+2],fptr);
}
}
fclose(fptr);
}
free(image);
counter++;
return(TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -