C++, OpenGL: Weird problem with c-strings
I have a C++ problem here which I simply cannot understand.
I have 2 slightly different functions. Both of them should do the very same thing. But only one works properly.
Method 1: input of the method is 'const string samplerName = "test"'
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(...);
}
}
Method 2:
void setUniformSampler(Gluint program, GLuint sampler) {
GLint uniformLocation = glGetUniformLocation(program, "test"); // returns 0
if(uniformLocation >= 0) {
glUniform1i(uniformLocation, sampler);
} else {
throw exception(...);
}
}
As you can see, glGetUniformLocation returns 2 different values. The correct return value would be "0", not "-1". So I wonder, what exactly is the difference between the two calls?
quote: "c_str() generates a null-terminated sequence of characters (c-string) with the same content as the string object and returns it as a pointer to an array of characters". And that is precisely what the method glGetUniform开发者_开发问答Location(...) needs as its second parameter. So, why does only Method 2 above succeed? Is it a compiler problem?
I'm working with MS Visual Studio 2008 on Win7.
I've been searching for this bug for almost 2 days now. I really want to clarify this. It drove me crazy...
Thanks Walter
EDIT:
This doesn't work either.
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(...);
}
}
Your parameter is const, and you can't call a non-const function on a const object. Maybe that's the problem? The function needs a pointer to a null-terminated string. Make sure that's what you're giving it.
check the implementation and the type of the parameter in glGetUniformLocation(parameter)
, "test" is a const literal whose life and location never change in your executable's life, while c_str() is dynamically calculated from a string object, it dies when the string object dies.
In other words, you need to check in side of glGetUniformLocation()
to find the reason, which I guess is related to some CRT string functions.
You might be victim to a mixup of wide character vs slim (i.e. 8-bit) character strings. If both your shader source and the uniform name are defined as static strings, then they will agree on the string representation. string::c_str might change this, as c_str will always return a string of char, i.e. it is not wchar aware.
Technically it should make difference, since a bug free shader compiler use a unambigous internal representation. But there may be a bug, that the difference between wide and slim characters are interpreted as different identifiers.
What happens if you pass the shader source, too through string::c_str? Also check the debugger hexedit view on the string variable. If it looks like this:
00000000 74 65 73 74 0a |test.|
You got a 8-bit character string. If it looks like this:
00000000 74 00 65 00 73 00 74 00 0a 00 |t.e.s.t...|
then you got a wide string. And then compare this with the variable in which the shader is supplied.
精彩评论