(c ++)openGL beginner:沿z平移时出现意外的摄像机行为

时间:2016-11-24 00:27:03

标签: c++ opengl

所以我决定学习OpenGL,我要做的第一件事就是深入了解基础知识。在这种情况下,我想熟悉OpenGL坐标系和摄像机定位。

以下是关于OpenGL的两个相关事实:我知道这一点:

  1. 其坐标轴形成右手坐标系

  2. 默认情况下,摄像机位于原点,并指向z轴的负方向:

  3. enter image description here

    首先,一个概念性问题:假设相机后面的物体不可见(意味着物体坐标必须至少满足z <0),我是对的吗?

    第二次,关于我在标题中提到的奇怪相机行为的问题。我写了一个简单的OpenGL程序,绘制一个中心位于(0,0,0)的立方体,并允许我实时翻译相机。这就是我所拥有的:

    int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)函数中与OpenGL相关的代码:

        <...>    
        HGLRC openGLContext = wglCreateContext(hDC);
        wglMakeCurrent(hDC, openGLContext);
    
        if (Win32LoadOpenGLFunctions())//fragment-related additon
            initOpenGL();
        <...>
    

    initOpenGL()函数中的代码:

        static void initOpenGL()
        {
            glEnable(GL_DEPTH_TEST);
        }
    

    draw()函数中的代码:

    void draw()
    {
        glViewport(0, 0, width, height);
        glClearColor(0, 0, 0, 0);
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    
        glColor3f(1.0, 1.0, 1.0);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(-1, 1, -1, 1, 5, -5);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
    
        glTranslatef(0.0, 0.0, test);//translate the camera along the z-axis
    
        glBegin(GL_TRIANGLES);
            Cube(1);
        glEnd();
    
        glFlush();
    }
    

    test函数中的参数draw()被绑定到按键,因此我可以测试当我沿z轴平移相机时屏幕输出的变化。

    Cube()函数如下所示:

    void Cube(float a)
    {
        float A = a * 0.5f;
    
        //red face
        glColor3f(1, 0, 0);
        glVertex3f(A, A, A);
        glVertex3f(-A, -A, A);
        glVertex3f(A, -A, A);
    
        glVertex3f(A, A, A);
        glVertex3f(-A, A, A);
        glVertex3f(-A, -A, A);
    
        //blue face
        glColor3f(0, 0, 1);
        glVertex3f(A, A, -A);
        glVertex3f(-A, -A, -A);
        glVertex3f(A, -A, -A);
    
        glVertex3f(A, A, -A);
        glVertex3f(-A, A, -A);
        glVertex3f(-A, -A, -A);
    
        //yellow face
        glColor3f(1, 1, 0);
        glVertex3f(A, A, A);
        glVertex3f(A, A, -A);
        glVertex3f(-A, A, A);
    
        glVertex3f(-A, A, A);
        glVertex3f(A, A, -A);
        glVertex3f(-A, A, -A);
    
        //cyan face
        glColor3f(0, 1, 1);
        glVertex3f(A, -A, A);
        glVertex3f(A, -A, -A);
        glVertex3f(-A, -A, A);
    
        glVertex3f(-A, -A, A);
        glVertex3f(A, -A, -A);
        glVertex3f(-A, -A, -A);
    
        //green face
        glColor3f(0, 1, 0);
        glVertex3f(A, A, A);
        glVertex3f(A, -A, A);
        glVertex3f(A, -A, -A);
    
        glVertex3f(A, A, A);
        glVertex3f(A, -A, -A);
        glVertex3f(A, A, -A);
    
        //orange face
        glColor3f(1, 0.67, 0);
        glVertex3f(-A, A, A);
        glVertex3f(-A, -A, A);
        glVertex3f(-A, -A, -A);
    
        glVertex3f(-A, A, A);
        glVertex3f(-A, -A, -A);
        glVertex3f(-A, A, -A);
    }
    

    这张照片显示了我假设发生的事情:

    enter image description here

    在这张照片中,我们正在俯视立方体。由于我指定了具有5和-5的正交投影作为近和远裁剪值,因此观看体积是从z = 5延伸到z = -5的框。立方体在z = 0.5处具有“红色”面,在z = -0.5处具有“蓝色”面。相机最初位于(0,0,0),这意味着保持立方体。因为它看着“蓝色”的脸,我应该看到一个蓝色的方块。

    如果我将相机转向“蓝色”脸部(test&lt; 0),我预计test&lt; test时,“蓝色”脸会消失。 -0.5因为它落后于相机。当翻译成“红色”面(test&gt; 0)时,我希望DEPTH_TEST&gt;时屏幕上的蓝色方块变为红色。 0.5(因为相机位于“红色”面前,阻挡了“蓝色”面并且test打开了)。当test&gt; 5.0屏幕应该变黑,因为相机在观看体积之外。

    但事实并非如此。当test从0变为5.5时,“蓝色”面部可见,此时它会消失。将{{1}}从0减少到约-4.5会显示“蓝色”面,然后它会切换到“红色”,在约-5.5时消失。

    有什么想法吗?

    -

    相关问题 - 为什么它看起来像一个矩形而不是一个正方形?我没有看到我在代码中引入这样的透视图。正交不应使正方形看起来像矩形afaik。enter image description here

1 个答案:

答案 0 :(得分:0)

(完全披露,我不是OpenGL专家,我只是玩了一下)

第一个问题:你的直觉是正确的,相机背后的物体将不可见。因此,对于默认相机,位于z的对象> 0将不可见。

第二个问题:您对相机相对于正交观看体积的位置的解释是不正确的。通过定义观看音量,您可以有效地移动相机。相机位于观看体积的后面,在这种情况下,z = 5.0。

通过更改测试值,您将沿z轴移动查看体积。当测试&lt; -4.5,您已将观察体积移动到红色表面之外,因此蓝色表面变得可见。当测试&lt; 5.5,您已将观察体积移动到蓝色表面之外,因此两个表面都不再可见。

相关问题:相机所在的观看体积的背面是正方形。但是,显示相机所看到的内容的窗口是一个矩形,因此它会从相机中拉伸图像。如果更改查看体积的大小或窗口的大小以使宽度和高度匹配,则表面将显示为完美的正方形。