2013-05-13 64 views
3

坐标我想使用glFrustum的透视投影,并按照我的理解glFrustumglOrtho可以用来修改我们所期望的坐标系的实际屏幕坐标映射(如在蓝皮书读取)。所以,如果我做
glFrustum(-1,1,-1,1,1,1000);,它改变了坐标
左= -1,右= 1,底部= -1,在直角坐标的形式顶部= 1。变化与glFrustum

我试图通过调用下面的函数在我的拉伸方法绘制在该坐标系统中的简单的房间(含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平局)的例子),但墙壁不断出现在屏幕两侧(与场景歪斜,并在该中心与离轴投影基本相同)为什么墙壁仍然位于侧面的位置(即使是在你的面前) h坐标变成了-0.25,0.25)还是在glFrustum调用中我在这里丢失了关于坐标系的内容?

+0

您的值不能正确。 “left == bottom”和“right == top”意味着'aspectRatio = 1'(因为'headX'和'headY'为0)。你把'fov'设置为'0.5'。这意味着'接近== 0.5'。但是,您将其设置为“1”。必须有一些不同于你预期的值。如果所有变量都包含正确的值,请检查。 – 2013-05-13 16:37:02

+0

@NicoSchertler:我将headX和headY设置为零,并截取了截图。 - > http://i.imgur.com/dTjfazb.png看上去很好。长宽比确实是一个因为我没有做的类型铸造加倍分裂的宽度/高度。你可以添加这个答案?我会在这些评论中询问一些后续问题。谢谢 – user1240679 2013-05-13 16:48:39

+0

如果你认为这是答案,我会这样做。 – 2013-05-13 16:54:09

回答

4

我才意识到,你也改变headZ-2。这解释了这种行为。

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

Visualization

+1

感谢功能!特别是那个数字! – user1240679 2013-05-13 18:00:55