C++ OpenGL未检测到链接错误(或错误触发器?)
我编写了一个小宏来检测着色器编译器错误和着色器程序链接错误:C++ OpenGL未检测到链接错误(或错误触发器?),c++,opengl,error-handling,linker,shader,C++,Opengl,Error Handling,Linker,Shader,我编写了一个小宏来检测着色器编译器错误和着色器程序链接错误: #define OPEN_GL_FUN_SHADER_DEBUG_STATUS_REPORTER_SHADER_UTILITIES_CPP( WHAT_TO_GET, STATUS, DEBUG_DATA, DEBUG_STATUS, ID, FUNCTION_NAME, EXTRA ) \ if( DEBUG_STATUS == true ) \ { \
#define OPEN_GL_FUN_SHADER_DEBUG_STATUS_REPORTER_SHADER_UTILITIES_CPP( WHAT_TO_GET, STATUS, DEBUG_DATA, DEBUG_STATUS, ID, FUNCTION_NAME, EXTRA ) \
if( DEBUG_STATUS == true ) \
{ \
glGet##WHAT_TO_GET##iv( ID, STATUS, ( &DEBUG_DATA.status ) ); \
if( DEBUG_DATA.status == GL_FALSE ) \
{ \
GLint logLength; \
glGet##WHAT_TO_GET##iv( ID, GL_INFO_LOG_LENGTH, ( &logLength ) ); \
std::vector< GLchar > log( logLength ); \
glGet##WHAT_TO_GET##InfoLog( ID, logLength, ( &logLength ), ( &log[ 0 ] ) ); \
auto shaderLog = log.data(); \
if( ( !( typeid( GLchar ) == typeid( char ) ) ) == true ) { \
std::cerr << "Warning::" \
FUNCTION_NAME \
"::GLchar and char are " \
"not of the same type, this could cause difficulty when error reporting logging.\n"; \
} \
DEBUG_DATA.errorMessage = std::string{ log.data() }; \
DEBUG_DATA.logLength = logLength; \
DEBUG_DATA.shaderId = ID; \
EXTRA \
} \
}
为什么要在宏中执行此操作?作为一个函数进行调试会容易得多。你只需要一步一步地检查一下,看看出了什么问题。对于
要获取的内容
-着色器
和程序
,只有两个可能的值,那么为什么不只传入所需的枚举呢?您仍然可以用一个提供函数名的简单得多的宏来包装它。@user1118321我可以做一个函数,但我必须编写glGetProgramiv
和glGetShaderiv
(与glGetXYZInfo
相同),但是我确实将宏包装成一个更简单的函数。您能演示一下如何调用宏吗?在不知道将被替换的宏参数的值的情况下,仅仅看到宏代码是不够的。@RetoKoradiquestion@RetoKoradi完成:-)
/*!!!!!!!!!!!!!!!!!!---------------------------------------------!!!!!!!!!!!!!!!!!!
Relevant use (there are some default parameters in the header, but they are all set to true.
!!!!!!!!!!!!!!!!!!---------------------------------------------!!!!!!!!!!!!!!!!!!*/
ShaderDebugInformation LinkProgram( GLuint programId, std::vector< ShaderObjectCode > shadersToLink, bool debug,
bool deleteShadersOnFailure, bool deleteProgramOnFailure )
{
for( const auto& currentShader : shadersToLink )
glAttachShader( programId, currentShader.objectCodeId );
glLinkProgram( programId );
ShaderDebugInformation debugData;
OPEN_GL_FUN_SHADER_DEBUG_STATUS_REPORTER_SHADER_UTILITIES_CPP( Program, GL_LINK_STATUS, debugData,
debug, programId, "LinkProgram( GLuint, std::vector< ShaderObjectCode >[, bool ] )",
if( deleteShadersOnFailure == true ) {
for( const auto& currentShader : shadersToLink )
DeleteShader( currentShader.objectCodeId );
}
if( deleteProgramOnFailure == true )
DeleteProgram( programId );
)
return debugData;
}
//Relevant use continued.//
void LinkProgram( ShaderProgram& programToLink, bool debug,
bool deleteShadersOnFailure, bool deleteProgramOnFailure )
{
programToLink.debugData = LinkProgram(
programToLink.shaderProgramId, programToLink.objectSources, debug,
deleteShadersOnFailure, deleteProgramOnFailure );
if( debug == true && programToLink.debugData.status != GL_FALSE )
{
const auto& objectCodeSources = programToLink.objectSources;
for( const auto& currentShader : objectCodeSources )
glDetachShader( programToLink.shaderProgramId, currentShader.objectCodeId );
}
}
//Irrelevant use.//
ShaderObjectCode CreateShaderObjectCode( ShaderSource shaderSource, bool debug, bool deleteShaderOnFailure )
{
ShaderObjectCode objectCode;
objectCode.objectCodeId = CompileShader( shaderSource );
OPEN_GL_FUN_SHADER_DEBUG_STATUS_REPORTER_SHADER_UTILITIES_CPP( Shader, GL_COMPILE_STATUS, objectCode.debugData,
debug, objectCode.objectCodeId, "CreateShaderObjectCode( ShaderSource[, bool ] )",
if( deleteShaderOnFailure == true )
DeleteShader( objectCode.objectCodeId ); )
return objectCode;
}
//Data structures.//
struct ShaderDebugInformation
{
std::string errorMessage;
GLuint logLength, shaderId;
GLint status;
};
struct ShaderSource {
GLenum shaderType;
std::string shaderSource;
};
struct ShaderObjectCode {
ShaderDebugInformation debugData;
GLuint objectCodeId;
};
struct ShaderProgram
{
GLuint shaderProgramId;
ShaderDebugInformation debugData;
std::vector< ShaderSource > sourceCode;
std::vector< ShaderObjectCode > objectSources;
bool linked;
};