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 回答