1

そのため、学校用の単純なスピログラフ ジェネレーターを構築しようとしていますが、Windows 7 の Eclipse CDT ですべてがうまくいきました。私のプログラムは、生成された各スピログラフ (最大 5 つ) にデフォルトのシェーダーを割り当てます。ユーザーが任意のスピログラフに選択して割り当てることができる他の 3 つのシェーダー プログラムもあります。Eclipse の内部では正常に動作しますが、Eclipse の外部で実行するとシェーダーがリンクできません。このプログラムは GLUT と GLEW を使用し、必要な .dll を実行可能ファイルのディレクトリに含めました。私はこれを4時間修正しようとしてきましたが、常に失敗するわけではないEclipseの外部へのリンクに失敗する原因がわかりません。

すべてのシェーダーを含めるつもりはありませんが、リンクに失敗してアプリケーションが終了する最初の 2 つを次に示します。

#version 330 

layout (location = 0) in vec4 vPosition; 
uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;

out vec4 color; 

void main() 
{ 
   gl_Position = proj * view * model * vPosition;
   color = vec4( 
        (4 - vPosition.z) * (4 - vPosition.z) / 16.0, 
        (2.0 - abs( 2.0 - vPosition.z )) / 2.0, 
        vPosition.z * vPosition.z / 16.0,
        1.0
   );
}

とフラグメントシェーダー

#version 330 

in vec4 color; 

void main() 
{ 
   gl_FragColor = color;
}

および印刷ログ

Vertex shader was successfully compiled to run on hardware.

Fragment shader was successfully compiled to run on hardware.
Fragment shader(s) failed to link,  vertex shader(s) failed to link. 
ERROR: error(#280) Not all shaders have valid object code
ERROR: error(#280) Not all shaders have valid object code

シェーダーをコンパイルしてリンクするために使用するInitShader()関数は、過去に行ったアプリケーションで機能しました。私が違うことをしている唯一のことは、programs[]1つをコンパイルしてアプリケーション全体で実行するのではなく、いくつかの異なるシェーダープログラムを作成してそれらを割り当てるために使用していることです。

program[0] = InitShader("shaders/vshader.glsl", "shaders/fshader.glsl");
program[1] = InitShader("shaders/vshader2.glsl", "shaders/fshader.glsl");
program[2] = InitShader("shaders/vshader3.glsl", "shaders/fshader.glsl");
program[3] = InitShader("shaders/vshaderw.glsl", "shaders/fshader.glsl");

いずれにせよ、これが のコードですInitShader()

GLuint InitShader(const char* source, GLenum type)
{
    GLuint shader = glCreateShader(type);
    glShaderSource(shader, 1, (const GLchar**) &source, NULL );
    glCompileShader(shader);
    printLog( shader );

    return shader;
}

GLuint InitShader(const char* vfile, const char *ffile) {
    GLuint program = glCreateProgram();
    GLuint shader;

    // stringify and attach vshader
    std::ifstream vertstream(vfile);
    std::string vert((std::istreambuf_iterator<char>(vertstream)), std::istreambuf_iterator<char>());
    shader = InitShader(vert.c_str(), GL_VERTEX_SHADER);
    glAttachShader( program, shader );

    // stringify and attach fshader
    std::ifstream fragstream(ffile);
    std::string frag((std::istreambuf_iterator<char>(fragstream)), std::istreambuf_iterator<char>());
    shader = InitShader(frag.c_str(), GL_FRAGMENT_SHADER);
    glAttachShader( program, shader );

    // link program
    glLinkProgram(program);

    printLog(program);
    // link  and error check
    GLint  linked;
    glGetProgramiv( program, GL_LINK_STATUS, &linked );
    if ( !linked ) {
        fprintf(stderr, "Shaders failed to link!\n");
        exit( EXIT_FAILURE );
    }

    // use program object
    glUseProgram(program);

    return program;
}

ここは午前 4 時なので、私の灰色の細胞はほぼ使い果たされています。そして、それは実際には宿題の助けではありません。実行可能ファイルは、クラスのEclipseの外で実行する必要はありません。自分用のスタンドアロンプ​​ログラムを作成する方法を知りたいだけです。

4

1 に答える 1

3

あなたの問題の原因はここにあります:

program[0] = InitShader("shaders/vshader.glsl", "shaders/fshader.glsl");

シェーダ ソース ファイルへのパスは相対パスです。Eclipse は、プログラムを直接実行するときの作業ディレクトリとは異なる作業ディレクトリ (おそらくプロジェクト ルート) からプログラムを実行する可能性があります。

解決策: どちらか

  • プログラムの起動時の作業ディレクトリが内部で使用される相対パスと一致することを確認してください (非常に信頼性が低い)
  • プログラム内で絶対パスを使用する (柔軟性に欠ける)

または、私が提案すること

  • 実行時にシェーダー ファイルの場所 (コマンド ライン オプション、実行可能バイナリの場所など) を決定し、実行時にそれに応じてパスを調整します。
于 2012-11-05T13:04:07.933 に答える