Не рисуется куб OpenGL

Рейтинг: 0Ответов: 0Опубликовано: 22.03.2023

Задача следующая: нужно создать куб цветовой модели RGB и реализовать вращение камеры вокруг него клавишами W, A, S, D. Написал следующий код:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL4;
using OpenTK.Input;
using System.IO;
using System.Diagnostics;
using System.Drawing.Text;
using AGU_lr2;

namespace AGU_lr2
{
    public partial class MainWindow : GameWindow
    {
        private Color4 backColor = new Color4(0.1f, 0.1f, 0.3f, 1.0f);
        private const float fovY = (float)Math.PI / 4;
        private const float nearDistance = 0.1f;
        private const float farDistance = 100.0f;

        private float cameraPositionAngleXAxis = 0.0f;
        private float cameraPositionAngleYAxis = 0.0f;
        private float cameraPositionAngleDelta = (float)Math.PI / 36;
        private float cameraPositionDistanceFromOrigin = 5.0f;
        private Vector4 startEye = new Vector4(0.0f, 0.0f, 0.0f, 1.0f);
        private Vector4 viewTarget = new Vector4(0.0f, 0.0f, 0.0f, 1.0f);
        private Vector4 viewYUp = new Vector4(0.0f, 1.0f, 0.0f, 1.0f);

        private int program;

        private int cubeVertexArray;
        private int cubeVertexBuffer;
        private int cubeColorBuffer;

        private double time;

        private Matrix4 modelMatrix;
        private Matrix4 viewMatrix;
        private Matrix4 projectionMatrix;
        private Matrix4 mvpMatrix;

        private int mvpMatrixLocation;
        public MainWindow() : base(
            800, 600, GraphicsMode.Default, "", GameWindowFlags.Default,
            DisplayDevice.Default, 4, 4, GraphicsContextFlags.Debug
            )
        {
            Title += "OpenGL version: " + GL.GetString(StringName.Version);
            Load += MainWindow_Load;
            Resize += MainWindow_Resize;
            KeyDown += MainWindow_KeyDown;
            RenderFrame += MainWindow_RenderFrame;
        }

        private int CompileShader(ShaderType type, string path)
        {
            var shader = GL.CreateShader(type);
            var src = File.ReadAllText(path);
            GL.ShaderSource(shader, src);
            GL.CompileShader(shader);
            var info = GL.GetShaderInfoLog(shader);
            if(!string.IsNullOrWhiteSpace(info))
            {
                Debug.WriteLine($"GL.CompileShader [{type}] had info log: {info}");
            }
            return shader;
        }

        private int CreateProgram()
        {
            var program = GL.CreateProgram();
            var shaders = new List<int>();
            shaders.Add(CompileShader(ShaderType.VertexShader, "vertexShader.glsl"));
            shaders.Add(CompileShader(ShaderType.FragmentShader, "fragmentShader.glsl"));
            foreach(var shader in shaders)
            {
                GL.AttachShader(program, shader);
            }
            GL.LinkProgram(program);
            var info = GL.GetProgramInfoLog(program);
            if(!string.IsNullOrWhiteSpace(info))
            {
                Debug.WriteLine($"GL.LinkProgram had info log: {info}");
            }
            foreach(var shader in shaders)
            {
                GL.DetachShader(program, shader);
                GL.DeleteShader(shader);
            }
            return program;
        }

