开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