问题
I'm using opentk in c# to render a 3d surface and rotate it. The yaw works fine, but the pitch rotation (tilting the object towards the camera) causes the surface to deform.
The image on the left is what I'm rendering which is deformed and the one one the right is correct. Note that when the pitch is zero, it looks perfectly fine. Here is the gist of my code:
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
}
I was wondering if anyone has a clue as to why this is happening. Having a simple pitch/yaw rotation sample would help - so if you know an opentk sample that can help, I'd appreciate linking it.
回答1:
I can not tell you exactly what you are doing wrong, but I can paste the code which I use to rotate the camera around an object at the origin:
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;
}
I don't use the fixed-function pipeline but you could set the resulting Projection and ModelView matrices just like you're already doing it.
来源:https://stackoverflow.com/questions/23987313/opentk-pitch-rotation-deforms-the-shape