c++ opengl实现第一人称视角变换(地面)

2024-08-02  本文已影响0人  一路向后

1.概述

在opengl的坐标系中, 正前方为z轴, 头顶方向为y轴, 双手展开为x轴。gluLookAt函数有9个参数, 前三个为眼睛所在坐标位置,中间三个为眼睛正视位置,后面三个为头顶的方向向量.

2.源码实现

#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <cmath>

using namespace std;

struct EyeView {
    float z;
    float x;
    float yaw;
    float pitch;
};

EyeView g_eye;

void drawTriangle()
{
    float eye[] = {0.0, 0.0, 0.0};
    float lookat[] = {0.0, 0.0, 0.0};
    float dist = 0.0;

    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45, 1, 1, 1000);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    eye[0] = 0.0+g_eye.x;
    eye[1] = 0.0;
    eye[2] = 0.0+g_eye.z;
    lookat[0] = 0.0 + 1.0 * sin(g_eye.yaw * M_PI / 180) * cos(g_eye.pitch * M_PI / 180);
    lookat[1] = 0.0 + 1.0 * sin(g_eye.pitch * M_PI / 180);
    lookat[2] = 0.0 + 1.0 * cos(g_eye.yaw * M_PI / 180) * cos(g_eye.pitch * M_PI / 180);

    dist = sqrt(lookat[0]*lookat[0]+lookat[1]*lookat[1]+lookat[2]*lookat[2]);

    gluLookAt(0.0+g_eye.x, 0.0, g_eye.z-1.0, g_eye.x+lookat[0], lookat[1], lookat[2], 0.0, 1.0, 0.0);

    glBegin(GL_TRIANGLES);
    glColor3f(1.0, 0.0, 0.0);
    glVertex3f(0.0, 0.0, 1.0);
    glColor3f(0.0, 1.0, 0.0);
    glVertex3f(-0.8, 0.8, 1.0);
    glColor3f(0.0, 0.0, 1.0);
    glVertex3f(0.8, 0.8, 1.0);
    glEnd();

    glutSwapBuffers();
}

void keyboardFunc(unsigned char key, int x, int y)
{
    switch(key)
    {
        case 'q':
        case 27:
            exit(0);
            break;

        case 'w':
            //左移
            g_eye.x -= 0.05;
            break;

        case 'e':
            //右移
            g_eye.x += 0.05;
            break;

        case 'a':
            //后退
            g_eye.z -= 0.05;
            break;

        case 's':
            //前进
            g_eye.z += 0.05;
            break;

        case 'd':
            //左转
            g_eye.yaw -= 3; 
            break;

        case 'f':
            //右转
            g_eye.yaw += 3;
            break;

        case 'z':
            //抬头
            g_eye.pitch -= 3; 
            break;

        case 'x':
            //低头
            g_eye.pitch += 3;
            break;

    }

    glutPostRedisplay();
}

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(400, 400);
    glutCreateWindow("hello");

    g_eye.x = 0.0;
    g_eye.z = 0.0;
    g_eye.yaw = 0.0;
    g_eye.pitch = 0.0;

    glutKeyboardFunc(keyboardFunc);
    glutDisplayFunc(&drawTriangle);
    glutMainLoop();

    return 0;
}

3.编译源码

$ g++ -o example example.cpp -std=c++11 -I/opt/apps/wxwidget/include -L/opt/apps/wxwidget/lib -lGL -lGLU -lglut -Wl,-rpath=/opt/apps/wxwidget/lib

4.运行结果

屏幕截图 2024-08-03 150142.png
上一篇下一篇

猜你喜欢

热点阅读