2010-12-09 2 views
1

У меня проблема с C++, которую я просто не могу понять.C++, OpenGL: странная проблема с c-строками

У меня есть 2 несколько разных функций. Оба они должны делать то же самое. Но только один работает правильно.

Способ 1: вход метода является 'Const строка samplerName = "тест"'


void setUniformSampler(Gluint program, const string samplerName, GLuint sampler) { 
    GLint uniformLocation = glGetUniformLocation(program, samplerName.c_str()); // returns -1 

    if(uniformLocation >= 0) { 
     glUniform1i(uniformLocation, sampler); 
    } else { 
     throw exception(...); 
    } 
} 

Способ 2:


void setUniformSampler(Gluint program, GLuint sampler) { 
    GLint uniformLocation = glGetUniformLocation(program, "test"); // returns 0 

    if(uniformLocation >= 0) { 
     glUniform1i(uniformLocation, sampler); 
    } else { 
     throw exception(...); 
    } 
} 

Как вы можете видеть, glGetUniformLocation возвращает 2 разных значения. Правильное возвращаемое значение будет «0», а не «-1». Интересно, в чем же разница между двумя вызовами?

quote: "c_str() генерирует последовательность символов (c-string) с нулевым завершением с тем же содержимым, что и строковый объект, и возвращает его как указатель на массив символов". И это именно то, что метод glGetUniformLocation (...) нуждается в качестве второго параметра. Итак, почему только метод 2 выше преуспевает? Это проблема компилятора?

Я работаю с MS Visual Studio 2008 на Win7.

Я искал эту ошибку уже почти 2 дня. Я действительно хочу это прояснить. Это сводило меня с ума ...

Thanks Walter

EDIT:

Это не работает.


void setUniformSampler(Gluint program, const string samplerName, GLuint sampler) { 
    const GLchar* name = samplerName.c_str(); 

    GLint uniformLocation = glGetUniformLocation(program, name); // still returns -1 

    if(uniformLocation >= 0) { 
     glUniform1i(uniformLocation, sampler); 
    } else { 
     throw exception(...); 
    } 
} 

+0

Вы уверены, что строка `samplerName` фактически содержит` test`? Вы можете проверить с помощью отладчика или вызов `printf()`? – 2010-12-09 06:22:44

+0

Да, я использовал отладчик Visual Studio, и я могу скрыть, что samplerName содержит тест. – Walter 2010-12-09 06:23:40

+0

Как насчет `программы`? Правильно ли она инициализирована/передана в первом случае? – 2010-12-09 06:31:35

ответ

0

Ваш параметр Const, и вы не можете назвать неконстантную функцию на константный объект. Может, в этом проблема? Функция нуждается в указателе на строку с нулевым завершением. Убедитесь, что это то, что вы даете.

0

проверить реализацию и тип параметра в glGetUniformLocation(parameter), «тест» - это константный литерал, чья жизнь и местоположение никогда не изменяются в жизни вашего исполняемого файла, в то время как c_str() динамически вычисляется из строкового объекта, он умирает, когда строковый объект умирает.

Другими словами, вам нужно проверить сторону glGetUniformLocation(), чтобы найти причину, которая, как я полагаю, связана с некоторыми функциями строки CRT.

0

Возможно, вы являетесь жертвой смешанного символа с широкими символами или тонкими (то есть 8-битными) символьными строками. Если оба источника шейдера и унифицированное имя определены как статические строки, то они согласятся на строковое представление. string :: c_str может изменить это, так как c_str всегда возвращает строку char, т. е. не знает wchar.

Технически это должно сделать разницу, так как компилятор без шейдера использует недвусмысленное внутреннее представление. Но может быть ошибка, что разница между широкими и тонкими символами интерпретируется как разные идентификаторы.

Что произойдет, если вы передадите источник шейдера тоже через строку :: c_str? Также проверьте представление hexedit отладчика на строковой переменной. Если это выглядит так:

00000000 74 65 73 74 0a         |test.| 

У вас есть 8-битная строка символов. Если это выглядит так:

00000000 74 00 65 00 73 00 74 00 0a 00     |t.e.s.t...| 

тогда у вас есть широкая строка. А затем сравните это с переменной, в которой поставляется шейдер.

 Смежные вопросы

  • Нет связанных вопросов^_^