您是否尝试过使用 GL_ARB_robustness 为您的 OpenGL 实现添加健壮性支持?
2.6“显卡重置恢复”
某些事件可能会导致 GL 上下文重置。这样的重置
导致所有上下文状态丢失。从此类事件中恢复
需要重新创建受影响上下文中的所有对象。这
图形重置状态的当前状态由
返回
enum GetGraphicsResetStatusARB();
返回的符号常量指示 GL 上下文是否已在
自上次调用以来的任何时间点的重置状态
GetGraphicsResetStatusARB。 NO_ERROR 表示 GL 上下文有
自上次调用以来未处于重置状态。
GUILTY_CONTEXT_RESET_ARB 表示检测到复位
归因于当前的 GL 上下文。 INNOCENT_CONTEXT_RESET_ARB
表示已检测到不可归因于
当前的总帐上下文。 UNKNOWN_CONTEXT_RESET_ARB 表示检测到
原因不明的图形重置。
此外,请确保在初始化上下文时具有调试上下文,并使用 ARB_debug_output 扩展名接收日志输出。
void DebugMessageControlARB(enum source,
enum type,
enum severity,
sizei count,
const uint* ids,
boolean enabled);
void DebugMessageInsertARB(enum source,
enum type,
uint id,
enum severity,
sizei length,
const char* buf);
void DebugMessageCallbackARB(DEBUGPROCARB callback,
const void* userParam);
uint GetDebugMessageLogARB(uint count,
sizei bufSize,
enum* sources,
enum* types,
uint* ids,
enum* severities,
sizei* lengths,
char* messageLog);
void GetPointerv(enum pname,
void** params);
例如:
// Initialize GL_ARB_debug_output ASAP
if (glfwExtensionSupported("GL_ARB_debug_output"))
{
typedef void APIENTRY (*glDebugMessageCallbackARBFunc)
(GLDEBUGPROCARB callback, const void* userParam);
typedef void APIENTRY (*glDebugMessageControlARBFunc)
(GLenum source, GLenum type, GLenum severity,
GLsizei count, const GLuint* ids, GLboolean enabled);
auto glDebugMessageCallbackARB = (glDebugMessageCallbackARBFunc)
glfwGetProcAddress("glDebugMessageCallbackARB");
auto glDebugMessageControlARB = (glDebugMessageControlARBFunc)
glfwGetProcAddress("glDebugMessageControlARB");
glDebugMessageCallbackARB(debugCallback, this);
glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE,
GL_DEBUG_SEVERITY_LOW_ARB, 0, nullptr, GL_TRUE);
}
...
std::string GlfwThread::severityString(GLenum severity)
{
switch (severity)
{
case GL_DEBUG_SEVERITY_LOW_ARB: return "LOW";
case GL_DEBUG_SEVERITY_MEDIUM_ARB: return "MEDIUM";
case GL_DEBUG_SEVERITY_HIGH_ARB: return "HIGH";
default: return "??";
}
}
std::string GlfwThread::sourceString(GLenum source)
{
switch (source)
{
case GL_DEBUG_SOURCE_API_ARB: return "API";
case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB: return "SYSTEM";
case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB: return "SHADER_COMPILER";
case GL_DEBUG_SOURCE_THIRD_PARTY_ARB: return "THIRD_PARTY";
case GL_DEBUG_SOURCE_APPLICATION_ARB: return "APPLICATION";
case GL_DEBUG_SOURCE_OTHER_ARB: return "OTHER";
default: return "???";
}
}
std::string GlfwThread::typeString(GLenum type)
{
switch (type)
{
case GL_DEBUG_TYPE_ERROR_ARB: return "ERROR";
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: return "DEPRECATED_BEHAVIOR";
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: return "UNDEFINED_BEHAVIOR";
case GL_DEBUG_TYPE_PORTABILITY_ARB: return "PORTABILITY";
case GL_DEBUG_TYPE_PERFORMANCE_ARB: return "PERFORMANCE";
case GL_DEBUG_TYPE_OTHER_ARB: return "OTHER";
default: return "???";
}
}
// Note: this is static, it is called from OpenGL
void GlfwThread::debugCallback(GLenum source, GLenum type,
GLuint id, GLenum severity,
GLsizei, const GLchar *message,
const GLvoid *)
{
std::cout << "source=" << sourceString(source) <<
" type=" << typeString(type) <<
" id=" << id <<
" severity=" << severityString(severity) <<
" message=" << message <<
std::endl;
AssertBreak(type != GL_DEBUG_TYPE_ERROR_ARB);
}
您几乎可以肯定地在一个不错的 OpenGL 实现中使用了这两个扩展。他们有帮助,很多。调试上下文对所有内容进行验证并向日志抱怨。他们甚至在一些 OpenGL 实现的日志输出中给出了性能建议。使用 ARB_debug_output 会使检查 glGetError 过时 - 它会为您检查每次调用。