1

私は一般的にopenglと行列に慣れていませんが、カメラクラスを一人称モードで動作させています.モデルビューとビューマトリックスのみを使用しています

今のところこれしか持っていませんが、

        Matrix4 view = Matrix4.LookAt
        (
            cam_pos[0],
            cam_pos[1],
            cam_pos[2],
            cam_pos[0] + cam_view[0],
            cam_pos[1] + cam_view[1],
            cam_pos[2] + cam_view[2],
            0.0f, 1.0f, 0.0f
       );

        GL.MatrixMode(MatrixMode.Modelview);
        GL.LoadMatrix(ref view);

ここに私の完全なクラスがあります:

namespace opengl.Cameras
{
    using opengl.Components;
    using OpenTK;
    using OpenTK.Graphics.OpenGL;
    using System.Windows.Forms;
    using System;

    public class BasicCamera : CameraComponent, IComponent
    {
        const float sensitivity = 0.002f;
        const float walk_speed = 100.5f;

        float[] cam_pos = {75.5f, 30.0f, -110};
        float[] cam_view = {-0.0f, 0.0f, 0.7f};

        static int old_x, old_y;

        void normalize(float[] v)
        {
            float magnitude = (float)Math.Sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);           
            v[0] /= magnitude;
            v[1] /= magnitude;
            v[2] /= magnitude;
        }

        void rotate_view(float[] view, float angle, float x, float y, float z)
        {
            float new_x;
            float new_y;
            float new_z;

            float c = (float)Math.Cos(angle);
            float s = (float)Math.Sin(angle);

            new_x = (x * x * (1 - c) + c) * view[0];
            new_x += (x * y * (1 - c) - z * s) * view[1];
            new_x += (x * z * (1 - c) + y * s) * view[2];

            new_y = (y * x * (1 - c) + z * s) * view[0];
            new_y += (y * y * (1 - c) + c) * view[1];
            new_y += (y * z * (1 - c) - x * s) * view[2];

            new_z = (x * z * (1 - c) - y * s) * view[0];
            new_z += (y * z * (1 - c) + x * s) * view[1];
            new_z += (z * z * (1 - c) + c) * view[2];

            view[0] = new_x;
            view[1] = new_y;
            view[2] = new_z;

            normalize(view);
        }

        void motion(int x, int y)
        {
            float rot_x, rot_y;
            float[] rot_axis = new float[3];

            x -= Viewport.Width / 2;
            y -= Viewport.Height / 2;

            rot_x = -(float)(x - old_x) * sensitivity;
            rot_y = -(float)(y - old_y) * sensitivity;

            old_x = x;
            old_y = y;

            rotate_view(cam_view, rot_x, 0.0f, 1.0f, 0.0f);

            rot_axis[0] = -cam_view[2];
            rot_axis[1] = 0.0f;
            rot_axis[2] = cam_view[0];

            normalize(rot_axis);

            rotate_view(cam_view, rot_y, rot_axis[0], rot_axis[1], rot_axis[2]);
        }

        public BasicCamera() :  base()
        {
            // Enable depth testing
            GL.Enable(EnableCap.DepthTest);
            GL.ClearDepth(1.0f);
        }

        public void Load(CameraComponent Camera)
        {
        }

        public void UpdateFrame(double elapsed)
        {
            if (this[Keys.W])
            {
                cam_pos[0] += cam_view[0] * walk_speed;
                cam_pos[1] += cam_view[1] * walk_speed;
                cam_pos[2] += cam_view[2] * walk_speed;
            }
            if (this[Keys.S])
            {
                cam_pos[0] -= cam_view[0] * walk_speed;
                cam_pos[1] -= cam_view[1] * walk_speed;
                cam_pos[2] -= cam_view[2] * walk_speed;
            }
            if (this[Keys.A])
            {
                cam_pos[0] += cam_view[2] * walk_speed;
                cam_pos[2] -= cam_view[0] * walk_speed;
            }
            if (this[Keys.D])
            {
                cam_pos[0] -= cam_view[2] * walk_speed;
                cam_pos[2] += cam_view[0] * walk_speed;
            }

            if (this[Keys.Space])
                cam_pos[1] += walk_speed;
        }

        public void Render(double elapsed)
        {
            Matrix4 view = Matrix4.LookAt
            (
                cam_pos[0],
                cam_pos[1],
                cam_pos[2],
                cam_pos[0] + cam_view[0],
                cam_pos[1] + cam_view[1],
                cam_pos[2] + cam_view[2],
                0.0f, 1.0f, 0.0f
           );

            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadMatrix(ref view);
        }

        public void OnMouseMove(MouseEventArgs e)
        {

        }

        public void OnMouseDown(MouseEventArgs e)
        {
            old_x = (int)e.X - Viewport.Width / 2;
            old_y = (int)e.Y - Viewport.Height / 2;
        }

        public void OnMouseMotion(Vector2 MousePosition, Vector2 PrevMousePosition)
        {           
            motion((int)MousePosition.X, (int)MousePosition.Y);
        }

        public void Destroy()
        {
        }

        public void Load()
        {

        }
    }
}
4

2 に答える 2

1

最も簡単な答えはいいえです。glClipPlain() を使用してクリッピング プレーンを設定することは可能ですが、この関数を使用しても、射影行列によって設定されたデフォルトのクリッピング プレーンは上書きされません (デフォルトでは (1.0 近く、-1.0 遠く) ) orthographic) 結果として、非常に簡単な独自の射影行列を設定しない限り、これらのクリッピング プレーンの外に出るオブジェクトは消えます: glMatrixMode(GL_PROJECTION); glFrustum(-left_side, right_side, -bottom, top, near, -far) *これらの関数は実際には非推奨であることに注意してください glFloatv(GL_PROJECTION_MATRIX, modview); glUniformMatrix4fv(vert_shader, 1, false, modview); *この場合の modview は、マトリックス値を保持するための 16 個の float 要素配列になります *vert_shader 私が望むシェーダー

これらのシェーダー関数の詳細については、自分で知っておくか、オンラインの非常に豊富なチュートリアルを読んでください。私自身初心者ですが、何らかの形であなたを助けてくれることを願っています;)

于 2013-09-06T05:47:33.567 に答える