OpenGL获取报错信息

本文介绍了在使用OpenGL时如何获取并打印错误信息,包括通过`glGetError`函数检查错误队列,以及使用glad库支持新版本OpenGL扩展。还提到了设置错误回调函数的方法,如`glDebugMessageCallback`,以便在发生错误时自动处理。此外,文章也提及了glfw库的错误处理,包括`glfwGetError`函数和设置错误回调的选项。
摘要由CSDN通过智能技术生成

在学习OpenGL的过程中,往往因为某些测试目的或单纯太菜而写出错误的代码,此时只能面对漆黑的窗口怀疑人生。如何让OpenGL能够像编译器一样,在出错时打印错误信息到控制台呢?本文将介绍几种方法。

基础介绍

首先声明OpenGL的API库:glfw。这个库支持较新的glfw版本(如gl4),让我们可以使用更新的OpenGL特性。现目前glfw官网可以下载的版本是3.3,注意这是glfw的版本,而不是开发环境所使用的OpenGL版本。

通过#include <GLFW/glfw3.h>包含glfw头文件之后,我们就可以使用GLFW API 的所有常量、类型和函数原型。其中一部分是通过包含开发环境自身提供的OpenGL头文件实现的,但是Windows平台对OpenGL支持很少(大概是因为微软自己做了DirectX的原因),因此简单地包含glfw3.h只能让我们直接使用古老的OpenGL 1.2版本,新版本函数需要手动查询并绑定函数指针后才能使用,为了解决这一问题,一般使用extension loader library,如glad库来支持这些扩展。

OpenGL获取错误

OpenGL运行中产生的错误保存在一个队列中,调用函数

GLenum glGetError(void);

从队列中获取一个代表错误的枚举数,对应error的类型,种类如下

枚举值枚举名描述
0GL_NO_ERROR错误队列为空,当前未记录任何错误
1280GL_INVALID_ENUM使用非法的枚举参数
1281GL_INVALID_VALUE参数越界(out of range)
1282GL_INVALID_OPERATION当前状态下不允许执行此操作。
1283GL_STACK_OVERFLOW堆栈溢出
1284GL_STACK_UNDERFLOW堆栈下溢(出栈操作达到堆栈底部)
1285GL_OUT_OF_MEMORY内存溢出,OpenGL此后的行为将是未定义的
1286GL_INVALID_FRAMEBUFFER_OPERATION使用未准备好的帧缓存
1287GL_CONTEXT_LOST由于显卡重置导致 OpenGL 上下文丢失。

由于错误可能会累积,或是在某个调用中产生多种错误,因此一般用while()反复调用以获取全部错误。

以下是一个简单的Debug头文件,包含该头文件后,在某一行中调用checkGLError()函数,即可确定该行之前产生了哪些错误。

在多处使用时,这个函数可以接收一个字符串参数,来标记不同错误的位置。

#pragma once
#include <iostream>
#include <string>
#include <map>

#include <GLFW/glfw3.h>

std::map<int, std::string> ErrorInfo{
    {0, "NO_ERROR"},
    {1280, "GL_INVALID_ENUM"},
    {1281, "GL_INVALID_VALUE"},
    {1282, "GL_INVALID_OPERATION"},
    {1283, "GL_STACK_OVERFLOW"},
    {1284, "GL_STACK_UNDERFLOW"},
    {1285, "GL_OUT_OF_MEMORY"},
    {1286, "GL_INVALID_FRAMEBUFFER_OPERATION"},
    {1287, "GL_CONTEXT_LOST"}
};

void checkGLError(const std::string& flag = "NO_FLAG") {
    int code = glGetError();
    
    if (code != GL_NO_ERROR) {
        if (flag != "NO_FLAG") {
            std::cout << "OpenGL ERROR at flag \"" << flag << "\"\n";
        }

        while (code != GL_NO_ERROR) {
            std::cerr << "ERROR CODE \"" << code << "\": " << ErrorInfo[code] << std::endl;
            code = glGetError();
        }
    }
}

(或许)更好的一种方式是在每个OpenGL函数调用时都套上一个检测错误的宏,尽管这样做会降低运行效率,但在程序的Debug阶段是很有效的,具体做法见Cherno的OpenGL教程 p10

新版本OpenGL支持的错误回调

设置错误回调后,即可在发生错误时自动处理,十分方便。

  • 注意:要使用错误回调需要包含较新(4.3版本以后)的glad库。
    使用glad官网的在线服务下载新版本glad

错误回调的原型如下

void glDebugMessageCallback(	DEBUGPROC , callback
								void * userParam);
  • callback是一个在出错时将被调用的函数的函数指针。
  • userParam是用户传入的,将对应传入callback函数的指针。

glfw获取错误

  • 注意:glfw所返回的错误是带有glfw前缀的函数所产生的错误,即glfw库运行时产生的错误,它们不会引起程序崩溃。只要glfw成功初始化,它都会保持安全地运行。

方法1

使用函数

int glfwGetError(const char ** description)

用法可参加这段代码

const char* description;
int code = glfwGetError(&description);
 
if (description) {
    // print code and description
}
  • 错误代码指示错误的常规类别。如果自上次调用以来未发生任何错误,则返回GLFW_NO_ERROR(0)。

  • 注意,指针的内存由glfw自己管理,直接传入空指针即可,也不需要释放指针。

方法2

类似于OpenGL自己的回调函数,glfw也可以设置回调函数,每次发生错误时都会调用该回调。同样是定义一个特定原型的回调函数,并传入glfwSetErrorCallback即可。

void error_callback(int code, const char* description) {
	// print code and description
}

glfwSetErrorCallback(error_callback);

参考资料

GLFW: Introduction to the API
glGetError_PersonFly_小逗的博客-CSDN博客
GLFW:Getting started
glDebugMessageCallback - OpenGL 4 - docs.gl

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值