我正在尝试使用glFrustum
透视投影,据我所知glFrustum
,glOrtho
可以用来修改我们所需坐标系到真实屏幕坐标的映射(如蓝皮书中所述)。因此,如果我这样做glFrustum(-1,1,-1,1,1,1000);
,它会将坐标更改为
left = -1, right = 1, bottom = -1, top = 1 以笛卡尔坐标的形式。
我试图通过在我的 draw 方法中调用以下函数在这个坐标系中绘制一个简单的房间(有 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();
我打印了 , , , 的值leftValue
,rightValue
当bottomValue
鼠标topValue
位于屏幕中央时(调用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调用中有一些关于坐标系的东西我在这里遗漏了?