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));
    }
}

シェーダーは最後に改行が欠落しておらず、最後のセミコロンの後に余分なスペースがあり、スペースの代わりにタブを使用していることに注意してください。(インターネット上のさまざまな古い投稿で示唆されているように!)。

  • 同時にではなく、ここで同じ頂点シェーダーから生成された2つのエラーメッセージを次に示します。

#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を返します。これから、でポインタを取得します。その一時的なものが(この行の終わりで)破棄されると、そのポインタは、アクセスできなくなったメモリを指します。c_str

正しいコードは次のとおりです。

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