我在c#中使用opentk来渲染3d表面并旋转它。 偏航工作正常,但俯仰旋转(使物体朝向摄像机倾斜)会导致表面变形。
左边的图像是我正在渲染的变形而右边的图像是正确的。 请注意,当音高为零时,它看起来非常精细。 以下是我的代码的要点:
private void glControl1_Paint(object sender, PaintEventArgs e)
{
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
Matrix4 perspective = Matrix4.CreatePerspectiveFieldOfView(1.0f, aspect_ratio, 1.0f, 10000.0f); //Setup Perspective [fovy, aspect, zNear, zFar]
Matrix4 lookat = Matrix4.LookAt(eye_pos.X, eye_pos.Y, eye_pos.Z, 0, 0, 0, 0, 0, 1); //Setup camera [eyeX, eyeY, eyeZ, targetX, targetY, targetZ, upX, upY, upZ)]
GL.MatrixMode(MatrixMode.Projection); //Load Perspective
GL.LoadIdentity();
GL.Viewport(0, 0, this.ClientSize.Width, this.ClientSize.Height);
GL.LoadMatrix(ref perspective);
GL.MatrixMode(MatrixMode.Modelview); //Load Camera
GL.LoadIdentity();
GL.LoadMatrix(ref lookat);
GL.Viewport(0, 0, glControl1.Width, glControl1.Height); //Size of window
GL.Enable(EnableCap.DepthTest); //Enable correct Z Drawings
GL.DepthFunc(DepthFunction.Less); //Enable correct Z Drawings
//Rotating
Vector2 xy_view_vector = new Vector2(eye_pos.X, eye_pos.Y);
xy_view_vector.Normalize();
Vector2 fold_vec = xy_view_vector.PerpendicularLeft; // this is the line over which you'd tilt the view forward towards the camera
GL.Rotate((float)numericUpDown2.Value, fold_vec.X, fold_vec.Y, 0.0f);// pitch (tilt forward)
GL.Rotate((float)numericUpDown1.Value, 0.0f, 0.0f, 1.0f);// yaw rotation - about z
// axes
GL.Begin(PrimitiveType.Lines);
GL.Color3(Color.White);
GL.Vertex3(-10, 0, 0);
GL.Vertex3(10, 0, 0);
GL.Vertex3(0, -10, 0);
GL.Vertex3(0, 10, 0);
GL.Vertex3(0, 0, -10);
GL.Vertex3(0, 0, 10);
GL.End();
int i2, j2;
float z1, z2, z3, z4;
GL.Begin(PrimitiveType.Quads);
for (int i = 0; i < data.x.Count - 2; i++)
{
for (int j = 0; j < data.y.Count - 2; j++)
{
i2 = i + 1;
j2 = j + 1;
z1 = data.z[i.ToString() + "," + j.ToString()];
z2 = data.z[i2.ToString() + "," + j.ToString()];
z3 = data.z[i2.ToString() + "," + j2.ToString()];
z4 = data.z[i.ToString() + "," + j2.ToString()];
GL.Color4(color_map.GetColor((z1 + z3) / 2, data.minz, data.maxz, opacity));
GL.Vertex3(new Vector3(data.x[i], data.y[j], z1));
GL.Vertex3(new Vector3(data.x[i2], data.y[j], z2));
GL.Vertex3(new Vector3(data.x[i2], data.y[j2], z3));
GL.Vertex3(new Vector3(data.x[i], data.y[j2], z4));
}
}
GL.End();
GraphicsContext.CurrentContext.VSync = true; //Caps frame rate as to not over run GPU
glControl1.SwapBuffers(); //Takes from the 'GL' and puts into control
}
我想知道是否有人知道为什么会这样。 有一个简单的俯仰/偏航旋转样本会有所帮助 - 所以如果你知道一个可以提供帮助的opentk样本,我会很感激它的链接。
答案 0 :(得分:2)
我无法确切地告诉你你做错了什么,但是我可以粘贴我用来围绕原点对象旋转相机的代码:
void SetupPerspective()
{
var aspectRatio = Width / (float)Height;
Projection = Matrix4.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspectRatio, 0.1f, 10);
ModelView = Matrix4.Identity;
// apply camera transform
Camera.ApplyCamera(ref ModelView);
}
void ApplyCamera(ref Matrix4 modelView)
{
modelView = Matrix4.CreateRotationY(Yaw)
* Matrix4.CreateRotationX(Pitch)
* Matrix4.CreateRotationZ(Roll)
* Matrix4.CreateTranslation(-Position)
* modelView;
}
我没有使用固定功能管道,但您可以设置生成的Projection和ModelView矩阵,就像您已经在使用它一样。