OpenGL常犯的错误及查错方法总结
实践告诉我,OpenGL程序的调试是最让人头大的,因为完全不知道哪里错,在此根据以前爬过的坑,简单总结一下纠错方法,希望对后来者有帮助:
1. 着色器的编译检查
即着色器在语法上能不能通过。
这里要用到glGetShaderiv()
函数,具体用法如下,可以用来检测编译状态的。
int success1 = 0;
glGetShaderiv(vertexShader,GL_COMPILE_STATUS,&success1);
if(!success1)
{
cout << "failed to compile VertexShader" << endl;
}
但有时候明明知道某个着色器编译没通过,但就是不知道在哪出错,这个时候可以用glGetShaderInfoLog
函数,打印出具体报错信息
int success1 = 0;
glGetShaderiv(vertexShader,GL_COMPILE_STATUS,&success1);
if(!success1)
{
cout << "failed to compile VertexShader" << endl;
char log[512];
glGetShaderInfoLog(vertexShader,512,NULL,log);
cout << log << endl;
}
举个例子,比如fragmentShader这样写:
#version 330 core
out vec4 ourColor;
void main()
{
ourColor=vec4(0.2f,0.5f,0.6f,1.0f);s
}
就会这样报错:
这里的0:5,的5是行数,这样就容易找到报错的位置啦。
2. 着色器之间的链接检查
顶点着色器和片元着色器都编译成功,但其中的linkProgram也可能出现问题,简单的链接问题可以用glGetProgramiv和glGetProgramInfoLog来找到错误。
此外出错还可能是这个原因:
检查着色器之间的衔接部分,需要注意着色器之间传递的变量名一定要一模一样,比如顶点着色器输出out vec4 FragColor
,那么片元着色器名字一定要一样in vec4 FragColor
3. 除了基本的编译错误,接下来就是比较难找的地方了, 主要有以下几点:
检查自己的API有没有写对
OpenGL的API实在是太多,而且很多很相似,这些API一个字母写错,可能就会导致整个程序有问题。。。。
传入的Uniform名字和着色器的名字一定要相同
我就爬过这个坑,cpp里写的是project
矩阵,结果顶点着色器里的名字是projection
,最后找了很久
检查片元着色器
如果想检查片元着色器是不是可用的的,可以试试直接设置输出颜色FragColor=vec4(1.0f,0.0f,0.0f,1.0f)
, 如果输出红色说明是可用的。
VAO从VBO中获取数据
获取数据时一定要注意VBO中的数据格式和VAO中的数据格式是不是吻合的
另外的一些细节
- 有一次只出现了 窗口,看不到绘制的图形,最后才发现,自己的glSwapBuffer和glDarwArrays函数写反了,在Loop里面,glSwapBuffer函数一定要在调用draw call的后面!!
- OpenGL是一个状态机,很多API有着严格的执行顺序,比如VAO必须先于EBO绑定,在传入Uniform时,必须先调用glUseProgram函数, 这些顺序需要额外注意一下。
PS
如果是用的Vs studio,可以安装如下文本工具,达到如下颜色效果,帮助自己编码:
具体方法如下:
1.点击工具---->拓展和更新
2.选择联网----->输入GLSL,搜索后下载安装,之后重启visual studio就行。