man*_*479 0 c++ opengl shader compiler-errors glsl
问题是,着色器(非常简单的,因为我正在学习OpenGL)无法以看似随机的方式编译(并提供随机错误消息*).但是,相同的着色器在大约3或4次尝试后编译.这是代码:
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));
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,着色器最后没有缺少换行符,在最后一个分号后面有一个额外的空格,并使用制表符而不是空格.(正如互联网上各种旧帖所示!).
#version 330
in vec2 Position;
uniform mat4 transform;
void main()
{
gl_Position = transform*vec4(Position,0.0f,1.0f);
}
Run Code Online (Sandbox Code Playgroud)
错误:
0(1) : error C0000: syntax error, unexpected $undefined at token "<undefined>"
0(6) : error C0000: syntax error, unexpected '!', expecting ',' or ')' at token "!"
Run Code Online (Sandbox Code Playgroud)
有时它只是有效!这是我司机的问题吗?(我在Arch Linux 64位上使用最近的302.x稳定nvidia二进制驱动程序,带有9600年龄的GSO卡)
PS:只要着色器正确编译,代码就会按预期工作,所以我认为它应该是正确的.我很乐意发布一个工作(有时!)示例作为zip文件,如果从这里找不到问题,有人想看一看.
const GLchar* data = stream.str().c_str();
Run Code Online (Sandbox Code Playgroud)
这是不好的.如果您想要字符串的数据,则需要存储它.str
将返回缓冲区的副本,然后您将获得指向的缓冲区c_str
.一旦该临时被销毁(在该行的末尾),该指针将指向您不再有权访问的内存.
正确的代码是这样的:
std::string dataString = stream.str();
const GLchar *data = reinterpret_cast<GLchar*>(dataString.c_str());
Run Code Online (Sandbox Code Playgroud)