c# - 为什么我的代码没有渲染一个非常简单的矩形?

标签 c# opengl opentk

我对 C# 和 OpenGL 都很陌生。因此,对于任何愚蠢的错误,我提前表示歉意。

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

出于某种原因,在我尝试摆弄顶点着色器代码(尝试将法线坐标转换为 NDC)后,一切都停止工作。我什至没有碰过我的游戏窗口代码(至少我不记得了)。所以这真的让我很沮丧,因为我似乎无法找出出了什么问题。现在出现的是这样的:

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

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

以下是文件:

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);
}

着色器.frag

#version 410

in vec4 vColor;
out vec4 outputColor;

void main()
{
    outputColor = vColor;
}

最佳答案

这是偷偷摸摸的,但 1f 不是 GLSL 中的有效浮点常量。

官方语法是:

GLSL floating point constant

1f 是一个带有 float 后缀数字序列,但这不是选项之一。需要有一个指数部分,或者一个点才能将数字序列转换为小数常数

I don't get any errors from the GL.GetShaderInfoLog

如果您在编译着色器之后调用此函数,您应该得到一个。

关于c# - 为什么我的代码没有渲染一个非常简单的矩形?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75645813/

相关文章:

c# - 是否可以使用 VSPackage 添加新项目向导?

c# - 在 C# 中构建代理

opengl - 3d 遮挡剔除

java - 千个 Sprite 绘制效果不佳

c# - OpenGL - 如何创建和绑定(bind)立方体贴图数组?

c# - 无法让模板缓冲区在 OpenTK 中工作,简单的 2D 四边形

c# - Xamarin Forms ListView 数据绑定(bind)

c# - 在没有 N+1 的情况下通过 NHibernate 进行查询 - 包含示例

在没有 XCode 的情况下使用 CGL/NSOpenGL 在 OSX 上使用 OpenGL 的 C++ 代码?

c# - 如何在 OpenTK 中设置无限 FPS?