Следуя инструкциям на 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);
}
По какой-то причине я получаю этот вывод:
⤱㨠攠牲牯䌠ㄲ›瘣牥楳湯㌠〰洠獵⁴敢映汯潬敷祢攠ੳ⠰⤲㨠攠牲牯䌠㈰›湵畳灰牯整敶獲潩〳ਰ⠰⤲㨠攠牲牯䌠〰〰›祳瑮硡攠牲牯湵硥数瑣摥✠✨硥数瑣湩㨢∺愠⁴潴敫⠢ਢ⠰⤴㨠攠牲牯䌠㔷㈳
Может кто-нибудь сказать мне, почему я получаю этот испорченный вывод?
Вся помощь приветствуется.
Вы не конвертируете char
с wchar_t
с помощью swprintf(..., "%s\n", ...)
потому что, согласно https://msdn.microsoft.com/en-us/library/hf4y5e3w.aspx %s
означает следующее:
При использовании с функциями printf указывает однобайтовую или многобайтовую строку символов; при использовании с функциями wprintf указывает строку широких символов. Символы отображаются вплоть до первого нулевого символа или до достижения значения точности.
Как вы действительно используете *wprintf
функционировать здесь, %s
уже ожидает широкую строку, но вы даете ей не широкую строку. Так что текст ASCII (в этом случае 1) : error C0121: #version 300 must be followed by ...
) интерпретируется как широкая строка, что приводит к мусору.
Согласно той же веб-странице, %S
может быть самым быстрым решением для решения вашей проблемы здесь («при использовании с функциями wprintf указывает однобайтовую или многобайтовую строку символов» — что %s
для нормального printf).
Как объясняет @genpfault в своем Так ответь Спецификация OpenGL говорит о *GetString
команды, возвращающие строки UFT-8. Ничего не сказано о glGetShaderInfoLog
, но кажется разумным, что он также возвращает строку в кодировке UTF-8.
Даже если это ASCII, он будет таким же при преобразовании в UTF-8, потому что первые 127 кодов UTF-8 совпадают с кодами ASCII.
Лучшим вариантом будет распечатать строки UTF-8, если это возможно в C ++ без какого-либо преобразования. Но на сегодняшний день это не в Windows, которая использует UFT-16 для внутреннего использования, или в Linux и его UTF-32.
Для конвертации используйте станд :: codecvt. Например, см. этот ТАК вопрос