Неверный куб рисования C # OpenTK GLControl

#c# #winforms #opengl #glsl #opentk

#c# #winforms #opengl #glsl #opentk

Вопрос:

Я использую GLControl OpenTK в приложении C # WinForm (.NET Framework), но я не знаю, почему мой куб размером 20 мм3 масштабируется отдельно от моей формы.

Я наследую GLControl с помощью DCGLControl и добавляю GL.Viewport(ClientRectangle) при изменении размера элемента управления :

 private void DCGLControl_Resize(object sender, EventArgs e)
{
    GL.Viewport(ClientRectangle);
    Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, Width / (float)Height, 1.0f, 1000f);
    GL.MatrixMode(MatrixMode.Projection);
    GL.LoadMatrix(ref projection);
}
 

И вот мое событие DCGLControl_Load (инициализируйте что-то и запустите новый поток для его визуализации):

 private void DCGLControl_Load(object sender, EventArgs e)
{
    GL.Enable(EnableCap.DepthTest);
    GL.ClearColor(ClearColor);
    Resize  = DCGLControl_Resize;

    Matrix4 trans;
    trans = Matrix4.CreateScale(0.01f, 0.01f, 0.01f);

    Context.MakeCurrent(null);
    renderThread = new Thread(() =>
    {
        Context.MakeCurrent(WindowInfo);
        while (true)
        {
            int n;
            for (n = 0; n < Models.Count; n  )
                if (Models[n].VAO == 0)
                {
                    Models[n].Shader.Compile();
                    GenVAO(Models[n]);
                }
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
            GL.Viewport(ClientRectangle);


            for (n = 0; n < Models.Count; n  )
            {
                GL.BindVertexArray(Models[n].VAO);

                Models[n].Shader.Use();
                Models[n].Shader.SetMatrix4("transform", trans);

                if (Models[n].UseEBO)
                    GL.DrawElements(Models[n].PrimitiveType, Models[n].DrawOrder.Length, DrawElementsType.UnsignedInt, 0);
                else
                    GL.DrawArrays(Models[n].PrimitiveType, 0, Models[n].Vertices.Length);
            }
            SwapBuffers();
            Thread.Sleep(1000/60);
        }
    });

    renderThread.Start();
}
 

И вот мой вершинный шейдер :

 #version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;

uniform mat4 transform;

void main()
{
    gl_Position =  transform * vec4(position, 1.0);
}
 

Я получил такой результат :
скриншот ошибки

Я новичок в OpenGL и OpenTK, спасибо за помощь 🙂

Ответ №1:

Вы не можете смешивать матрицы фиксированных функций с преобразованиями матриц в 3.30 core shader. Это означает, что инструкция GL.MatrixMode(MatrixMode.Projection); не имеет никакого эффекта (за исключением ошибки OpenGL в контексте основного профиля). Необходимо добавить матрицу проекции в шейдер:

 #version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;

uniform mat4 projection;
uniform mat4 transform;

void main()
{
    gl_Position = projection * transform * vec4(position, 1.0);
}
 

Добавьте атрибут для матрицы проекции:

 private Matrix4 projection;
 

Установите матрицу в обратном DCGLControl_Resize вызове:

 private void DCGLControl_Resize(object sender, EventArgs e)
{
    GL.Viewport(ClientRectangle);
    self.projection = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, Width / (float)Height, 1.0f, 1000f);
}
 

Перед рисованием геометрической матрицы установите единообразие матрицы:

 GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.Viewport(ClientRectangle);

for (n = 0; n < Models.Count; n  )
{
    GL.BindVertexArray(Models[n].VAO);

    Models[n].Shader.Use();
    Models[n].Shader.SetMatrix4("projection", self.projection);
    Models[n].Shader.SetMatrix4("transform", trans);

    if (Models[n].UseEBO)
        GL.DrawElements(Models[n].PrimitiveType, Models[n].DrawOrder.Length, DrawElementsType.UnsignedInt, 0);
    else
        GL.DrawArrays(Models[n].PrimitiveType, 0, Models[n].Vertices.Length);
}
SwapBuffers();
 

Комментарии:

1. Спасибо за ответ, но когда я добавляю проекцию, все объекты в сцене исчезают (на моем порту просмотра ничего не отображается), вам нужна другая информация о моем коде?

2. @HarugaHarumi Это еще одна проблема. Очень вероятно, что объекты обрезаны ближней плоскостью перспективной проекции. Обратите внимание, что объекты должны быть нарисованы между ближней и дальней плоскостями усеченного изображения . Необходимо сдвинуть объекты вдоль отрицательной оси z. (например, перевести -5 вдоль оси z)

3. Итак, если мои вершины cude равны (0,0,0) (20, 20, 20), он будет невидимым? или я все еще вижу какое-то лицо?

4. @HarugaHarumi Он невидим. Попробуйте диапазон от (0, 0, -10) до (20, 20, -30)

5. @ Rabbid76 Он появляется в моем окне просмотра, большое вам спасибо!! но теперь, когда я изменяю размер своей высоты элемента управления, куб масштабируется вместе с ним, но изменяет ширину. Это правильно?