问题
The problem is that, shaders (pretty simple ones, as I'm learning OpenGL) fail to compile in a seemingly random manner (and gives random error messages * ). The same shaders, however, compile after about 3 or 4 tries. Here is the code:
Shader::Shader(GLenum Type,std::string filename)
{
shader_type = Type;
std::ifstream ifs(filename);
if(!ifs)
throw(std::runtime_error("File:"+filename+" not opened."));
std::ostringstream stream;
stream<<ifs.rdbuf();
const GLchar* data = stream.str().c_str();
handle = glCreateShader(shader_type);
glShaderSource(handle,1,static_cast<const GLchar**>(&data),0);
glCompileShader(handle);
int status;
glGetShaderiv(handle,GL_COMPILE_STATUS,&status);
if(status == GL_FALSE)
{
int loglength;
glGetShaderiv(handle,GL_INFO_LOG_LENGTH,&loglength);
auto data = new char[loglength];
glGetShaderInfoLog(handle,loglength,&loglength,data);
std::string strdata(data);
delete [] data;
throw(std::runtime_error(strdata));
}
}
Note that the shaders aren't missing newlines at the end, has an extra space after the last semicolon and uses tabs instead of spaces. (as suggested in various old posts over the internet!).
- Here are two error messages produced from the same vertex shader here, not at the same time:
#version 330
in vec2 Position;
uniform mat4 transform;
void main()
{
gl_Position = transform*vec4(Position,0.0f,1.0f);
}
Errors:
0(1) : error C0000: syntax error, unexpected $undefined at token "<undefined>"
0(6) : error C0000: syntax error, unexpected '!', expecting ',' or ')' at token "!"
And sometimes it just works ! Is it a problem with my drivers ? (I'm using the recent 302.x stable nvidia binary drivers on Arch Linux 64 bit, with an aged 9600 GSO card )
P.S: The code works as expected ,whenever the shader compiles correctly, so I think it shoud be correct. I'll be happy to post a working(sometimes !) example as a zip file if the problem can't be found from this, and someone wants to take a look.
回答1:
const GLchar* data = stream.str().c_str();
This is bad. If you want the string's data, you need to store it. str
will return a copy of the buffer, which you then get a pointer to with c_str
. Once that temporary is destroyed (at the end of this line), that pointer will point to memory you no longer have access to.
The correct code is this:
std::string dataString = stream.str();
const GLchar *data = reinterpret_cast<GLchar*>(dataString.c_str());
来源:https://stackoverflow.com/questions/11138705/is-there-anything-wrong-with-my-glsl-shader-loading-code