Проблема с матрицей вида в OpenTK

Я написал программу, используя OpenTK(с#), которая выводит картинку на экран. Следующий этап - добавить камеру, передвигающуюся при нажатии AWSD. Если что, в основе моего кода лежит довольно популярный учебник https://opentk.net/learn/chapter1 .

Для этого я создал класс Camera для имитации камеры:

using OpenTK.Graphics.OpenGL4;
using OpenTK.Mathematics;
using OpenTK.Windowing.Common;
using OpenTK.Windowing.Desktop;
using OpenTK.Windowing.GraphicsLibraryFramework;

namespace engine_0._0._1
{
internal class Camera
{
    public float speed;
    Vector3 position;
    Vector3 target;
    Vector3 up;
    Matrix4 view;

    public Camera(float normalSpeed, Shader shader)
    {
        position = new Vector3(0.0f, 0.0f, 3.0f);
        target = new Vector3(0.0f, 0.0f, 0.0f);
        up = Vector3.UnitY;
        speed = normalSpeed;
        view = Matrix4.LookAt(position, target, up);

        shader.SetMatrix4("view", view);
    }

    public void ChangeSpeed(float newSpeed)
    {
        speed = newSpeed;
    }
    public void Go(KeyboardState input, FrameEventArgs e)
    {
        if (input.IsKeyDown(Keys.W))
        {
            position += target * speed * (float)e.Time;
        }
        if (input.IsKeyDown(Keys.S))
        {
            position -= target * speed * (float)e.Time;
        }
        if (input.IsKeyDown(Keys.D))
        {
            position += Vector3.Normalize(Vector3.Cross(target, up)) * speed * (float)e.Time;
        }
        if (input.IsKeyDown(Keys.A))
        {
            position -= Vector3.Normalize(Vector3.Cross(target, up)) * speed * (float)e.Time;
        }
    }
}
}

Далее в главном классе Window создаю экземпляр класса Camera:

using OpenTK.Graphics.OpenGL4;
using OpenTK.Mathematics;
using OpenTK.Windowing.Common;
using OpenTK.Windowing.Desktop;
using OpenTK.Windowing.GraphicsLibraryFramework;

namespace engine_0._0._1
{
internal class Window : GameWindow
{
    float[] vertices;
    uint[] indices;
    Shader shader;
    Camera cam;
    int vertexBufferObject;
    int vertexArrayObject;
    int elementBufferObject;
    Matrix4 view;
    public Window(int width, int height, string title) : base(GameWindowSettings.Default, new NativeWindowSettings() { Size = (width, height), Title = title }) { }

    protected override void OnLoad()
    {
        base.OnLoad();

        GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        //Не обращайте внимания, этот код точно рабочий
        Map map = new Map(@"Maps\m1.txt");
        vertices = map.vertices;
        indices = map.indices;

        shader = new Shader(@"Shaders\shader.vert", @"Shaders\shader.frag");

        cam = new Camera(1.5f, shader); // ИНИЦИЛИЗИРУЮ КАМЕРУ СРАЗУ ПОСЛЕ ИНИЦИАЛИЗАЦИИ ШЕЙДЕРА
        //этот код точно рабочий
        // Создаю VBO
        vertexBufferObject = GL.GenBuffer();
        GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBufferObject);
        GL.BufferData(BufferTarget.ArrayBuffer, vertices.Length * sizeof(float), vertices, BufferUsageHint.StaticDraw);
        //этот код точно рабочий
        // Создаю VAO
        vertexArrayObject = GL.GenVertexArray();
        GL.BindVertexArray(vertexArrayObject);
        GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), 0);
        GL.EnableVertexAttribArray(0);

        //этот код точно рабочий
        int texCoordLocation = shader.GetAttribLocation("aTexCoord");
        GL.VertexAttribPointer(texCoordLocation, 2, VertexAttribPointerType.Float, false, 6 * sizeof(float), 3 * sizeof(float));
        
        Texture ground = new Texture(@"Tiles\grass.png", TextureUnit.Texture0);
        Texture lava = new Texture(@"Tiles\lava.png", TextureUnit.Texture1);
        
        shader.SetInt("ground", 0);
        shader.SetInt("lava", 1);
        GL.EnableVertexAttribArray(texCoordLocation);
        
        //этот код точно рабочий
        //tiles VAP
        int tileTypeLocation = shader.GetAttribLocation("aTileType");
        GL.VertexAttribPointer(tileTypeLocation, 1, VertexAttribPointerType.Float, false, 6 * sizeof(float), 5 * sizeof(float));
        GL.EnableVertexAttribArray(tileTypeLocation);

        elementBufferObject = GL.GenBuffer();
        GL.BindBuffer(BufferTarget.ElementArrayBuffer, elementBufferObject);
        GL.BufferData(BufferTarget.ElementArrayBuffer, indices.Length * sizeof(uint), indices, BufferUsageHint.StaticDraw);

        shader.Use();

        //Code goes here
    }

    protected override void OnRenderFrame(FrameEventArgs e)
    {
        base.OnRenderFrame(e);

        GL.Clear(ClearBufferMask.ColorBufferBit);

        //Code goes here.

        shader.Use();
        GL.BindVertexArray(vertexArrayObject);

        GL.DrawElements(PrimitiveType.Triangles, indices.Length, DrawElementsType.UnsignedInt, 0);

        SwapBuffers();
    }
    protected override void OnUpdateFrame(FrameEventArgs e)
    {
        base.OnUpdateFrame(e);

        if (KeyboardState.IsKeyDown(Keys.Escape))
        {
            Close();
        }
    }

    protected override void OnResize(ResizeEventArgs e)
    {
        base.OnResize(e);

        GL.Viewport(0, 0, e.Width, e.Height);
    }

    protected override void OnUnload()
    {
        // Unbind all the resources by binding the targets to 0/null.
        GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
        GL.BindVertexArray(0);
        GL.UseProgram(0);

        // Delete all the resources.
        GL.DeleteBuffer(vertexBufferObject);
        GL.DeleteVertexArray(vertexArrayObject);

        GL.DeleteProgram(shader.Handle);

        base.OnUnload();
    }
}
}

А так же код вершинного шейдера:

#version 330 core

layout (location = 0) in vec3 aPosition;

layout (location = 1) in vec2 aTexCoord;

layout (location = 2) in float aTileType;

uniform mat4 view;

out vec2 TexCoord;
out float TileType;

void main()
{
    TexCoord = aTexCoord;
    TileType = aTileType;
    gl_Position = vec4(aPosition, 1.0f) * view;
}

Сама проблема в том, что пока я не добавил в код камеру, программа вела себя правильно, но после добавления камеры картинка полностью пропала(но код скомпилировался) Вот и не знаю, что делать?


Ответы (1 шт):

Автор решения: Kromster

Для начала стоит попробовать передавать единичную матрицу вида, чтобы проверить что она передается корректно.

Скорее всего у вас неправильный порядок умножения. У меня в GLSL всегда "задом-наперед", т.е. vertex * MVP записан как PVM * vertex:

gl_Position = mProj * mView * mModel * vec4(vaPosition, 1.0);
→ Ссылка