C++ 在第一人称视图和第三人称视图之间切换(OpenGL)

C++ 在第一人称视图和第三人称视图之间切换(OpenGL),c++,opengl,perspectivecamera,camera-view,C++,Opengl,Perspectivecamera,Camera View,我正在尝试实现一个简单的3D环境,让机器人可以四处走动。我希望用户能够在机器人的第一人称和第三人称视图之间切换 我已经实现了机器人,还有一个简单的区域和一些其他对象。目前,视图为第三人称。我一直在使用gluPerspective函数来尝试实现头转向时第一个人转向(已经实现了头转向),但似乎无论我使用什么参数,我都无法让切换工作。它总是保持不变。有没有比我到目前为止所尝试的更简单的方法来达到这个效果?因为我的方法,我所做的事情不起作用吗 下面的代码足以将透视图设置为第一人称,但是它并不像我所期望的

我正在尝试实现一个简单的3D环境,让机器人可以四处走动。我希望用户能够在机器人的第一人称和第三人称视图之间切换

我已经实现了机器人,还有一个简单的区域和一些其他对象。目前,视图为第三人称。我一直在使用gluPerspective函数来尝试实现头转向时第一个人转向(已经实现了头转向),但似乎无论我使用什么参数,我都无法让切换工作。它总是保持不变。有没有比我到目前为止所尝试的更简单的方法来达到这个效果?因为我的方法,我所做的事情不起作用吗

下面的代码足以将透视图设置为第一人称,但是它并不像我所期望的那样跟随图的头部。我可以在他身上初始化它,但我不知道如何让机器人随着相机移动,因为周围的风景在他周围有效地移动。我在想,我可以通过第一人称的方式移除机器人来“伪装”这一点。想法

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
double atx = xPos + cos(lookAngle);
double atz = zPos + sin(lookAngle);
double atHeight = eyeHeight + eyeIncline;
gluLookAt(xPos, eyeHeight, zPos, atx, atHeight, atz, 0.0, 1.0, 0.0);
我尝试调用键盘函数中的switch语句来切换到第三人称。键盘调用看起来像这样:

void key(unsigned char k, int x, int y)
{
if ( k == 27 ) /* Escape */
  exit(0);
else if ( k == 86 ) { /* 'v' for view change */
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   gluLookAt(0, 0, -20, 0, 0, -1, 0, 1, 0); //Look down z-axis

}
glutPostRedisplay();
}
但它不起作用。不进行切换

代码如下:

#define GLUT_DISABLE_ATEXIT_HACK

#include <GL/glut.h>
#include <GL/gl.h>
#include <math.h>

#define TORSO_HEIGHT 5.0
#define UPPER_ARM_HEIGHT 3.0
#define LOWER_ARM_HEIGHT 2.0
#define UPPER_LEG_RADIUS  0.5
#define LOWER_LEG_RADIUS  0.5
#define LOWER_LEG_HEIGHT 2.0
#define UPPER_LEG_HEIGHT 3.0
#define UPPER_LEG_RADIUS  0.5
#define TORSO_RADIUS 1.0
#define UPPER_ARM_RADIUS  0.5
#define LOWER_ARM_RADIUS  0.5
#define HEAD_HEIGHT 1.5
#define HEAD_RADIUS 1.0

double cubeX[] = { 5.0, 5.0, 5.0 };
double cubeY[] = { 3.0, 3.0, 3.0 };
double cubeZ[] = { 7.0, 5.0, 3.0 };
double cubeR[] = { 1.0, 0.0, 0.0 };
double cubeG[] = { 0.0, 1.0, 0.0 };
double cubeB[] = { 0.0, 0.0, 1.0 };

double xPos = 2.0, zPos = 5.0;
double eyeHeight = 4.5;
double eyeIncline = -0.5;
double lookAngle = 0.0; //In rads

double posIncr = 0.25;
double thetaIncr = 0.1;

typedef float point[3];

static GLfloat theta[11] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,
        180.0,0.0,180.0,0.0}; /* initial joint angles */
