OpenTK GL.CreateShader 上的 AccessViolationException
AccessViolationException on GL.CreateShader with OpenTK
我在将着色器集成到我的程序中时遇到了一些问题。到目前为止,我一直在使用默认管道,但它不再能够完成我想做的所有事情。我整理了一些我认为应该可以使用的代码。
创建和编译着色器的代码:
public int CompileShaders()
{
int vertexShader = GL.CreateShader(ShaderType.VertexShader);
string shader = System.IO.File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + @"Shaders\test.vert");
GL.ShaderSource(vertexShader, shader);
GL.CompileShader(vertexShader);
int fragmentShader = GL.CreateShader(ShaderType.FragmentShader);
shader = System.IO.File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + @"Shaders\test.frag");
GL.ShaderSource(fragmentShader, shader);
GL.CompileShader(fragmentShader);
int shaderProgram = GL.CreateProgram();
GL.AttachShader(shaderProgram, vertexShader);
GL.AttachShader(shaderProgram, fragmentShader);
GL.LinkProgram(shaderProgram);
GL.DetachShader(shaderProgram, vertexShader);
GL.DetachShader(shaderProgram, fragmentShader);
GL.DeleteShader(vertexShader);
GL.DeleteShader(fragmentShader);
_shaderProgram = shaderProgram;
return shaderProgram;
}
当命中此代码时,对 GL.CreateShader 的第一次调用会抛出 AccessViolationException。令人困惑的一点是大多数关于此问题的其他文章都处理尚未初始化的 OpenGL 上下文。但是,我的程序的 GLContext 早在这段代码 运行 之前就已经初始化并使用了(因为我已经绘制了它并将其显示在屏幕上)。我还在 GLControl Load 事件处理程序中测试了 运行 这段代码,运行 没问题。
要详细了解代码的结构,存在一个包含 GLLayers 的 GLScene。这些层然后包含 GLEntities 形式的几何体,它可以是众多类型中的一种,例如 GLMesh。编译着色器和维护对着色器程序的引用的代码是 GLEntity 的一部分。 GLEntity class 和所有从它继承的 classes 都有绘制函数,这些函数将通过 GL.UseProgram 命令使用着色器。所以程序中的事件顺序如下。该程序打开并初始化内部变量以及带有视口的 OpenGL 上下文。然后用户打开一个文件,此时生成几何图形并将其添加到 GLScene 中的层。几何生成完成后,着色器应该可以编译了。
你们中有人知道是什么导致了这个问题吗?
感谢您的帮助。
编辑:为 GLContext 添加了初始化代码
OpenTK.Toolkit.Init();
InitializeComponent();
OpenTK.Graphics.GraphicsMode gm = new OpenTK.Graphics.GraphicsMode(32, 24, 8, 8);
_glControl = new OpenTK.GLControl(gm);
winFormsHost.Child = _glControl;
public void GLControl_Load(object sender, EventArgs e)
{
_camera = new GLCamera();
_camera.Viewport = new Rectangle(0, 0, _mainVM.GLControl.Width, _mainVM.GLControl.Height);
_logger.Info("Camera initialized");
_mainVM.LoadSettings();
_logger.Info("Settings loaded by ViewTool");
}
感谢所有就此问题提出建议的人。经过一夜的睡眠,我找到了解决问题的方法。我是 运行 与主渲染线程不同的线程上的代码。这显然不符合 OpenGL 的性质。
我在将着色器集成到我的程序中时遇到了一些问题。到目前为止,我一直在使用默认管道,但它不再能够完成我想做的所有事情。我整理了一些我认为应该可以使用的代码。
创建和编译着色器的代码:
public int CompileShaders()
{
int vertexShader = GL.CreateShader(ShaderType.VertexShader);
string shader = System.IO.File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + @"Shaders\test.vert");
GL.ShaderSource(vertexShader, shader);
GL.CompileShader(vertexShader);
int fragmentShader = GL.CreateShader(ShaderType.FragmentShader);
shader = System.IO.File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + @"Shaders\test.frag");
GL.ShaderSource(fragmentShader, shader);
GL.CompileShader(fragmentShader);
int shaderProgram = GL.CreateProgram();
GL.AttachShader(shaderProgram, vertexShader);
GL.AttachShader(shaderProgram, fragmentShader);
GL.LinkProgram(shaderProgram);
GL.DetachShader(shaderProgram, vertexShader);
GL.DetachShader(shaderProgram, fragmentShader);
GL.DeleteShader(vertexShader);
GL.DeleteShader(fragmentShader);
_shaderProgram = shaderProgram;
return shaderProgram;
}
当命中此代码时,对 GL.CreateShader 的第一次调用会抛出 AccessViolationException。令人困惑的一点是大多数关于此问题的其他文章都处理尚未初始化的 OpenGL 上下文。但是,我的程序的 GLContext 早在这段代码 运行 之前就已经初始化并使用了(因为我已经绘制了它并将其显示在屏幕上)。我还在 GLControl Load 事件处理程序中测试了 运行 这段代码,运行 没问题。
要详细了解代码的结构,存在一个包含 GLLayers 的 GLScene。这些层然后包含 GLEntities 形式的几何体,它可以是众多类型中的一种,例如 GLMesh。编译着色器和维护对着色器程序的引用的代码是 GLEntity 的一部分。 GLEntity class 和所有从它继承的 classes 都有绘制函数,这些函数将通过 GL.UseProgram 命令使用着色器。所以程序中的事件顺序如下。该程序打开并初始化内部变量以及带有视口的 OpenGL 上下文。然后用户打开一个文件,此时生成几何图形并将其添加到 GLScene 中的层。几何生成完成后,着色器应该可以编译了。
你们中有人知道是什么导致了这个问题吗?
感谢您的帮助。
编辑:为 GLContext 添加了初始化代码
OpenTK.Toolkit.Init();
InitializeComponent();
OpenTK.Graphics.GraphicsMode gm = new OpenTK.Graphics.GraphicsMode(32, 24, 8, 8);
_glControl = new OpenTK.GLControl(gm);
winFormsHost.Child = _glControl;
public void GLControl_Load(object sender, EventArgs e)
{
_camera = new GLCamera();
_camera.Viewport = new Rectangle(0, 0, _mainVM.GLControl.Width, _mainVM.GLControl.Height);
_logger.Info("Camera initialized");
_mainVM.LoadSettings();
_logger.Info("Settings loaded by ViewTool");
}
感谢所有就此问题提出建议的人。经过一夜的睡眠,我找到了解决问题的方法。我是 运行 与主渲染线程不同的线程上的代码。这显然不符合 OpenGL 的性质。