У меня проблема с перемещением и вращением объектов в OpenGL. Я использую C # и OpenTK (Mono), но думаю, проблема в том, что я не понимаю часть OpenGL, поэтому вы можете помочь мне, даже если вы ничего не знаете о C # / OpenTK.
Я читаю OpenGL SuperBible (последняя редакция) и пытался переписать GLFrame в C #. Вот часть, которую я уже переписал:
public class GameObject
{
protected Vector3 vLocation;
public Vector3 vUp;
protected Vector3 vForward;
public GameObject(float x, float y, float z)
{
vLocation = new Vector3(x, y, z);
vUp = Vector3.UnitY;
vForward = Vector3.UnitZ;
}
public Matrix4 GetMatrix(bool rotationOnly = false)
{
Matrix4 matrix;
Vector3 vXAxis;
Vector3.Cross(ref vUp, ref vForward, out vXAxis);
matrix = new Matrix4();
matrix.Row0 = new Vector4(vXAxis.X, vUp.X, vForward.X, vLocation.X);
matrix.Row1 = new Vector4(vXAxis.Y, vUp.Y, vForward.Y, vLocation.Y);
matrix.Row2 = new Vector4(vXAxis.Z, vUp.Z, vForward.Z, vLocation.Z);
matrix.Row3 = new Vector4(0.0f, 0.0f, 0.0f, 1.0f);
return matrix;
}
public void Move(float x, float y, float z)
{
vLocation = new Vector3(x, y, z);
}
public void RotateLocalZ(float angle)
{
Matrix4 rotMat;
// Just Rotate around the up vector
// Create a rotation matrix around my Up (Y) vector
rotMat = Matrix4.CreateFromAxisAngle(vForward, angle);
Vector3 newVect;
// Rotate forward pointing vector (inlined 3x3 transform)
newVect.X = rotMat.M11 * vUp.X + rotMat.M12 * vUp.Y + rotMat.M13 * vUp.Z;
newVect.Y = rotMat.M21 * vUp.X + rotMat.M22 * vUp.Y + rotMat.M23 * vUp.Z;
newVect.Z = rotMat.M31 * vUp.X + rotMat.M32 * vUp.Y + rotMat.M33 * vUp.Z;
vUp = newVect;
}
}
Итак, я создаю новый GameObject (GLFrame) для некоторых случайных координат: GameObject go = new GameObject(0, 0, 5);
и немного поворачиваю его: go.RotateLocalZ(rotZ);
. Затем я получаю матрицу, используя Matrix4 matrix = go.GetMatrix();
и визуализирую кадр (сначала я устанавливаю матрицу просмотра, а затем умножаю ее на матрицу моделирования)
protected override void OnRenderFrame(FrameEventArgs e)
{
base.OnRenderFrame(e);
this.Title = "FPS: " + (1 / e.Time).ToString("0.0");
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadIdentity();
Matrix4 modelmatrix = go.GetMatrix();
Matrix4 viewmatrix = Matrix4.LookAt(new Vector3(5, 5, -10), Vector3.Zero, Vector3.UnitY);
GL.LoadMatrix(ref viewmatrix);
GL.MultMatrix(ref modelmatrix);
DrawCube(new float[] { 0.5f, 0.4f, 0.5f, 0.8f });
SwapBuffers();
}
DrawCube(float[] color)
- это мой собственный метод рисования куба.
Теперь самая важная часть: если я отрисовываю кадр без части GL.MultMatrix(ref matrix);
, , но с использованием GL.Translate()
и GL.Rotate()
, это работает (второй скриншот). Однако, если я не использую эти два метода и передаю матрицу моделирования непосредственно в OpenGL, используя GL.MultMatrix()
, она рисует что-то странное (первый снимок экрана).
Можете ли вы помочь мне и объяснить, в чем проблема? Почему он работает с использованием методов перевода и поворота, а не умножением матрицы вида на матрицу моделирования?