static GLint angle = 2;

GLUquadricObj *t, *h, *lua, *lla, *rua, *rla, *lll, *rll, *rul, *lul, *lf1, *lf2;

double size=1.0;

void torso()
{
glPushMatrix();
glRotatef(-90.0, 1.0, 0.0, 0.0);
gluCylinder(t,TORSO_RADIUS, TORSO_RADIUS, TORSO_HEIGHT,10,10);
glPopMatrix();
}

void head()
{
glPushMatrix();
glTranslatef(0.0, 0.5*HEAD_HEIGHT,0.0);
glScalef(HEAD_RADIUS, HEAD_HEIGHT, HEAD_RADIUS);
gluSphere(h,1.0,10,10);
glPopMatrix();
}

void left_upper_arm()
{
glPushMatrix();
glRotatef(-90.0, 1.0, 0.0, 0.0);
gluCylinder(lua,UPPER_ARM_RADIUS, UPPER_ARM_RADIUS, UPPER_ARM_HEIGHT,10,10);
glPopMatrix();
}

void left_lower_arm()
{
glPushMatrix();
glRotatef(-90.0, 1.0, 0.0, 0.0);
gluCylinder(lla,LOWER_ARM_RADIUS, LOWER_ARM_RADIUS, LOWER_ARM_HEIGHT,10,10);
glPopMatrix();
}

void left_finger1()
{
glPushMatrix();
glRotatef(-90.0, 1.0, 0.0, 0.0);
gluCylinder(lf1,FINGER_1_RADIUS, FINGER_1_RADIUS, FINGER_1_HEIGHT,10,10);
glPopMatrix();
}

void left_finger2()
{
glPushMatrix();
glRotatef(-90.0, 1.0, 0.0, 0.0);
gluCylinder(lla,LOWER_ARM_RADIUS, LOWER_ARM_RADIUS, LOWER_ARM_HEIGHT,10,10);
glPopMatrix();
} 

void right_upper_arm()
{
glPushMatrix();
glRotatef(-90.0, 1.0, 0.0, 0.0);
gluCylinder(rua,UPPER_ARM_RADIUS, UPPER_ARM_RADIUS, UPPER_ARM_HEIGHT,10,10);
glPopMatrix();
}

void right_lower_arm()
{
glPushMatrix();
glRotatef(-90.0, 1.0, 0.0, 0.0);
gluCylinder(rla,LOWER_ARM_RADIUS, LOWER_ARM_RADIUS, LOWER_ARM_HEIGHT,10,10);
glPopMatrix();
}

void left_upper_leg()
{
glPushMatrix();
glRotatef(-90.0, 1.0, 0.0, 0.0);
gluCylinder(lul,UPPER_LEG_RADIUS, UPPER_LEG_RADIUS, UPPER_LEG_HEIGHT,10,10);
glPopMatrix();
}

void left_lower_leg()
{
glPushMatrix();
glRotatef(-90.0, 1.0, 0.0, 0.0);
gluCylinder(lll,LOWER_LEG_RADIUS, LOWER_LEG_RADIUS, LOWER_LEG_HEIGHT,10,10);
glPopMatrix();
}

void right_upper_leg()
{
glPushMatrix();
glRotatef(-90.0, 1.0, 0.0, 0.0);
gluCylinder(rul,UPPER_LEG_RADIUS, UPPER_LEG_RADIUS, UPPER_LEG_HEIGHT,10,10);
glPopMatrix();
}

void right_lower_leg()
{
glPushMatrix();
glRotatef(-90.0, 1.0, 0.0, 0.0);
gluCylinder(rll,LOWER_LEG_RADIUS, LOWER_LEG_RADIUS, LOWER_LEG_HEIGHT,10,10);
glPopMatrix();
}

