0

问题是,着色器(非常简单的,因为我正在学习 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));
    }
}

请注意,着色器最后没有缺少换行符,在最后一个分号之后有一个额外的空格,并且使用制表符而不是空格。(正如互联网上各种旧帖子中所建议的那样!)。

  • 下面是从同一个顶点着色器产生的两条错误消息,不是同时产生的:

#version 330
in vec2 Position;
uniform mat4 transform;
void main()
{
    gl_Position = transform*vec4(Position,0.0f,1.0f);

}

错误:

0(1) : error C0000: syntax error, unexpected $undefined at token "<undefined>"


0(6) : error C0000: syntax error, unexpected '!', expecting ',' or ')' at token "!"

有时它只是工作!是我的驱动程序有问题吗?(我在 Arch Linux 64 位上使用最近的 302.x 稳定的 nvidia 二进制驱动程序,并带有一张陈旧的 9600 GSO 卡)

PS:只要着色器正确编译,代码就会按预期工作,所以我认为它应该是正确的。如果无法从中找到问题,我很乐意将工作(有时!)示例作为 zip 文件发布,并且有人想看看。

4

1 回答 1

6
const GLchar* data = stream.str().c_str();

这是不好的。如果你想要字符串的数据,你需要存储它str将返回缓冲区的副本,然后您将获得指向 with 的指针c_str。一旦该临时对象被销毁(在此行的末尾),该指针将指向您不再有权访问的内存。

正确的代码是这样的:

std::string dataString = stream.str();
const GLchar *data = reinterpret_cast<GLchar*>(dataString.c_str());
于 2012-06-21T16:38:01.153 回答