透视投影(误解了gluPerspective)

时间:2015-08-03 09:21:11

标签: c++ opengl

我想用gluPerspective近和远参数来澄清事情,我知道    他们为所有对象定义了z轴的范围 - 因此剪切算法将剪切比近/远更近/远的对象。当我们说接近= 0.1和远= 100 * winWid时,我们没有看到任何东西,因为对象落后于观察者(默认情况下摄像头为(0.0, 0.0, 0.0)加上openGL用户坐标系统是右手),所以然后我们调用(见下面的代码)translate(0.0, 0.0, -winWid)向后移动-z轴对象,将它们放在摄像机前面。 但是如果我们设置far = -100 * winWid;一切都与积极的远远值相同。

那么当远处是负面时会发生什么变化?

为什么在这种情况下也没有剪辑?

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

const float winWid = 1000.0f;
const float winHei = 800.0f;      
GLfloat cube_side = 200.0f;
GLfloat ALPHA = 0.7f;

void render();    
void updateDisplay()
{
    render(cubeAngle, rotx, roty, rotz);
}    

void drawCube(const GLfloat& a)
{
    glBegin(GL_QUADS);
      //    back face   
      glColor4f(0.0f, 1.0f, 0.0f, ALPHA);
      glVertex3f(0.0f, 0.0f, 0.0f);
      glVertex3f(0.0f, a, 0.0f);
      glVertex3f(a, a, 0.0f);
      glVertex3f(a, 0.0f, 0.0f); 
      //  and other cube faces here ...
    glEnd();
}      

void render()
{       
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    
    glPushMatrix();    
        drawCube(cube_side);    
    glPopMatrix();  
    glutSwapBuffers();
} 

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_ALPHA);
    glutInitWindowSize(winWid, winHei);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("window");    
    glutDisplayFunc(updateDisplay);     
    glEnable(GL_DEPTH_TEST);                                    //  depth buffer setup
    glEnable(GL_BLEND);                                         //  transparency setup
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);              

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();   

    gluPerspective(55.0f, winWid/winHei, 0.1f, 100*winWid);
    glMatrixMode(GL_MODELVIEW); 
    glTranslatef(0.0f, 0.0f, -winWid);                          //  move back to see drawing objects
    glRotatef(75.0f, -1.0f, 0.0f, 0.0f);                            //  make z+ axis point up to emphasize 3D (wihout this rotate z+ points towards the viewer)

    glutMainLoop();
    return 0;
}

1 个答案:

答案 0 :(得分:1)

gluPerspective不支持负的远平面值。文档说明:

  

zFar:指定从查看器到远剪裁平面的距离(始终为正)(source)

默认情况下,OpenGL中的摄像头沿负z轴观察。所以可见区域在世界坐标中是[-near,-far]。在您的代码示例中,对象位于z = -1000,而可见范围是[-0.01,-100 * 1000],这意味着对象显然在视图中。

另外需要提及的是深度缓冲精度:这主要由nearPlane和farPlane给出的范围定义。假设您具有16位的精度(可以或多或少取决于设置),可以存储2 ^ 16个不同的深度值。这意味着对于您的设置,对象可以相对远离彼此,并且仍将被视为处于相同深度。您可以考虑这个巨大的深度范围是否真的对于应用程序是必要的。