📄 stereo.cpp
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <glut.h>
/*
Demonstration OpenGL stereo application
*/
typedef struct {
double x,y,z;
} XYZ;
typedef struct {
double r,g,b;
} COLOUR;
typedef struct {
unsigned char r,g,b,a;
} PIXELA;
typedef struct {
XYZ vp; /* View position */
XYZ vd; /* View direction vector */
XYZ vu; /* View up direction */
XYZ pr; /* Point to rotate about */
double focallength; /* Focal Length along vd */
double aperture; /* Camera aperture */
double eyesep; /* Eye separation */
int screenwidth,screenheight;
} CAMERA;
void Display(void);
void CreateEnvironment(void);
void MakeGeometry(void);
void MakeLighting(void);
void HandleKeyboard(unsigned char key,int x, int y);
void HandleSpecialKeyboard(int key,int x, int y);
void HandleMouse(int,int,int,int);
void HandleMainMenu(int);
void HandleSpeedMenu(int);
void HandleSpinMenu(int);
void HandleVisibility(int vis);
void HandleReshape(int,int);
void HandleMouseMotion(int,int);
void HandlePassiveMotion(int,int);
void HandleIdle(void);
void GiveUsage(char *);
void RotateCamera(int,int,int);
void TranslateCamera(int,int);
void CameraHome(int);
void Normalise(XYZ *);
XYZ CalcNormal(XYZ,XYZ,XYZ);
int WindowDump(int,int,int);
#define ABS(x) (x < 0 ? -(x) : (x))
#define MIN(x,y) (x < y ? x : y)
#define MAX(x,y) (x > y ? x : y)
#define TRUE 1
#define FALSE 0
#define ESC 27
#define PI 3.141592653589793238462643
#define DTOR 0.0174532925
#define RTOD 57.2957795
#define CROSSPROD(p1,p2,p3) \
p3.x = p1.y*p2.z - p1.z*p2.y; \
p3.y = p1.z*p2.x - p1.x*p2.z; \
p3.z = p1.x*p2.y - p1.y*p2.x
/* Flags */
int fullscreen = FALSE;
int stereo = FALSE;
int showconstruct = FALSE;
int windowdump = FALSE;
int record = FALSE;
int debug = FALSE;
int currentbutton = -1;
double rotatespeed = 1;
double dtheta = 1;
CAMERA camera;
XYZ origin = {0.0,0.0,0.0};
double rotateangle = 0.0; /* Pulsar Rotation angle */
int main(int argc,char **argv)
{
int i;
int mainmenu,speedmenu,spinmenu;
camera.screenwidth = 800;
camera.screenheight = 600;
/* Parse the command line arguments */
for (i=1;i<argc;i++) {
if (strstr(argv[i],"-h") != NULL)
GiveUsage(argv[0]);
if (strstr(argv[i],"-f") != NULL)
fullscreen = TRUE;
if (strstr(argv[i],"-s") != NULL)
stereo = TRUE;
if (strstr(argv[i],"-d") != NULL)
debug = TRUE;
if (strstr(argv[i],"-c") != NULL)
showconstruct = TRUE;
}
stereo = TRUE;
fullscreen = TRUE;
/* Set things up and go */
glutInit(&argc,argv);
if (!stereo)
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
else
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_STEREO);
glutCreateWindow("Pulsar model");
glutReshapeWindow(800,600);
if (fullscreen)
glutFullScreen();
glutDisplayFunc(Display);
glutReshapeFunc(HandleReshape);
glutVisibilityFunc(HandleVisibility);
glutKeyboardFunc(HandleKeyboard);
glutSpecialFunc(HandleSpecialKeyboard);
glutMouseFunc(HandleMouse);
glutMotionFunc(HandleMouseMotion);
glutSetCursor(GLUT_CURSOR_NONE);
CreateEnvironment();
CameraHome(0);
/* Set up the speed menu */
speedmenu = glutCreateMenu(HandleSpeedMenu);
glutAddMenuEntry("Stop",1);
glutAddMenuEntry("Slow",2);
glutAddMenuEntry("Medium",3);
glutAddMenuEntry("Fast",4);
glutAddMenuEntry("Very fast",5);
/* Set up the spin menu */
spinmenu = glutCreateMenu(HandleSpinMenu);
glutAddMenuEntry("1 degree",1);
glutAddMenuEntry("2 degrees",2);
glutAddMenuEntry("3 degrees",3);
glutAddMenuEntry("5 degrees",4);
/* Set up the main menu */
mainmenu = glutCreateMenu(HandleMainMenu);
glutAddSubMenu("Rotation",speedmenu);
glutAddSubMenu("Camera rotation steps",spinmenu);
glutAddMenuEntry("Toggle construction lines",1);
glutAddMenuEntry("Quit",9);
glutAttachMenu(GLUT_RIGHT_BUTTON);
/* Ready to go! */
glutMainLoop();
return(0);
}
/*
This is where global OpenGL/GLUT settings are made,
that is, things that will not change in time
*/
void CreateEnvironment(void)
{
glEnable(GL_DEPTH_TEST);
glDisable(GL_LINE_SMOOTH);
glDisable(GL_POINT_SMOOTH);
glEnable(GL_POLYGON_SMOOTH);
glShadeModel(GL_SMOOTH);
glDisable(GL_DITHER);
glDisable(GL_CULL_FACE);
glLineWidth(1.0);
glPointSize(1.0);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
glFrontFace(GL_CW);
glClearColor(0.0,0.0,0.0,0.0); /* Background colour */
glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
}
/*
This is the basic display callback routine
It creates the geometry, lighting, and viewing position
In this case it rotates the camera around the scene
*/
void Display(void)
{
XYZ r;
double dist,ratio,radians,scale,wd2,ndfl;
double left,right,top,bottom,near1=0.1,far1=10000;
/* Clip to avoid extreme stereo */
if (stereo)
near1 = camera.focallength / 5;
/* Misc stuff */
ratio = camera.screenwidth / (double)camera.screenheight;
radians = DTOR * camera.aperture / 2;
wd2 = near1 * tan(radians);
ndfl = near1 / camera.focallength;
if (stereo) {
/* Derive the two eye positions */
CROSSPROD(camera.vd,camera.vu,r);
Normalise(&r);
r.x *= camera.eyesep / 2.0;
r.y *= camera.eyesep / 2.0;
r.z *= camera.eyesep / 2.0;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
left = - ratio * wd2 - 0.5 * camera.eyesep * ndfl;
right = ratio * wd2 - 0.5 * camera.eyesep * ndfl;
top = wd2;
bottom = - wd2;
glFrustum(left,right,bottom,top,near1,far1);
glMatrixMode(GL_MODELVIEW);
glDrawBuffer(GL_BACK_RIGHT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(camera.vp.x + r.x,camera.vp.y + r.y,camera.vp.z + r.z,
camera.vp.x + r.x + camera.vd.x,
camera.vp.y + r.y + camera.vd.y,
camera.vp.z + r.z + camera.vd.z,
camera.vu.x,camera.vu.y,camera.vu.z);
MakeLighting();
MakeGeometry();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
left = - ratio * wd2 + 0.5 * camera.eyesep * ndfl;
right = ratio * wd2 + 0.5 * camera.eyesep * ndfl;
top = wd2;
bottom = - wd2;
glFrustum(left,right,bottom,top,near1,far1);
glMatrixMode(GL_MODELVIEW);
glDrawBuffer(GL_BACK_LEFT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(camera.vp.x - r.x,camera.vp.y - r.y,camera.vp.z - r.z,
camera.vp.x - r.x + camera.vd.x,
camera.vp.y - r.y + camera.vd.y,
camera.vp.z - r.z + camera.vd.z,
camera.vu.x,camera.vu.y,camera.vu.z);
MakeLighting();
MakeGeometry();
} else {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
left = - ratio * wd2;
right = ratio * wd2;
top = wd2;
bottom = - wd2;
glFrustum(left,right,bottom,top,near1,far1);
glMatrixMode(GL_MODELVIEW);
glDrawBuffer(GL_BACK);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(camera.vp.x,camera.vp.y,camera.vp.z,
camera.vp.x + camera.vd.x,
camera.vp.y + camera.vd.y,
camera.vp.z + camera.vd.z,
camera.vu.x,camera.vu.y,camera.vu.z);
MakeLighting();
MakeGeometry();
}
/* glFlush(); This isn't necessary for double buffers */
glutSwapBuffers();
if (record || windowdump)
WindowDump(camera.screenwidth,camera.screenheight,stereo);
/* Next angle for rotating the pulsar */
rotateangle += rotatespeed;
}
/*
Create the geometry for the pulsar
*/
void MakeGeometry(void)
{
int i,j,k;
double cradius = 5.3; /* Final radius of the cone */
double clength = 30; /* Cone length */
double sradius = 10; /* Final radius of sphere */
double r1,r2; /* Min and Max radius of field lines */
double x,y,z;
XYZ p[4],n[4];
COLOUR grey = {0.7,0.7,0.7};
COLOUR white = {1.0,1.0,1.0};
GLfloat specular[4] = {1.0,1.0,1.0,1.0};
GLfloat shiny[1] = {5.0};
char cmd[64];
glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,specular);
glMaterialfv(GL_FRONT_AND_BACK,GL_SHININESS,shiny);
/*
/* Top level rotation - spin */
glPushMatrix();
glRotatef(rotateangle,0.0,1.0,0.0);
/* Axis of rotation */
if (showconstruct) {
glColor3f(white.r,white.g,white.b);
glBegin(GL_LINES);
glVertex3f(0.0,-60.0,0.0);
glVertex3f(0.0,60.0,0.0);
glEnd();
}
/* Rotation about spin axis */
glPushMatrix();
glRotatef(45.0,0.0,0.0,1.0);
/* Magnetic axis */
if (showconstruct) {
glColor3f(white.r,white.g,white.b);
glBegin(GL_LINES);
glVertex3f(0.0,-60.0,0.0);
glVertex3f(0.0,60.0,0.0);
glEnd();
}
/* Light in center */
glColor3f(white.r,white.g,white.b);
glutSolidSphere(5.0,16,8);
/* Spherical center */
for (i=0;i<360;i+=5) {
for (j=-80;j<80;j+=5) {
p[0].x = sradius * cos(j*DTOR) * cos(i*DTOR);
p[0].y = sradius * sin(j*DTOR);
p[0].z = sradius * cos(j*DTOR) * sin(i*DTOR);
n[0] = p[0];
p[1].x = sradius * cos((j+5)*DTOR) * cos(i*DTOR);
p[1].y = sradius * sin((j+5)*DTOR);
p[1].z = sradius * cos((j+5)*DTOR) * sin(i*DTOR);
n[1] = p[1];
p[2].x = sradius * cos((j+5)*DTOR) * cos((i+5)*DTOR);
p[2].y = sradius * sin((j+5)*DTOR);
p[2].z = sradius * cos((j+5)*DTOR) * sin((i+5)*DTOR);
n[2] = p[2];
p[3].x = sradius * cos(j*DTOR) * cos((i+5)*DTOR);
p[3].y = sradius * sin(j*DTOR);
p[3].z = sradius * cos(j*DTOR) * sin((i+5)*DTOR);
n[3] = p[3];
glBegin(GL_POLYGON);
if (i % 20 == 0)
glColor3f(1.0,0.0,0.0);
else
glColor3f(0.5,0.0,0.0);
for (k=0;k<4;k++) {
glNormal3f(n[k].x,n[k].y,n[k].z);
glVertex3f(p[k].x,p[k].y,p[k].z);
}
glEnd();
}
}
/* Draw the cones */
for (j=-1;j<=1;j+=2) {
for (i=0;i<360;i+=10) {
p[0] = origin;
n[0] = p[0];
n[0].y = -1;
p[1].x = cradius * cos(i*DTOR);
p[1].y = j*clength;
p[1].z = cradius * sin(i*DTOR);
n[1] = p[1];
n[1].y = 0;
p[2].x = cradius * cos((i+10)*DTOR);
p[2].y = j*clength;
p[2].z = cradius * sin((i+10)*DTOR);
n[2] = p[2];
n[2].y = 0;
glBegin(GL_POLYGON);
if (i % 30 == 0)
glColor3f(0.0,0.2,0.0);
else
glColor3f(0.0,0.5,0.0);
for (k=0;k<3;k++) {
glNormal3f(n[k].x,n[k].y,n[k].z);
glVertex3f(p[k].x,p[k].y,p[k].z);
}
glEnd();
}
}
/* Draw the field lines */
r1 = 12;
r2 = 16;
for (j=0;j<360;j+=20) {
glPushMatrix();
glRotatef((double)j,0.0,1.0,0.0);
glBegin(GL_LINE_STRIP);
glColor3f(grey.r,grey.g,grey.b);
for (i=-140;i<140;i++) {
x = r1 + r1 * cos(i*DTOR);
y = r2 * sin(i*DTOR);
z = 0;
glVertex3f(x,y,z);
}
glEnd();
glPopMatrix();
}
glPopMatrix(); /* Pulsar axis rotation */
glPopMatrix(); /* Pulsar spin */
}
/*
Set up the lighing environment
*/
void MakeLighting(void)
{
GLfloat fullambient[4] = {1.0,1.0,1.0,1.0};
GLfloat position[4] = {0.0,0.0,0.0,0.0};
GLfloat ambient[4] = {0.2,0.2,0.2,1.0};
GLfloat diffuse[4] = {1.0,1.0,1.0,1.0};
GLfloat specular[4] = {0.0,0.0,0.0,1.0};
/* Turn off all the lights */
glDisable(GL_LIGHT0);
glDisable(GL_LIGHT1);
glDisable(GL_LIGHT2);
glDisable(GL_LIGHT3);
glDisable(GL_LIGHT4);
glDisable(GL_LIGHT5);
glDisable(GL_LIGHT6);
glDisable(GL_LIGHT7);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER,GL_TRUE);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_FALSE);
/* Turn on the appropriate lights */
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,fullambient);
glLightfv(GL_LIGHT0,GL_POSITION,position);
glLightfv(GL_LIGHT0,GL_AMBIENT,ambient);
glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuse);
glLightfv(GL_LIGHT0,GL_SPECULAR,specular);
glEnable(GL_LIGHT0);
/* Sort out the shading algorithm */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -