OpenGL调试(1)

一、简介
图形编程因为存在大量的接口函数,并且它们对于参数都有严格的定义,因此在有些情况下就会发生什么东西渲染错了,甚至于根本就没有渲染。同时由于我们的大部分时间都在与像素打交道,当出现了错误的时候寻找错误的源头可能会非常的困难。调试这样的视觉错误与往常熟悉的CPU调试不同,我们没有一个可以用来输出文本的控制台,在GLSL代码中也不能设置断点,更没有方法来检测CPU的运行状态。

二、OpenGL调试
当我们不正确使用了OpenGL的时候,glGetError()函数可以检测到,并在幕后生成一个或者多个用户错误标记,同时它也会检测错误集,并在OpenGL确实出错的时候返回一个错误值。
Glenum glGetError();
当glGetError被调用时,它的返回值信息如下:
在这里插入图片描述
在OpenGL的函数文档中可以找到函数在生成不同错误的原因,它可以帮助我们快速的定位到错误原因,方便我们解决问题。同时当一个错误标记被返回时,将不会报告其他的错误,也就是说当glGetError被调用时,它会清除所有的错误标记,这也就说如果你在每一帧之后调用glGetError一次,它返回一个错误,但你不能确定这就是唯一的错误,并且错误的来源可能在这一帧的任意地方。
glBindTexture(GL_TEXTURE_2D, tex);
std::cout << glGetError() << std::endl; // 返回 0 (无错误)
glTexImage2D(GL_TEXTURE_3D, 0, GL_RGB, 512, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
std::cout << glGetError() << std::endl; // 返回 1280 (非法枚举)
glGenTextures(-5, textures);
std::cout << glGetError() << std::endl; // 返回 1281 (非法值) std::cout << glGetError() << std::endl; // 返回 0 (无错误)
glGetError最强的地方在于它能够非常简单的定位错误可能的来源,并且验证OpenGL使用的正确性。同时默认的情况下glGetError只会打印错误数字。

GLenum glCheckError_(const char *file, int line)
{
GLenum errorCode;
while ((errorCode = glGetError()) != GL_NO_ERROR)
{
std::string error;
switch (errorCode)
{
case GL_INVALID_ENUM: error = “INVALID_ENUM”; break;
case GL_INVALID_VALUE: error = “INVALID_VALUE”; break;
case GL_INVALID_OPERATION: error = “INVALID_OPERATION”; break;
case GL_STACK_OVERFLOW: error = “STACK_OVERFLOW”; break;
case GL_STACK_UNDERFLOW: error = “STACK_UNDERFLOW”; break;
case GL_OUT_OF_MEMORY: error = “OUT_OF_MEMORY”; break;
case GL_INVALID_FRAMEBUFFER_OPERATION: error = “INVALID_FRAMEBUFFER_OPERATION”; break;
}
std::cout << error << " | " << file << " (" << line << “)” << std::endl;
}
return errorCode;
}
#define glCheckError() glCheckError_(FILE, LINE)

glGetError()并不能帮助你很多,因为它返回的信息非常简单,但不可否认它经常能帮助你检查笔误或者快速定位错误来源。总而言之,是一个非常简单但有效的工具。

三、总结
本篇文章中我们着重的讲述了glGetError函数,同时它也是一个十分有用的工具,类似的如glIsTexture()等等,下面我们将OpenGL调试继续进行介绍。

发布了146 篇原创文章 · 获赞 28 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/weixin_38498942/article/details/104069354