居中场景的问题

时间:2013-03-03 17:32:59

标签: c# wpf opengl

我必须用openGL显示stl模型。 (SharpGL。)我想设置初始视图,以便模型位于屏幕的中心并大致填充它。我已经计算了模型的边界立方体并设置了如下视图:(sceneBox是一个Rect3D - 它存储了左后角和大小的位置)

// Calculate viewport properties
double left = sceneBox.X;
double right = sceneBox.X + sceneBox.SizeX;
double bottom = sceneBox.Y;
double top = sceneBox.Y + sceneBox.SizeY;

double zNear = 1.0;
double zFar = zNear + 3 * sceneBox.SizeZ;

double aspect = (double)this.ViewportSize.Width / (double)this.ViewportSize.Height;

if ( aspect < 1.0 ) { 
    bottom /= aspect;
    top /= aspect;
} else {
    left *= aspect;
    right *= aspect;
}

//  Create a perspective transformation.
gl.Frustum(
    left / ZoomFactor, 
    right / ZoomFactor,
    bottom / ZoomFactor, 
    top / ZoomFactor,
    zNear, 
    zFar);

//  Use the 'look at' helper function to position and aim the camera.
gl.LookAt(
    0, 0, 2 * sceneBox.SizeZ,           
    sceneBox.X + 0.5 * sceneBox.SizeX, sceneBox.Y + 0.5 * sceneBox.SizeY, sceneBox.Z - 0.5 * sceneBox.SizeZ,    
    0, 1, 0);                   

这适用于我的小型手工测试模型:(它的盒子大小为2 * 2 * 2个单位)

Good view

这正是我想要的。 (黄线显示边界框)

但是,当我加载一个大约60 * 60 * 60单位的stl模型时,我明白了:

Bad view

它非常小而且太远了。

我应该改变什么来使其有效?

以下是完整的内容:https://dl.dropbox.com/u/17798054/program.zip

您也可以在zip中找到此模型。引用的代码位于KRGRAAT.SZE.Control.Engine.GLEngine.UpdateView()

2 个答案:

答案 0 :(得分:0)

显然问题是你在lookAt函数中使用的参数。如果你计算了边界立方体,你需要做的就是把它放在距离相机的距离(eyeZ)

<强> SIZEX /黄褐色(angleOfPerspective)

其中sizeX是构建立方体的Quad的宽度,angleOfPerspective是GlPerspective的第一个参数,当然前四边形的centerX == posX == centreX和前四边形的中心Y == posY == centreY和视锥体是没必要

lookAt reference http://www.opengl.org/sdk/docs/man2/xhtml/gluLookAt.xml

答案 1 :(得分:0)

所以,为了澄清Arek的答案,这就是我修复它的方法:

// Calculate viewport properties
double zNear = 1.0;
double zFar = zNear + 10 * sceneBox.SizeZ; // had to increase zFar

double aspect = (double)this.ViewportSize.Width / (double)this.ViewportSize.Height;

double angleOfPerspective = 60.0;
double centerX = sceneBox.X + 0.5 * sceneBox.SizeX;
double centerY = sceneBox.Y + 0.5 * sceneBox.SizeY;
double centerZ = sceneBox.Z + 0.5 * sceneBox.SizeZ;

//  Create a perspective transformation.
gl.Perspective( // swapped frustum for perspective
    angleOfPerspective / ZoomFactor, // moved zooming here
    aspect,
    zNear,
    zFar);

//  Use the 'look at' helper function to position and aim the camera.
gl.LookAt(
    centerX, centerY, sceneBox.SizeX / Math.Tan(angleOfPerspective), // changed eye position
    centerX, centerY, -centerZ,
    0, 1, 0);