使用glFrustum创建拼接场景

时间:2013-06-14 18:28:01

标签: c++ algorithm opengl graphics 3d

我有一个程序,我可以根据用户的位置在屏幕上进行场景渲染。当用户改变位置时,平截头体变为给出轴外投影。我想利用这种技术在三个不同的显示器上拼接一个更大的场景,具有以下类似的东西:

enter image description here 想象一下在三个显示器上呈现的大型真实世界场景。三个显示器应该显示场景,因为它将根据用户的位置在每个显示器上以改变的透视图显示。我可以使用一个显示器按照用户的位置渲染场景,但无法想到在三个屏幕上工作的方法。

我创建的类离轴投影基本上执行以下操作:

customCam::project(){
pushMatrices();
glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
        glFrustum(leftNear.x, rightNear.x, bottomNear.y, topNear.y, _near, _far);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(uPos.x, uPos.y, 0, uPos.x, uPos.y, -1, 0, 1, 0); //neglect z scaling for now. In the main program, it's there
    glTranslatef(0, 0, uPos.z);
}

我如何以这样一种场景看待三个截头体,以至于场景在现实世界中看起来是连续的?目前,该类的用户绘制如下场景:

cstCam.project();
    //draw something here
popMatriceS(); //which were pushed before glFrustum projection

修改 在我的例子中,为用户定义三个截头锥体(在同一参照系中考虑用户和屏幕角落的所有显示),我做了以下几点:

custCam1.project();
//draw scene here. eg: two walls at the far left and right screen
drawWalls();
popMatrices();
custCam2.project();
drawWalls();
popMatrices();
custCam3.project();
drawWalls();
popMatrices();

void drawWalls(){
//Left most corner screen wall
glBegin(GL_QUADS);
glVertex3f(-1.5*PHWIDTH, HEIGHT/2, 0); //where PHWIDTH, HEIGHT is the physical width/height of each screen
glVertex3f(-1.5*PHWIDTH, HEIGHT/2, -50);
glVertex3f(-1.5*PHWIDTH, -HEIGHT/2, -50);
glVertex3f(-1.5*PHWIDTH, -HEIGHT/2, 0);
glEnd();

//Right most corner screen wall
glBegin(GL_QUADS);
glVertex3f(1.5*PHWIDTH, HEIGHT/2, 0); //where PHWIDTH, HEIGHT is the physical width/height of each screen
glVertex3f(1.5*PHWIDTH, HEIGHT/2, -50);
glVertex3f(1.5*PHWIDTH, -HEIGHT/2, -50);
glVertex3f(1.5*PHWIDTH, -HEIGHT/2, 0);
glEnd();
}

1 个答案:

答案 0 :(得分:1)

这并不像看起来那么困难。考虑下面的图像(在znear级别从上面看三个屏幕)

Screens from above

我假设每个屏幕在znear距离的x方向上跨越2个单位。您可能需要根据场景缩放此值。

三个屏​​幕的y坐标范围不会改变,因为它们处于相同的垂直位置。

因此,屏幕需要三种不同的投影矩阵。确定偏移量非常简单。你只需要与相机点的差异:

left screen   => [-3 - camera.x, -1 - camera.x]
center screen => [-1 - camera.x, 1 - camera.x]
right screen  => [1 - camera.x, 3 - camera.x]

当然,您需要屏幕空间中的摄像头位置,如图所示。

视图矩阵可以是任意一个,但对于所有三个屏幕应该相同。这次,将场景空间中的摄像机位置传递给gluLookAt