为何基于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
相关产品推荐
相关产品推荐