void drawCube( int i )
{
double x = cubeX[i];
double y = cubeY[i];
double z = cubeZ[i];

glColor3i(1, 0, 0); //Red cube
glPushMatrix();
glTranslatef(x,y,z);
glutSolidCube(1);
glPopMatrix();

glColor3i(0, 1, 0); //Green Cube
glPushMatrix();
glTranslatef(x,y,z);
glutSolidCube(1);
glPopMatrix();

glColor3i(0, 0, 1); //Blue Cube
glPushMatrix();
glTranslatef(x,y,z);
glutSolidCube(1);
glPopMatrix();

glColor3i(0, 1, 1);
glPushMatrix();
glTranslatef(x,y,z);
glutSolidCube(1);
glPopMatrix();

}

void drawCubes(void)
{

glLoadName(1);
drawCube(0);

glLoadName(2);
drawCube(1);

glLoadName(3);
drawCube(2);

/* Set name back to '0' to indicate background. */
glLoadName(0);
}

void drawFloor(void)
{
GLfloat mat_diffuse[] = { 0.5, 0.5, 0.5, 1.0 };
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glBegin(GL_POLYGON);
  glNormal3f(0.0, 1.0, 0.0);
  glVertex3f(-10.0, 0.0, -10.0);
  glVertex3f(10.0, 0.0, -10.0);
  glVertex3f(10.0, 0.0,  10.0);
  glVertex3f(-10.0, 0.0,  10.0);
glEnd();
}

void doDrawing(void)
{

drawCubes();

drawFloor();

/* Everything else is a lighter shade of grey. */
GLfloat mat_diffuse[] = { 0.8, 0.8, 0.8, 1.0 };
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
}

void drawEnviro(void)
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
double atx = xPos + cos(lookAngle);
double atz = zPos + sin(lookAngle);
double atHeight = eyeHeight + eyeIncline;
gluLookAt(xPos, eyeHeight, zPos, atx, atHeight, atz, 0.0, 1.0, 0.0);

glPushMatrix();
doDrawing();
glPopMatrix();
}

void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
drawEnviro();
glLoadIdentity();
gluLookAt(0, 0, -20, 0, 0, -1, 0, 1, 0);
glColor3f(0.0, 0.0, 0.0);

glRotatef(theta[0], 0.0, 1.0, 0.0);
torso();
glPushMatrix();

glTranslatef(0.0, TORSO_HEIGHT+0.5*HEAD_HEIGHT, 0.0);
glRotatef(theta[1], 1.0, 0.0, 0.0);
glRotatef(theta[2], 0.0, 1.0, 0.0);
glTranslatef(0.0, -0.5*HEAD_HEIGHT, 0.0);
head();

glPopMatrix();
glPushMatrix();
glTranslatef(-(TORSO_RADIUS + UPPER_ARM_RADIUS), 0.9 * TORSO_HEIGHT, 0.0);
glRotatef(theta[3], 1.0, 0.0, 0.0);
left_upper_arm();

glTranslatef(0.0, UPPER_ARM_HEIGHT, 0.0);
glRotatef(theta[4], 1.0, 0.0, 0.0);
left_lower_arm();

glTranslatef(0.0, LOWER_ARM_HEIGHT, 0.0);
glRotatef(theta[11], 1.0, 0.0, 0.0);
left_finger1();

glPopMatrix();
glPushMatrix();
glTranslatef(TORSO_RADIUS+UPPER_ARM_RADIUS, 0.9*TORSO_HEIGHT, 0.0);
glRotatef(theta[5], 1.0, 0.0, 0.0);
right_upper_arm();

glTranslatef(0.0, UPPER_ARM_HEIGHT, 0.0);
glRotatef(theta[6], 1.0, 0.0, 0.0);
right_lower_arm();

glPopMatrix();
glPushMatrix();
glTranslatef(-(TORSO_RADIUS+UPPER_LEG_RADIUS), 0.1*UPPER_LEG_HEIGHT, 0.0);
glRotatef(theta[7], 1.0, 0.0, 0.0);
left_upper_leg();

glTranslatef(0.0, UPPER_LEG_HEIGHT, 0.0);
glRotatef(theta[8], 1.0, 0.0, 0.0);
left_lower_leg();

