【发布时间】:2017-08-24 21:36:59
【问题描述】:
我在将着色器集成到我的程序中时遇到了一些问题。到目前为止,我一直在使用默认管道,但它不再能够完成我想做的所有事情。我已经收集了一些我认为应该可以工作的代码。
创建和编译着色器的代码:
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");
}
【问题讨论】:
-
@Ripi2 我确实遇到了这个问题。不幸的是,这似乎是作者将着色器代码转换为字符和字符串数组并且没有正确通知 OpenGL 所述数组的长度的问题。在这里,我只是将一个大字符串传递给 OpenGL。我也已经验证了代码可以正常工作(至少它会毫无例外地运行)。
-
代码运行与否。嗯?
-
提供创建上下文的代码。您可能不要求正确的版本。我无法想象
CreateShader失败的其他解释.. -
@Ripi2 我已经添加了创建 GLControl 的代码。这是 OpenTK 中的一个内置类,它将创建上下文。另请注意,虽然未在此处列出,但 Load 事件已正确设置。响应代码是否运行,目前没有。但是,我通过从上述加载事件处理程序调用 CompileShaders 来测试代码,并且它确实在那时运行。当我在 GLEntity 类中调用它时,它失败了。抱歉,如果我没有说清楚。