首页 > 解决方案 > 在 opengl/glut 中使用 gluLookAt 和鼠标改变视角

问题描述

您好,所以我正在尝试使用鼠标功能将 gluLookAt 的视角移动到没有运气到目前为止我试图根据鼠标位置调整 upX 和 upY 但是我希望程序能够进行整个 360 度旋转对象基于鼠标移动,并希望它在窗口中的鼠标移动停止时停止。任何帮助将不胜感激我仍在学习

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

float posX=4, posY=6, posZ=5, targetX=0, targetY=0, targetZ=0, upX=0, upY=1, upZ=0;

void display() {
    glClear(GL_COLOR_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60.0, 4.0/3.0, 1, 40);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    gluLookAt(posX, posY, posZ, targetX, targetY, targetZ, upX, upY, upZ);  

    glColor3f(1.0, 1.0, 1.0);
    glutWireTeapot(1.5);

    glBegin(GL_LINES);
      glColor3f(1, 0, 0); glVertex3f(0, 0, 0); glVertex3f(10, 0, 0);
      glColor3f(0, 1, 0); glVertex3f(0, 0, 0); glVertex3f(0, 10, 0);
      glColor3f(0, 0, 1); glVertex3f(0, 0, 0); glVertex3f(0, 0, 10);
    glEnd();

    glFlush();
}

void usage(){
    std::cout<< "\n\n\
          q,Q: Quit\n\n" ;
          std::cout.flush();
}

void onMouseMove(int x, int y)
{
    posX = x*cos(posY) + PosY*sin(PosX)*sin(yRot) - dz*cos(xRot)*sin(yRot) 
    glutPostRedisplay();
}

void KeyboardFunc (unsigned char key, int eyeX, int eyeY)
{
    switch (key)
    {
       case 'q':
       case 'Q':
           exit(0);
           break;
    }
    glutPostRedisplay();
}

void init() 
{
    glClearColor(0.0, 0.0, 0.0, 1.0);
    glColor3f(1.0, 1.0, 1.0);
    usage();
}

int main(int argc, char** argv) 
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowPosition(300,250);
    glutInitWindowSize(800, 600);
    glutCreateWindow("Final");
    init();
    glutDisplayFunc(display);
    glutPassiveMotionFunc(&onMouseMove);
    glutKeyboardFunc(&KeyboardFunc); 
    glutMainLoop();
}

标签: c++openglglut

解决方案


如果您想实现一个轨迹球相机,并且您想使用固定功能管道矩阵堆栈来实现它,那么实际上不使用gluLookAt()but会更简单glRotate/glTranslate,如下所示:

glTranslatef(0f, 0f, -radius);
glRotatef(angX, 1f, 0f, 0f);
glRotatef(angY, 0f, 1f, 0f);
glTranslatef(-targetX, -targetY, -targetZ);

其中radius是“相机”到观察点的距离,angX是围绕 X 轴angY的角度,围绕 Y 轴的角度,(targetX, targetY, targetZ)是观察点的位置(您的targetX/Y/Z)。

您不必sin/cos自己计算(它由 计算glRotatef),您所要做的就是设置/增加angXangY在您的运动功能中。


推荐阅读