You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何基于C#+OpenTK的OpenGL代码无法渲染简单矩形?

OpenGL渲染矩形失效问题排查

我是C#和OpenGL的新手,在此先为可能出现的低级错误致歉。

我尝试使用OpenTK渲染一个简单矩形,跟随一系列教程学习后,已经掌握了大致的实现步骤,甚至曾经成功渲染出矩形效果:

成功渲染的彩色矩形

但不知为何,在我尝试修改顶点Shader代码(尝试将常规坐标转换为NDC)后,渲染功能完全失效。我甚至没有改动游戏窗口代码(至少我没有相关记忆)。这让我非常困扰,因为我找不到问题所在。现在的显示效果如下:

仅显示背景色的窗口

注意:背景色不同是因为我修改了它。

我猜测问题要么出在Shader代码上,要么是绑定相关的问题,但我不确定。如果有人能帮我解决,我将非常感激!


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

内容的提问来源于stack exchange,提问作者Leah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 03:28:09