使用 wprintf 打印 opengl 着色器编译日志
Print opengl shader compile log with wprintf
按照 opengl-tutorial.org 中的教程进行操作
,意识到我无法直接使用 printf 打印着色器编译日志,因为我是在 windows 桌面应用程序中进行的。我尝试使用此方法将其转换为 LPWSTR:
//compile the shader
glShaderSource(fShader, 1, &pFsCode, NULL);
glCompileShader(fShader);
//check shader compilation
glGetShaderiv(fShader, GL_COMPILE_STATUS, &result);
glGetShaderiv(fShader, GL_INFO_LOG_LENGTH, &logLen);
if (logLen > 0) {
//get compile log
vector<char> fErr(logLen + 1);
glGetShaderInfoLog(fShader, logLen, NULL, &fErr[0]);
//try to convert log to LPWSTR
wchar_t msg[100];
swprintf(msg, sizeof(msg) / sizeof(*msg), L"%s\n", &fErr[0]);
//print it
wprintf(msg);
}
出于某种原因,我得到了这个输出:
⤱㨠攠牲牯䌠ㄲ›瘣牥楳湯㌠〰洠獵⁴敢映汯潬敷祢攠ੳ⠰⤲㨠攠牲牯䌠㈰›湵畳灰牯整敶獲潩〳ਰ⠰⤲㨠攠牲牯䌠〰〰›祳瑮硡攠牲牯湵硥数瑣摥✠✨硥数瑣湩㨢∺愠⁴潴敫⠢ਢ⠰⤴㨠攠牲牯䌠㔷㈳
有人能告诉我为什么我得到这个损坏的输出吗?
感谢所有帮助。
您没有使用 swprintf(..., "%s\n", ...)
将 char
转换为 wchar_t
,因为根据 https://msdn.microsoft.com/en-us/library/hf4y5e3w.aspx %s
的含义如下:
When used with printf functions, specifies a single-byte or multi-byte character string; when used with wprintf functions, specifies a wide-character string. Characters are displayed up to the first null character or until the precision value is reached.
因为您确实在此处使用了 *wprintf
函数,所以 %s
已经需要一个宽字符串,但您给它一个非宽字符串。因此,ascii 文本(在本例中为 1) : error C0121: #version 300 must be followed by ...
)被解释为宽字符串,从而导致垃圾。
根据同一网页,%S
可能是解决您此处问题的最快方法("when used with wprintf functions, specifies a single-byte or multi-byte character string" - %s
是普通 printf 的意思)。
正如@genpfault 在他的 SO answer OpenGL 规范中所解释的那样,*GetString
命令返回 UFT-8 字符串。关于 glGetShaderInfoLog
什么也没说,但它似乎也是 returns 一个 UTF-8 编码的字符串。
即使是ASCII转换成UTF-8也是一样的,因为UTF-8前127码和ASCII码是一样的
您最好的选择是打印 UTF-8 字符串,如果这在 C++ 中是可能的而无需任何转换。但是今天它不在 Windows 中,它在内部使用 UFT-16,也不在 Linux 及其 UTF-32 用法中。
对于转换,使用 std::codecvt. For an example, see this SO question
按照 opengl-tutorial.org 中的教程进行操作 ,意识到我无法直接使用 printf 打印着色器编译日志,因为我是在 windows 桌面应用程序中进行的。我尝试使用此方法将其转换为 LPWSTR:
//compile the shader
glShaderSource(fShader, 1, &pFsCode, NULL);
glCompileShader(fShader);
//check shader compilation
glGetShaderiv(fShader, GL_COMPILE_STATUS, &result);
glGetShaderiv(fShader, GL_INFO_LOG_LENGTH, &logLen);
if (logLen > 0) {
//get compile log
vector<char> fErr(logLen + 1);
glGetShaderInfoLog(fShader, logLen, NULL, &fErr[0]);
//try to convert log to LPWSTR
wchar_t msg[100];
swprintf(msg, sizeof(msg) / sizeof(*msg), L"%s\n", &fErr[0]);
//print it
wprintf(msg);
}
出于某种原因,我得到了这个输出:
⤱㨠攠牲牯䌠ㄲ›瘣牥楳湯㌠〰洠獵⁴敢映汯潬敷祢攠ੳ⠰⤲㨠攠牲牯䌠㈰›湵畳灰牯整敶獲潩〳ਰ⠰⤲㨠攠牲牯䌠〰〰›祳瑮硡攠牲牯湵硥数瑣摥✠✨硥数瑣湩㨢∺愠⁴潴敫⠢ਢ⠰⤴㨠攠牲牯䌠㔷㈳
有人能告诉我为什么我得到这个损坏的输出吗?
感谢所有帮助。
您没有使用 swprintf(..., "%s\n", ...)
将 char
转换为 wchar_t
,因为根据 https://msdn.microsoft.com/en-us/library/hf4y5e3w.aspx %s
的含义如下:
When used with printf functions, specifies a single-byte or multi-byte character string; when used with wprintf functions, specifies a wide-character string. Characters are displayed up to the first null character or until the precision value is reached.
因为您确实在此处使用了 *wprintf
函数,所以 %s
已经需要一个宽字符串,但您给它一个非宽字符串。因此,ascii 文本(在本例中为 1) : error C0121: #version 300 must be followed by ...
)被解释为宽字符串,从而导致垃圾。
根据同一网页,%S
可能是解决您此处问题的最快方法("when used with wprintf functions, specifies a single-byte or multi-byte character string" - %s
是普通 printf 的意思)。
正如@genpfault 在他的 SO answer OpenGL 规范中所解释的那样,*GetString
命令返回 UFT-8 字符串。关于 glGetShaderInfoLog
什么也没说,但它似乎也是 returns 一个 UTF-8 编码的字符串。
即使是ASCII转换成UTF-8也是一样的,因为UTF-8前127码和ASCII码是一样的
您最好的选择是打印 UTF-8 字符串,如果这在 C++ 中是可能的而无需任何转换。但是今天它不在 Windows 中,它在内部使用 UFT-16,也不在 Linux 及其 UTF-32 用法中。
对于转换,使用 std::codecvt. For an example, see this SO question