如何让 C++ OpenGL Camera 向左和向右看?

问题描述 投票:0回答:1

在这个项目中,我制作了一个 3d 立方体并添加了一个相机。我们可以使用 W、A、S、D 键前进、后退、右转或左转,但我们不能右转或左转。比如我想看立方体的背面,但是我看不到。其实这个问题很简单,解法也很简单,但是我的数学水平不够,如果有人给我解释一下就更好了。我我会告诉你我的代码以及我在下面尝试过的内容。

#include <Windows.h>

#include <gl/GL.h>
#include <gl/GLU.h>
#include <GLFW/glfw3.h>

#include <cstdio>
#include <iostream>
#include <cmath>
#include <math.h>

int width = 1280;
int height = 720;

float camera_z = 5;
float camera_y = 0;
float camera_x = 0;

float fov = 60;

GLFWwindow* window;

float speed = 0.01;


GLfloat vertices[] = {
    -1, -1, -1,   -1, -1,  1,   -1,  1,  1,   -1,  1, -1,
    1, -1, -1,    1, -1,  1,    1,  1,  1,    1,  1, -1,
    -1, -1, -1,   -1, -1,  1,    1, -1,  1,    1, -1, -1,
    -1,  1, -1,   -1,  1,  1,    1,  1,  1,    1,  1, -1,
    -1, -1, -1,   -1,  1, -1,    1,  1, -1,    1, -1, -1,
    -1, -1,  1,   -1,  1,  1,    1,  1,  1,    1, -1,  1
};

GLfloat colors[] = {
    1, 1, 0,   1, 1, 0,   0, 1, 0,   0, 1, 0,
    1, 1, 0,   1, 1, 0,   0, 1, 0,   0, 1, 0,
    1, 1, 0,   1, 1, 0,   0, 1, 0,   0, 1, 0,
    1, 1, 0,   1, 1, 0,   0, 1, 0,   0, 1, 0,
    1, 1, 0,   0, 1, 1,   0, 1, 0,   0, 1, 0,
    1, 1, 0,   0, 1, 1,   0, 1, 0,   0, 1, 0
};



void keyboard() {

    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {

        glfwSetWindowShouldClose(window, GL_TRUE);

    }
    if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {

        camera_z = camera_z - speed;

    }
    if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {

        camera_x = camera_x - speed;

    }
    if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {

        camera_z = camera_z + speed;

    }
    if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {

        camera_x = camera_x + speed;
    }
    if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS) {

        camera_y = camera_y + speed;
    }
    if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS) {

        camera_y = camera_y - speed;
    }

    

    if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS) {

        // need help
       
    }
    if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS) {
       
        // need help
    }

   
}
       




void drawCube() {

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);

    glVertexPointer(3, GL_FLOAT, 0, vertices);
    glColorPointer(3, GL_FLOAT, 0, colors);
    
    glDrawArrays(GL_QUADS, 0, 24);

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);

}



int main(void)
{
    

    /* Initialize the library */
    if (!glfwInit())
        return -1;

    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(width, height, "C++ OpenGL ", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }

    /* Make the window's context current */
    glfwMakeContextCurrent(window);

    

    glEnable(GL_DEPTH_TEST); 

    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window))
    {
        glViewport(0, 0, width, height);

        /* Render here */
        glClearColor(0.0, 192/256, 1, 1.0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        float aspect = (float)width / (float)height;
        float fov = 60;
        gluPerspective(fov, aspect, 0.1, 1000);
        
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        keyboard();
        
                                                      
        gluLookAt(
            camera_x,
            camera_y,
            camera_z,
            camera_x + 1, // need help
            camera_y + 1, // need help
            camera_z - fov ,
            0,
            1, 
            0
        );

        glTranslatef(0, 0,-3);
        drawCube();



        glFlush();

        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}

我试过的是变量camera_eyex,*_eyey,*_eyez。我将它们添加到循环中以赋予相机 + 1 值。我以前想左转右转的时候就增减,但是这个方法有很多错误。例如,即使在我按下 W 键时相机旋转了 45 度,它也会直线移动,所以它不会转到我正在看的地方。此外,向右或向左转弯超过 90 度是不可能的。另外,当我按左键向左转时,转弯越来越慢

c++ opengl camera glfw
1个回答
1
投票

你需要建立一个变换矩阵。变换通常是平移、缩放和旋转的组合。

首先旋转,然后缩放然后平移(实际计算顺序 - 乘法 - 是相反的):

translation x scale x rotation

如果你想围绕某个点(枢轴或中心)缩放或旋转,那么你必须平移到中心点,最后平移回原点,如:

translation x center x scale x rotation x -center

lookAt 算法根据参数(眼睛、目标、向上)设置旋转和平移,而您的目标是将旋转与平移分开。因此,您必须构建自己的转换,例如:

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

//set the position of the camera
glTranslate(pos);

//set the scale or rotation pivot
//glTranslate(center);

//scale
//glScale(scale);

//rotate around z-axis first
glRotate(z_angle, 0, 0, 1);    

//rotate around y-axis
glRotate(y_angle, 0, 1, 0);

//rotate around x-axis
glRotate(x_angle, 1, 0, 0);

//set the center back, if set before
//glTranslate(-center);

您会在这里找到更多信息(与 OpenGl 相关,尽管是“现代”OpenGl):https://learnopengl.com/Getting-started/Transformations

注意:您可能必须将输入“W A S D”调整到更改的轴。例如,如果“W”键调整 z 分量,您可能不会使用上面的设置“向前”(沿 z 轴)。为了根据变换后的轴移动,您需要变换矩阵并提取它们。更好的是使用数学库,例如glm。轨道相机如何实现,再次看看:https://learnopengl.com/Getting-started/Camera

© www.soinside.com 2019 - 2024. All rights reserved.