为什么我的代码没有呈现一个非常简单的矩形?

问题描述 投票:0回答:1

我对 C# 和 OpenGL 都很陌生。所以我提前为任何愚蠢的错误道歉。

我正在尝试使用 OpenTK 渲染一个简单的矩形。我已经学习了很多教程并开始了解究竟需要做什么。事实上,我能够一次渲染它

出于某种原因,在我尝试修改顶点着色器代码(尝试将法线坐标转换为 NDC)之后,一切都停止了。我什至没有触摸我的游戏窗口代码(至少我没有回忆)。所以这真的让我很沮丧,因为我似乎无法找出问题所在。这是现在出现的:

注意:背景颜色不同,因为我改变了它。

我的猜测是它要么是着色器代码,要么是一些绑定问题。我不太确定。如果有人能帮助我,我将不胜感激!

文件如下:

Game.cs

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

namespace Test
{
    public class Game : GameWindow
    {

        private int vertexBufferHandle;
        private int colorBufferHandle;
        private int indexBufferHandle;
        private int vertexArrayHandle;

        private Shader shader;

        private readonly float[] vertices = new float[]
        {
            -0.7f, -0.5f, 0.0f,
            -0.7f,  0.5f, 0.0f,
             0.7f, -0.5f, 0.0f,
             0.7f,  0.5f, 0.0f
        };

        private readonly float[] colors = new float[]
        {
            1.0f, 0.0f, 0.0f, 1.0f,
            0.0f, 1.0f, 0.0f, 1.0f,
            0.0f, 0.0f, 1.0f, 1.0f,
            1.0f, 0.0f, 1.0f, 1.0f
        };

        private readonly uint[] indices = new uint[]
        {
            0, 1, 2,
            2, 1, 3
        };

        public Game(int width, int height, string title = "Game") : base(GameWindowSettings.Default, new NativeWindowSettings()
        {
            Title = title,
            Size = new Vector2i(width, height),
            WindowBorder = WindowBorder.Fixed,
            StartVisible = false,
            StartFocused = true,
            API = ContextAPI.OpenGL,
            Profile = ContextProfile.Core,
            APIVersion = new Version(4, 1)
        })
        {
            this.CenterWindow();
        }

        protected override void OnLoad()
        {
            this.IsVisible = true;

            GL.ClearColor(Color4.AliceBlue);

            this.vertexBufferHandle = GL.GenBuffer();
            GL.BindBuffer(BufferTarget.ArrayBuffer, this.vertexBufferHandle);
            GL.BufferData(BufferTarget.ArrayBuffer, vertices.Length * sizeof(float), vertices, BufferUsageHint.StaticDraw);
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);

            this.colorBufferHandle = GL.GenBuffer();
            GL.BindBuffer(BufferTarget.ArrayBuffer, this.colorBufferHandle);
            GL.BufferData(BufferTarget.ArrayBuffer, colors.Length * sizeof(float), colors, BufferUsageHint.StaticDraw);
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);

            this.indexBufferHandle = GL.GenBuffer();
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, this.indexBufferHandle);
            GL.BufferData(BufferTarget.ElementArrayBuffer, indices.Length * sizeof(float), indices, BufferUsageHint.StaticDraw);
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);

            vertexArrayHandle = GL.GenVertexArray();
            GL.BindVertexArray(vertexArrayHandle);

            GL.BindBuffer(BufferTarget.ArrayBuffer, this.vertexBufferHandle);
            GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 3 * sizeof(float), 0);
            GL.EnableVertexAttribArray(0);

            GL.BindBuffer(BufferTarget.ArrayBuffer, this.colorBufferHandle);
            GL.VertexAttribPointer(1, 4, VertexAttribPointerType.Float, false, 4 * sizeof(float), 0);
            GL.EnableVertexAttribArray(1);

            GL.BindBuffer(BufferTarget.ElementArrayBuffer, this.indexBufferHandle);

            GL.BindVertexArray(0);

            shader = new Shader("Shader/shader.vert", "Shader/shader.frag");

            base.OnLoad();

        }

        protected override void OnRenderFrame(FrameEventArgs args)
        {
            GL.Clear(ClearBufferMask.ColorBufferBit);

            shader.Use();
            GL.BindVertexArray(vertexArrayHandle);
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, indexBufferHandle);
            GL.DrawElements(PrimitiveType.Triangles, 6, DrawElementsType.UnsignedInt, 0);
            // GL.BindVertexArray(0);

            Context.SwapBuffers();
            base.OnRenderFrame(args);
        }

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

        protected override void OnUnload()
        {
            
            GL.BindVertexArray(0);
            GL.DeleteVertexArray(vertexArrayHandle);

            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);

            GL.DeleteBuffer(this.vertexBufferHandle);
            GL.DeleteBuffer(this.colorBufferHandle);

            GL.UseProgram(0);
            GL.DeleteProgram(shader.ProgramHandle);

            base.OnUnload();
        }
    }
}

Program.cs

using System;

namespace Test
{
    class Rectangle
    {
        static void Main(string[] args)
        {
            using(Game game = new Game(width: 400, height: 400))
            {
                game.Run();
            };
        }
    }
}

Shader.cs

using System;
using OpenTK.Graphics.OpenGL4;

namespace Test
{
    public class Shader
    {

        public int ProgramHandle;

        public Shader(string vert, string frag)
        {
            string vertexShaderCode = File.ReadAllText("../../../" + vert);
            string fragmentShaderCode = File.ReadAllText("../../../" + frag);

            int vertexShaderHandle = GL.CreateShader(ShaderType.VertexShader);
            GL.ShaderSource(vertexShaderHandle, vertexShaderCode);

            int fragmentShaderHandle = GL.CreateShader(ShaderType.FragmentShader);
            GL.ShaderSource(fragmentShaderHandle, fragmentShaderCode);

            Console.Write(GL.GetShaderInfoLog(vertexShaderHandle));
            Console.Write(GL.GetShaderInfoLog(fragmentShaderHandle));

            GL.CompileShader(vertexShaderHandle);
            GL.CompileShader(fragmentShaderHandle);

            this.ProgramHandle = GL.CreateProgram();
            GL.AttachShader(this.ProgramHandle, vertexShaderHandle);
            GL.AttachShader(this.ProgramHandle, fragmentShaderHandle);

            GL.LinkProgram(this.ProgramHandle);

            GL.DetachShader(this.ProgramHandle, vertexShaderHandle);
            GL.DetachShader(this.ProgramHandle, fragmentShaderHandle);

            GL.DeleteShader(vertexShaderHandle);
            GL.DeleteShader(fragmentShaderHandle);
        }

        public void Use()
        {
            GL.UseProgram(ProgramHandle);
        }
    }
}

(我没有从

GL.GetShaderInfoLog
中得到任何错误)

shader.vert

#version 410

layout(location = 0) in vec3 aPosition;
layout(location = 1) in vec4 aColor;
out vec4 vColor;

void main(void){
    vColor = aColor;
    gl_Position = vec4(aPosition, 1f);
}

shader.frag

#version 410

in vec4 vColor;
out vec4 outputColor;

void main()
{
    outputColor = vColor;
}
c# opengl opentk
1个回答
1
投票

这很狡猾,但是

1f
在 GLSL 中不是有效的浮点常量。

官方语法是:

1f
是带有
digit-sequence
floating-suffix
,但这不是选项之一。要么需要一个
exponent-part
,要么需要一个点来将
digit-sequence
变成
fractional-constant

我没有从 GL.GetShaderInfoLog 得到任何错误

如果你在编译着色器后调用它,你应该得到一个。

© www.soinside.com 2019 - 2024. All rights reserved.