glPopMatrix();
glPushMatrix();
glTranslatef(TORSO_RADIUS+UPPER_LEG_RADIUS, 0.1*UPPER_LEG_HEIGHT, 0.0);
glRotatef(theta[9], 1.0, 0.0, 0.0);
right_upper_leg();

glTranslatef(0.0, UPPER_LEG_HEIGHT, 0.0);
glRotatef(theta[10], 1.0, 0.0, 0.0);
right_lower_leg();

glPopMatrix();

glFlush();
glutSwapBuffers();
}

void setProjection(void)
{
gluPerspective(60.0, 1.0, 0.1, 100.0);
}

void mouse(int btn, int state, int x, int y)
{
  if(btn==GLUT_LEFT_BUTTON && state == GLUT_DOWN)
    {
    theta[angle] += 5.0;
    if( theta[angle] > 360.0 ) theta[angle] -= 360.0;
    }
  if(btn==GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
    {
    theta[angle] -= 5.0;
    if( theta[angle] < 360.0 ) theta[angle] += 360.0;
    }
    display();
 }

void menu(int id)
{
if (id < 11 ) angle = id;
if (id == 11 ) exit(0);
}

void specialKey(int k, int x, int y)
{
/* Accept commands to move the viewpoint. */
switch (k) {
  case GLUT_KEY_UP:
     xPos += posIncr * cos(lookAngle);
     zPos += posIncr * sin(lookAngle);
     break;
  case GLUT_KEY_DOWN:
     xPos -= posIncr * cos(lookAngle);
     zPos -= posIncr * sin(lookAngle);
     break;
  case GLUT_KEY_LEFT:
     lookAngle -= thetaIncr;
     break;
  case GLUT_KEY_RIGHT:
     lookAngle += thetaIncr;
     break;
  case GLUT_KEY_PAGE_UP:
     eyeIncline += 0.5;
     break;
  case GLUT_KEY_PAGE_DOWN:
     eyeIncline -= 0.5;
     break;
  case GLUT_KEY_HOME:
     eyeHeight += 0.5;
     break;
  case GLUT_KEY_END:
     eyeHeight -= 0.5;
     break;
  default:
     return;
  }
  glutPostRedisplay();
 }

void reshape(int w, int h) 
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective (65.0, w/h, 1, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

void init()
{
    GLfloat mat_specular[]={1.0, 1.0, 1.0, 1.0};
    GLfloat mat_diffuse[]={1.0, 1.0, 1.0, 1.0};
    GLfloat mat_ambient[]={1.0, 1.0, 1.0, 1.0};
    GLfloat mat_shininess={100.0};
    GLfloat light_ambient[]={0.0, 0.0, 0.0, 1.0};
    GLfloat light_diffuse[]={1.0, 1.0, 1.0, 1.0};
    GLfloat light_specular[]={1.0, 1.0, 1.0, 1.0};
    GLfloat light_position[]={10.0, 10.0, 10.0, 0.0};

    glLightfv(GL_LIGHT0, GL_POSITION, light_position);
    glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
    glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);

    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
    glMaterialf(GL_FRONT, GL_SHININESS, mat_shininess);

    glShadeModel(GL_SMOOTH);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glDepthFunc(GL_LEQUAL);
    glEnable(GL_DEPTH_TEST);

    glClearColor(0.0, 0.0, 0.0, 0.0);
    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();
    setProjection();

    //Fill the body parts of the robot
    h=gluNewQuadric();
    gluQuadricDrawStyle(h, GLU_FILL);
    t=gluNewQuadric();
    gluQuadricDrawStyle(t, GLU_FILL);
    lua=gluNewQuadric();
    gluQuadricDrawStyle(lua, GLU_FILL);
    lla=gluNewQuadric();
    gluQuadricDrawStyle(lla, GLU_FILL);
    rua=gluNewQuadric();
    gluQuadricDrawStyle(rua, GLU_FILL);
    rla=gluNewQuadric();
    gluQuadricDrawStyle(rla, GLU_FILL);
    lul=gluNewQuadric();
    gluQuadricDrawStyle(lul, GLU_FILL);
    lll=gluNewQuadric();
    gluQuadricDrawStyle(lll, GLU_FILL);
    rul=gluNewQuadric();
    gluQuadricDrawStyle(rul, GLU_FILL);
    rll=gluNewQuadric();
    gluQuadricDrawStyle(rll, GLU_FILL);
    lf1=gluNewQuadric();
    gluQuadricDrawStyle(lf1, GLU_FILL);

 }

int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500, 500);
glutCreateWindow("robot");
init();
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutSpecialFunc(specialKey);

