用glFrustum改变坐标

时间:2013-05-13 12:11:00

标签: c++ algorithm opengl 3d openframeworks

我正在尝试使用glFrustum进行透视投影,据我所知glFrustum glOrtho可用于修改我们所需坐标系到真实屏幕坐标的映射(如阅读蓝皮书)。因此,如果我执行glFrustum(-1,1,-1,1,1,1000);,它会将坐标更改为
left = -1,right = 1,bottom = -1,top = 1,采用笛卡尔坐标形式。

我试图通过在我的绘图方法中调用以下函数在此坐标系中绘制一个简单的房间(带有2个侧墙),并在屏幕上进行适当的绘制。

void drawRoomWalls(){
    //Left wall
    glBegin(GL_QUADS);
    glVertex3f(-1.0, 1.0, 0.0);
    glVertex3f(-1.0, 1.0, -0.4);
    glVertex3f(-1.0, -1.0, -0.4);
    glVertex3f(-1.0, -1.0, 0.0);
    glEnd();

    //Right wall
    glBegin(GL_QUADS);
    glVertex3f(1.0, 1.0, 0.0);
    glVertex3f(1.0, 1.0, -0.4);
    glVertex3f(1.0, -1.0, -0.4);
    glVertex3f(1.0, -1.0, 0.0);
    glEnd();
}

该函数调用如下:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
    glFrustum(1.0, -1.0, -1.0, 1.0, 1.0, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -1.0);
drawRoomWalls();

随后,我尝试进行离轴投影(将鼠标作为输入而不是用户的头部)。代码如下: glMatrixMode(GL_PROJECTION);     glPushMatrix();     glMatrixMode(GL_MODELVIEW);     glPushMatrix();

double fov, near, far;
double headX, headY, headZ;
float aspectRatio;

near = 0.5f; far = 1000.0f;  aspectRatio = ofGetWidth()/ofGetHeight();
fov = tan(DEG_TO_RAD * 30/2); //tan accepts angle in radians. tan of the half of the fov angle
fov = 0.5; //taken constant for now

double msX = (double)ofGetMouseX();
double msY = (double)ofGetMouseY();
double scrWidth = (double)ofGetWidth();
double scrHeight = (double)ofGetHeight();

headX = (msX / scrWidth) - 0.5; 
headY = ((scrHeight - msY) / scrHeight) - 0.5;
headZ = -2.0;

glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum( near * (-fov * aspectRatio + headX),
               near * (fov * aspectRatio + headX),
               near * (-fov + headY),
               near * (fov + headY),
               near,
               far);

leftValue = near * (-fov * aspectRatio + headX); //for printing out on screen
rightValue = near * (fov * aspectRatio + headX); //for printing out on screen
bottomValue = near * (-fov + headY); //for printing out on screen
topValue = near * (fov + headY); //for printing out on screen

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(headX * headZ, headY * headZ, 0, headX * headZ, headY * headZ, -1, 0, 1, 0);
glTranslatef(0.0, 0.0, headZ);
drawRoomWalls();


我打印了leftValuerightValuebottomValuetopValue的值,当鼠标位于屏幕中央时(调用glFrustum看起来像glFrustum(-0.25,0.25,-0.25,0.25,1.0,1000.0)
根据上面的调用,我期望坐标系的left=-0.25, right=0.25, bottom=-0.25, top=0.25,我期待墙壁消失(因为它们以(1.0,1.0,0.0)绘制为例)。然而,墙壁一直出现在屏幕的两侧(场景歪斜,中心与离轴投影基本相同)。为什么墙壁仍然在两侧的位置(即使坐标变为-0.25,0.25)或glFrustum调用中有什么东西我在这里缺少坐标系?

1 个答案:

答案 0 :(得分:4)

我刚才意识到您还将headZ更改为-2。这解释了这种行为。

如果相机位于z = 2并且您的垂直半fov为0.5,那么在z = 0您已经看到正方向和负方向上的1个单位。这就是你看到墙壁的原因。

Visualization