我正在尝试使用opengl超级圣经和http://www.learnopengl.com/进入glsl。我想要的环境是opentk。
我试图将learnopengl.com的入门级教程“Hello Triangle”转换为opentk,这意味着使用非常简单的着色器绘制三角形,而不使用任何透视图/世界/模型转换。
我的结果只是颜色缓冲区,但否则一个空窗口,我只是不明白我在哪里犯了错误,所以任何帮助,在寻找和更重要的是理解他们将非常感谢。
我的opentk代码:
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using OpenTK;
using OpenTK.Graphics.OpenGL;
using OpenTK.Input;
namespace learnopengl.HelloTriangle
{
public class MainWindow : GameWindow
{
int _shaderId;
int _vao;
int _glbuf;
int _fragObj;
int _vertexObj;
Vector3[] _triangleVert;
public MainWindow()
: base(800,600)
{
KeyDown += MainWindow_KeyDown;
_triangleVert = new Vector3[] {
new Vector3(-0.5f, -0.5f, 0.0f),
new Vector3(0.5f, -0.5f, 0.0f),
new Vector3(-0.5f, 0.5f, 0.0f)
};
}
void MainWindow_KeyDown(object sender, KeyboardKeyEventArgs e)
{
if (e.Key == Key.Escape)
this.Exit();
if (e.Key == Key.F11)
if (this.WindowState == WindowState.Fullscreen)
this.WindowState = WindowState.Normal;
else
this.WindowState = WindowState.Fullscreen;
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
System.Diagnostics.Trace.WriteLine(string.Format("OpenGL version: {0}", GL.GetString(StringName.Version)));
GL.ClearColor(Color.Purple);
_vertexObj = GL.CreateShader(ShaderType.VertexShader);
_fragObj = GL.CreateShader(ShaderType.FragmentShader);
int statusCode;
string info;
GL.ShaderSource(_vertexObj, File.ReadAllText(@"shader\triangle.vert"));
GL.CompileShader(_vertexObj);
info = GL.GetShaderInfoLog(_vertexObj);
Console.Write(string.Format("triangle.vert compile: {0}",info));
GL.GetShader(_vertexObj, ShaderParameter.CompileStatus, out statusCode);
if (statusCode != 1) throw new ApplicationException(info);
GL.ShaderSource(_fragObj, File.ReadAllText(@"shader\triangle.frag"));
GL.CompileShader(_fragObj);
info = GL.GetShaderInfoLog(_fragObj);
Console.Write(string.Format("triangle.frag compile: {0}", info));
GL.GetShader(_fragObj, ShaderParameter.CompileStatus, out statusCode);
if (statusCode != 1) throw new ApplicationException(info);
_shaderId = GL.CreateProgram();
GL.AttachShader(_shaderId, _fragObj);
GL.AttachShader(_shaderId, _vertexObj);
GL.LinkProgram(_shaderId);
Console.Write(string.Format("link program: {0}", GL.GetProgramInfoLog(_shaderId)));
GL.UseProgram(_shaderId);
Console.Write(string.Format("use program: {0}", GL.GetProgramInfoLog(_shaderId)));
_vao = GL.GenVertexArray();
_glbuf = GL.GenBuffer();
GL.BindVertexArray(_vao);
GL.BindBuffer(BufferTarget.ArrayBuffer, _glbuf);
GL.BufferData<Vector3>(BufferTarget.ArrayBuffer, new IntPtr(Vector3.SizeInBytes * _triangleVert.Length), _triangleVert, BufferUsageHint.StaticDraw);
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, Vector3.SizeInBytes * _triangleVert.Length, 0);
GL.EnableVertexAttribArray(0);
GL.BindVertexArray(0);
}
protected override void OnResize(EventArgs e)
{
GL.Viewport(0, 0, Width, Height);
}
protected override void OnRenderFrame(FrameEventArgs e)
{
GL.Clear(ClearBufferMask.ColorBufferBit);
GL.BindVertexArray(_vao);
GL.DrawArrays(PrimitiveType.Triangles, 0, 3);
GL.BindVertexArray(0);
this.SwapBuffers();
}
protected override void OnUnload(EventArgs e)
{
GL.DeleteProgram(_shaderId);
GL.DeleteShader(_vertexObj);
GL.DeleteShader(_fragObj);
GL.DeleteVertexArray(_vao);
GL.DeleteBuffer(_glbuf);
base.OnClosed(e);
}
}
}
三角形.vert:
#version 330 core
layout(location = 0) in vec3 position;
void main()
{
gl_Position = vec4(position.x, position.y, position.z, 1.0f);
}
三角形.frag:
#version 330 core
//out vec4 color;
void main()
{
gl_FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);
//color = vec4(1.0f, 0.0f, 0.0f, 1.0f);
}
我的结果:
编辑:
使用来自注释的建议更新代码,但不会更改结果。
还验证了vbo是否正确填充了gdebugger:
编辑2:
我通过链接/使用着色器添加了信息日志,并将所有信息日志重新路由到控制台。我收到了一些可以忽略的警告。
我还测试了如果从所有着色器中移除float后缀是否发生任何更改,但所有内容都保持不变。
最佳答案
终于找到了问题的答案,那就是:
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, Vector3.SizeInBytes * _triangleVert.Length, 0);
第5个参数只指定单个属性的大小,而不是整个数组的大小:
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, Vector3.SizeInBytes, 0);
现在,它的工作,因为它应该,谢谢所有有帮助的评论!