2012-11-05 60 views
1

所以我試圖爲學校建立一個簡單的螺旋形發生器,在Windows 7的Eclipse CDT中,一切都很順利。我的程序爲每個生成的Spirograph(最大值爲5)分配一個默認着色器。另外還有3個着色器程序,用戶可以通過選擇將其分配給任何一個Spirograph。在eclipse中它的工作原理與它應該完全相同,但是當在eclipse外部運行時,着色器無法鏈接。該程序使用GLUT和GLEW,並將必要的.dll包含在可執行文件的目錄中。我一直試圖解決這個問題4個小時,不知道什麼會導致無法鏈接到eclipse之外的鏈接,而這些鏈接不會一直失敗。我的openGL着色器不會鏈接到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()函數我用來編譯l着色器的墨水已經用於我過去所做的應用。我所做的唯一不同的是我使用它來生成一些不同的着色器程序,並將它們分配到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之外運行,我只想知道如何爲自己創建獨立的程序。

回答

3

您的問題的原因就在於此:

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

着色器的源文件的路徑是相對。很有可能,Eclipse會在不同的工作目錄(可能是您的項目根目錄)中運行您的程序,而不是直接執行程序時的工作目錄。

解決方案:

  • 確保在程序啓動時的工作目錄的程序(非常不易伸縮的)

  • 使用絕對路徑內部(非常不可靠的)中使用的相對路徑相匹配或者,我建議

    • 確定着色器文件的位置在運行時(命令行選項,可執行二進制文件的位置等),並在運行時相應地調整路徑。