        private void MainWindow_Load(object sender, EventArgs e)
        {
            Vector4[] cubeVertices =
            {
                new Vector4(-0.5f, -0.5f, -0.5f, 1.0f), // #0 bottom left back black
                new Vector4(0.5f, -0.5f, -0.5f, 1.0f), // #1 bottom right back red
                new Vector4(0.5f, 0.5f, -0.5f, 1.0f), // #2 top right back yellow
                new Vector4(-0.5f, 0.5f, -0.5f, 1.0f), // #3 top left back green
                new Vector4(-0.5f, 0.5f, 0.5f, 1.0f), // #4 top left front cyan
                new Vector4(-0.5f, -0.5f, 0.5f, 1.0f), // #5 bottom left front blue
                new Vector4(0.5f, -0.5f, 0.5f, 1.0f), // #6 bottom right front magenta
                new Vector4(0.5f, 0.5f, 0.5f, 1.0f) // #7 top right front white
            };
                Color4[] cubeColors =
                {
                    new Color4(0.0f, 0.0f, 0.0f, 0.4f), // #0 bottom left back black
                    new Color4(1.0f, 0.0f, 0.0f, 0.4f), // #1 bottom right back red
                    new Color4(1.0f, 1.0f, 0.0f, 0.4f), // #2 top right back yellow
                    new Color4(0.0f, 1.0f, 0.0f, 0.4f), // #3 top left bac green
                    new Color4(0.0f, 1.0f, 1.0f, 0.4f), // #4 top left fron cyan
                    new Color4(0.0f, 0.0f, 1.0f, 0.4f), // #5 bottom left fron blue
                    new Color4(1.0f, 0.0f, 1.0f, 0.4f), // #6 bottom right front magenta
                    new Color4(1.0f, 1.0f, 1.0f, 0.4f) // #7 top right fron white
                };

                CursorVisible = true;

                program = CreateProgram();
                mvpMatrixLocation = GL.GetUniformLocation(program, "mvpMatrix");

                cubeVertexArray = GL.GenVertexArray();
                GL.BindVertexArray(cubeVertexArray);
                cubeVertexBuffer = GL.GenBuffer();
                GL.BindBuffer(BufferTarget.ArrayBuffer, cubeVertexBuffer);
                Vector4[] vertices =
                {
                    cubeVertices[0], cubeVertices[3], cubeVertices[2],
                    cubeVertices[2], cubeVertices[1], cubeVertices[0], // back
                    cubeVertices[0], cubeVertices[5], cubeVertices[4],
                    cubeVertices[4], cubeVertices[3], cubeVertices[0], // left
                    cubeVertices[0], cubeVertices[1], cubeVertices[6],
                    cubeVertices[6], cubeVertices[5], cubeVertices[0], // bottom
                    cubeVertices[7], cubeVertices[4], cubeVertices[5],
                    cubeVertices[5], cubeVertices[6], cubeVertices[7], // front
                    cubeVertices[7], cubeVertices[6], cubeVertices[1],
                    cubeVertices[1], cubeVertices[2], cubeVertices[7], // right
                    cubeVertices[7], cubeVertices[2], cubeVertices[3],
                    cubeVertices[3], cubeVertices[4], cubeVertices[7] // top
                };
                GL.BufferData(BufferTarget.ArrayBuffer, Vector4.SizeInBytes * vertices.Length, vertices, BufferUsageHint.StaticDraw);
                GL.EnableVertexAttribArray(0);
                GL.VertexAttribPointer(0, 4, VertexAttribPointerType.Float, false, 0, 0);

                cubeColorBuffer = GL.GenBuffer();
                GL.BindBuffer(BufferTarget.ArrayBuffer, cubeColorBuffer);
                Color4[] colors =
                {
                    cubeColors[0], cubeColors[3], cubeColors[2], cubeColors[2], cubeColors[1], cubeColors[0], // back
                    cubeColors[0], cubeColors[5], cubeColors[4], cubeColors[4], cubeColors[3], cubeColors[0], // left
                    cubeColors[0], cubeColors[1], cubeColors[6], cubeColors[6], cubeColors[5], cubeColors[0], // bottom
                    cubeColors[7], cubeColors[4], cubeColors[5], cubeColors[5], cubeColors[6], cubeColors[7], // front
                    cubeColors[7], cubeColors[6], cubeColors[1], cubeColors[1], cubeColors[2], cubeColors[7], // right
                    cubeColors[7], cubeColors[2], cubeColors[3], cubeColors[3], cubeColors[4], cubeColors[7] // top
                };

                GL.BufferData(BufferTarget.ArrayBuffer, 16 * colors.Length, colors, BufferUsageHint.StaticDraw);
                GL.EnableVertexAttribArray(1);
                GL.VertexAttribPointer(1, 4, VertexAttribPointerType.Float, false, 0, 0);
                GL.PolygonMode(MaterialFace.Front, PolygonMode.Fill);
                GL.Enable(EnableCap.DepthTest);
                GL.DepthFunc(DepthFunction.Less);
        }

