调试:
视觉错误与CPU调试不同,在GLSL代码中也不能设置断点,出现错误的时候寻找错误的源头可能会非常困难。
glGetError()
GLenum glGetError();返回整形数字,查询错误标记,但是当一个错误标记被返回的时候,将不会报告其它的错误标记。
因此根据这个特性,代码中通常使用大量的glGetError()函数(间隔尽量小),以便确定错误发生的的大致位置
为了显示更多的信息,可以写一个错误检测宏,它返回错误类型,文件名,和行数
如果你使用GLEW库,调用glewInit()会设置一个GL_INVALID_ENUM的错误标记,所以首先需要glewInit之后立即调用glGetError消除这个标记
调试输出
更为完善的错误或警告信息给用户,只有4.3以上的openGL版本支持
在调用glfwCreateWindow之前提醒到GLFW中:调试输出启用glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
检查我们是否成功地初始化了调试上下文,我们可以对OpenGL进行查询。GL_CONTEXT_FLAG_DEBUG_BIT
调试输出回调函数,在这里我们将输出一些有用的错误数据到控制台中。
void APIENTRY glDebugOutput(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, void *userParam);
可以通过glDebugMessageControl()过滤出你需要的错误类型
调式输出可以很容易的找出错误发生的准确行号或者调用,通过在glDebugOutput()中(特定的错误类型上)设置一个断点,查找调用栈(vs的Call Stack)直到找到消息发出的源头。
我们也可以使用glDebugMessageInsert将自定义信息推送到调试输出系统:
着色器调试
因为shader无法断点或者输出日志,所以只能用颜色来调试
通常将所有相关的变量直接发送到片段着色器的输出通道,以评估它们
比如法线可视化
参考编译器
不同的显卡商(AMD,NVidia,以及Intel)的GLSL间有不同的细微差别,如果你想要保证你的着色器代码在所有的机器上都能运行,可以直接使用官方的参考编译器(语言校验器),你可以很方便的检查你的着色器代码规范
GLSL语言校验器是通过下列固定的后缀名来决定着色器的类型的
- .vert:顶点着色器(Vertex Shader)
- .frag:片段着色器(Fragment Shader)
- .geom:几何着色器(Geometry Shader)
- .tesc:细分控制着色器(Tessellation Control Shader)
- .tese:细分计算着色器(Tessellation Evaluation Shader)
- .comp:计算着色器(Compute Shader)
帧缓冲输出
在OpenGL程序中一块特定区域显示帧缓冲的内容
……