2012-09-07 158 views
2

對於OpenGL學習,我指的是openglbook。目前在chapter 2,我試圖運行其代碼pasted here作爲參考。OpenGL(在Ubuntu中):glGetError()返回GL_INVALID_OPERATION

我現在面臨的問題是下面的功能:

void CreateShaders(void) 
{ 
    GLenum ErrorCheckValue = glGetError(); 

    VertexShaderId = glCreateShader(GL_VERTEX_SHADER); 
    glShaderSource(VertexShaderId, 1, &VertexShader, NULL); 
    glCompileShader(VertexShaderId); 

    FragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER); 
    glShaderSource(FragmentShaderId, 1, &FragmentShader, NULL); 
    glCompileShader(FragmentShaderId); 

    ProgramId = glCreateProgram(); 
     glAttachShader(ProgramId, VertexShaderId); 
     glAttachShader(ProgramId, FragmentShaderId); 
    glLinkProgram(ProgramId); 
    glUseProgram(ProgramId); 

    ErrorCheckValue = glGetError(); // =====> returns GL_INVALID_OPERATION 
    if (ErrorCheckValue != GL_NO_ERROR) 
    { 
     fprintf(
      stderr, 
      "ERROR: Could not create the shaders: %s \n", 
      gluErrorString(ErrorCheckValue) 
     ); 

     exit(-1); 
    } 
} 

如上功能(glew.h),爲什麼它返回"GL_INVALID_OPERATION"顯示?
如果我評論這些行,那麼它的作品,但只是打印一個空白窗口。

這是我的glxinfo。由於我的版本是2.2,這代碼是爲3.3+,我在下面的代碼刪除,以避免故障:

glutInitContextVersion(4, 0); 
    glutInitContextFlags(GLUT_FORWARD_COMPATIBLE); 
    glutInitContextProfile(GLUT_CORE_PROFILE); 

更新:從@添的回答下面的建議後,我能夠成功運行該程序;似乎這些系是創建問題:

「的#Version 400 \ n」 個(用 「的#Version 130」 代替)

佈局(位置= 0) (已刪除)。 佈局(位置= 1)(刪除)。

但是由於這個原因,預期的三角形不會完全相同。這個教程可能會教導最新的opengl版本,我沒有這個版本,這就造成了這個問題。

是否有任何方法可以將代碼從最新的OpenGL(4.0+)兼容的代碼修改爲較小的版本(例如< 3.0)而不改變輸出?我將無法升級圖形硬件。

+1

沒有足夠的時間來獲得完整的答案,但[glBindAttribLocation](http://www.opengl.org/sdk/docs/man/xhtml/glBindAttribLocation.xml)是一個函數,可以取代特殊'layout'關鍵字。 – Tim

回答

6

你沒有對着色器編譯和鏈接做適當的錯誤檢查。您的着色器中可能存在某種語法錯誤,這會妨礙編譯,因此useProgram調用會嘗試使用無效的程序。

對於每個着色器,調用glCompileShader後,你要調用glGetShaderiv(shader, GL_COMPILE_STATUS, compile_status)這compile_status返回truefalse告訴你,如果編譯是成功的。如果不是,則可以撥打glGetShaderiv(shader, GL_INFO_LOG_LENGTH, length)來獲取infoLog的大小,然後致電glGetShaderInfoLog()以獲取一個字符串,該字符串會告訴您編譯期間發生的任何錯誤。

總之,編譯器/連接錯誤檢查應該是這樣的:

void CheckError (GLuint shaderId, uint LINE) 
{ 
    GLint bCompiled; 
    glGetShaderiv(shaderId, GL_COMPILE_STATUS, &bCompiled); 
    if(bCompiled == false) 
    { 
    GLint length; 
    glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &length); 
    GLchar *pInfo = new GLchar[length + 1]; 
    glGetShaderInfoLog(shaderId, length, &length, pInfo); 
    fprintf(stderr, "called at line-%u: Compiler/Linker error: %s", LINE, pInfo); 
    delete[] pInfo; 
    } 
} 

如果兩個着色器編譯成功,則鏈接程序後,要測試與glGetProgramiv/GL_LINK_STATUS程序對象同樣的事情和glGetProgramInfoLog

+0

+1,你的建議奏效。我更新了我的問題。您能否提出一種在不更改輸出的情況下使用較小的OpenGL版本運行代碼的方法。 – iammilind