        private void UpdateMatrices()
        { 
            modelMatrix = Matrix4.Identity; 
            if (cameraPositionAngleXAxis > (float) Math.PI)
            { 
                cameraPositionAngleXAxis -= (float)Math.PI * 2.0f; 
            } 
            else if (cameraPositionAngleXAxis<(float)-Math.PI) 
            { 
                cameraPositionAngleXAxis += (float) Math.PI * 2.0f;
            } 
            if (cameraPositionAngleYAxis > (float) Math.PI)
            { 
                cameraPositionAngleYAxis -= (float)Math.PI * 2.0f;
            } 
            else if (cameraPositionAngleYAxis<(float)-Math.PI) 
            { 
                cameraPositionAngleYAxis += (float) Math.PI * 2.0f;
            }
            Vector4 eye = startEye;
            eye.Z = cameraPositionDistanceFromOrigin;
            viewMatrix = Matrix4.CreateRotationY(cameraPositionAngleYAxis) *
            Matrix4.CreateRotationX(cameraPositionAngleXAxis) *
            Matrix4.LookAt(
                eye.X, eye.Y, eye.Z,
                viewTarget.X, viewTarget.Y, viewTarget.Z,
                viewYUp.X, viewYUp.Y, viewYUp.Z
            );
            mvpMatrix = modelMatrix * viewMatrix * projectionMatrix;
        }

        private void MainWindow_RenderFrame(object sender, FrameEventArgs e)
        {
            Title = $" (VSync: {VSync}) FPS: {1f / e.Time:0}"; 
            time += e.Time;
            UpdateMatrices();
            GL.ClearColor(backColor);
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
            GL.UseProgram(program);
            GL.UniformMatrix4(mvpMatrixLocation, false, ref mvpMatrix);
            GL.DrawArrays(PrimitiveType.Triangles, 0, 36);

            SwapBuffers();
        }

        private void MainWindow_KeyDown(object sender, KeyboardKeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.A:
                {
                    cameraPositionAngleYAxis += cameraPositionAngleDelta;
                    break;
                }
                case Key.D:
                {
                    cameraPositionAngleYAxis -= cameraPositionAngleDelta;
                    break;
                }
                case Key.S:
                {
                    cameraPositionAngleXAxis -= cameraPositionAngleDelta;
                    break;
                }
                case Key.W:
                {
                    cameraPositionAngleXAxis += cameraPositionAngleDelta;
                    break;
                }
                case Key.Escape:
                {
                    Exit();
                    break;
                }
            }
        }

        private void MainWindow_Resize(object sender, EventArgs e)
        {
            GL.Viewport(0, 0, Width, Height);
            float aspectRatio = Width / (float)Height;
            projectionMatrix = Matrix4.CreatePerspectiveFieldOfView(fovY, aspectRatio, nearDistance, farDistance);
        }

        protected override void Dispose(bool manual)
        {
            GL.DisableVertexAttribArray(1);
            GL.DisableVertexAttribArray(0);
            GL.DeleteBuffer(cubeColorBuffer);
            GL.DeleteBuffer(cubeVertexBuffer);
            GL.DeleteVertexArray(cubeVertexArray);
            GL.DeleteProgram(program);
        }
    }
}

Но куб не отрисовывается, вместо этого на его месте появляется белый прямоугольник.(см. изображение)Результат выполнения кода

И вроде бы перепроверил всё уже раз 10, не понимаю в чём дело. Приложение WindowsForms .NET Framework 4.7.2 openTK последняя третья версия.

Ответы

Ответов пока нет.