glutCreateMenu(menu);
glutAddMenuEntry("torso", 0);
glutAddMenuEntry("head1", 1);
glutAddMenuEntry("head2", 2);
glutAddMenuEntry("right_upper_arm", 3);
glutAddMenuEntry("right_lower_arm", 4);
glutAddMenuEntry("left_upper_arm", 5);
glutAddMenuEntry("left_lower_arm", 6);
glutAddMenuEntry("right_upper_leg", 7);
glutAddMenuEntry("right_lower_leg", 8);
glutAddMenuEntry("left_upper_leg", 9);
glutAddMenuEntry("left_lower_leg", 10);
glutAddMenuEntry("quit", 11);
glutAttachMenu(GLUT_MIDDLE_BUTTON);

glutMainLoop();

return 0;
}
#定义过剩、禁用、退出
#包括
#包括
#包括
#定义躯干高度5.0
#定义上臂高度3.0
#定义下臂高度2.0
#定义上支腿半径0.5
#定义下支腿半径0.5
#定义下支腿高度2.0
#定义上肢高度3.0
#定义上支腿半径0.5
#将躯干半径定义为1.0
#定义上臂半径0.5
#定义下臂半径0.5
#定义头部高度1.5
#将头部半径定义为1.0
双立方[]={5.0,5.0,5.0};
双立方[]={3.0,3.0,3.0};
双立方[]={7.0,5.0,3.0};
双立方[]={1.0,0.0,0.0};
双立方[]={0.0,1.0,0.0};
双立方B[]={0.0,0.0,1.0};
双xPos=2.0,zPos=5.0;
双眼高度=4.5;
双眼倾斜=-0.5;
双视角=0.0//在拉德
双posIncr=0.25;
双倍温度=0.1;
typedef浮点值[3];
静态GLfloatθ[11]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,
180.0,0.0,180.0,0.0}; /* 初始接合角*/
静态闪烁角=2;
GLUquadricObj*t、*h、*lua、*lla、*rua、*rla、*lll、*rll、*rul、*lul、*lf1、*lf2;
双尺寸=1.0;
空躯干()
{
glPushMatrix();
glRotatef(-90.0,1.0,0.0,0.0);
胶合圆柱体(t,躯干半径,躯干半径,躯干高度,10,10);
glPopMatrix();
}
空头()
{
glPushMatrix();
GLTRANSTEF(0.0,0.5*头部高度,0.0);
glScalef(头部半径、头部高度、头部半径);
胶球(h,1.0,10,10);
glPopMatrix();
}
无效左上臂()
{
glPushMatrix();
glRotatef(-90.0,1.0,0.0,0.0);
gluCylinder(lua,上臂半径,上臂半径,上臂高度,10,10);
glPopMatrix();
}
无效左下臂()
{
glPushMatrix();
glRotatef(-90.0,1.0,0.0,0.0);
gluCylinder(lla,下焊臂半径,下焊臂半径,下焊臂高度,10,10);
glPopMatrix();
}
void left_finger1()
{
glPushMatrix();
glRotatef(-90.0,1.0,0.0,0.0);
胶合圆柱(lf1,指状半径,指状半径,指状高度,10,10);
glPopMatrix();
}
void left_finger2()
{
glPushMatrix();
glRotatef(-90.0,1.0,0.0,0.0);
gluCylinder(lla,下焊臂半径,下焊臂半径,下焊臂高度,10,10);
glPopMatrix();
} 
无效右上臂()
{
glPushMatrix();
glRotatef(-90.0,1.0,0.0,0.0);
gluCylinder(rua,上臂半径,上臂半径,上臂高度,10,10);
glPopMatrix();
}
无效右下臂()
{
glPushMatrix();
glRotatef(-90.0,1.0,0.0,0.0);
gluCylinder(rla,下焊臂半径,下焊臂半径,下焊臂高度,10,10);
glPopMatrix();
}
无效左上肢()
{
glPushMatrix();
glRotatef(-90.0,1.0,0.0,0.0);
gluCylinder(lul,上支腿半径,上支腿半径,上支腿高度,10,10);
glPopMatrix();
}
无效左下肢()
{
glPushMatrix();
glRotatef(-90.0,1.0,0.0,0.0);
胶合圆柱(lll,下焊脚半径,下焊脚半径,下焊脚高度,10,10);
glPopMatrix();
}
无效右上肢()
{
glPushMatrix();
glRotatef(-90.0,1.0,0.0,0.0);
胶合圆柱(rul,上焊脚半径,上焊脚半径,上焊脚高度,10,10);
glPopMatrix();
}
无效右下肢()
{
glPushMatrix();
glRotatef(-90.0,1.0,0.0,0.0);
胶合圆柱(rll,下焊脚半径,下焊脚半径,下焊脚高度,10,10);
glPopMatrix();
}
虚空多维数据集(int i)
{
双x=cubeX[i];
双y=立方[i];
双z=cubeZ[i];
glColor3i(1,0,0);//红色立方体
glPushMatrix();
glTranslatef(x,y,z);
立体立方体(1);
glPopMatrix();
glColor3i(0,1,0);//绿色立方体
glPushMatrix();
glTranslatef(x,y,z);
立体立方体(1);
glPopMatrix();
glColor3i(0,0,1);//蓝色立方体
glPushMatrix();
glTranslatef(x,y,z);
立体立方体(1);
glPopMatrix();
gl3i(0,1,1);
glPushMatrix();
glTranslatef(x,y,z);
立体立方体(1);
glPopMatrix();
}
空心立方体(空心)
{
glLoadName(1);
drawCube(0);
glLoadName(2);
拉丝方块(1);
glLoadName(3);
拉丝方块(2);
/*将名称设置回“0”以指示背景*/
glLoadName(0);
}
抽油池(抽油池)
{
GLfloat mat_diffuse[]={0.5,0.5,0.5,1.0};
GLMATERIALV(GL_前部、GL_漫反射、mat_漫反射);
glBegin(GL_多边形);
glNormal3f(0.0,1.0,0.0);
glVertex3f(-10.0,0.0,-10.0);
glVertex3f(10.0,0.0,-10.0);
glVertex3f(10.0,0.0,10.0);
glVertex3f(-10.0,0.0,10.0);
格伦德();
}
无效绘制(无效)
{
drawCubes();
钻台();
/*其他一切都是浅灰色*/
GLfloat mat_diffuse[]={0.8,0.8,0.8,1.0};
GLMATERIALV(GL_前部、GL_漫反射、mat_漫反射);
}
付款人无效(无效)
{
glMatrixMode(GLU模型视图);
glLoadIdentity();
双atx=xPos+cos(视角);
双atz=zPos+sin(视角);
双目视觉=眼睛高度+眼睛倾斜;
gluLookAt(xPos、眼高、zPos、atx、atHeight、atz、0.0、1.0、0.0);
glPushMatrix();
doDrawing();
glPopMatrix();
}
作废显示(作废)
{
glClear(GL_颜色_缓冲_位| GL_深度_缓冲_位);
抽屉式();
glLoadIdentity();
gluLookAt(0,0,-20,0,0,-1,0,1,0);
GL3F(0.0,0.0,0.0);
德国劳埃德船级社