使用OpenTK的GL.CreateShader上的AccessViolationException

时间:2017-08-23 18:21:25

标签: c# .net opengl 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类和从其继承的所有类都具有绘制函数,这些函数将通过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");
    }

1 个答案:

答案 0 :(得分:0)

感谢所有就此问题提供建议的人。经过一夜的睡眠,我找到了问题的解决方案。我在主渲染线程的单独线程上运行代码。这显然不适用于OpenGL的本质。