3

OpenGLでのオブジェクトの移動と回転に問題があります。私はC#とOpenTK(Mono)を使用していますが、問題はOpenGLの部分を理解していないことだと思います。そのため、C#/OpenTKについて何も知らなくても助けてくれるかもしれません。

OpenGL SuperBible(最新版)を読んでいて、C#でGLFrameを書き直そうとしました。これが私がすでに書き直した部分です:

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)は、立方体を描くための私自身の方法です。

ここで最も重要な部分:部分なしフレームをレンダリングする、とを使用すると、機能します(2番目のスクリーンショット)。ただし、これら2つの方法を使用せず、を使用してモデリングマトリックスをOpenGLに直接渡すと、奇妙なものが描画されます(最初のスクリーンショット)。GL.MultMatrix(ref matrix);GL.Translate()GL.Rotate()GL.MultMatrix()

それはどのように見えるか それはどのように見えるべきか

私を助けて、どこに問題があるのか​​説明してもらえますか?変換メソッドと回転メソッドを使用して機能するのに、ビューマトリックスにモデリングマトリックスを乗算しないのはなぜですか?

4

1 に答える 1

6

OpenGL変換行列は、列ごとに並べられています。使用している行列の転置を使用する必要があります。

于 2011-10-27T14:49:27.647 に答える