2013-09-29 35 views
3

我正在使用OpenGL 4.2,我無法弄清楚爲什麼我在這個程序中得到一個GL_INVALID_VALUE錯誤。我在調用glBindAttribLocation時遇到錯誤。根據OpenGL 4 reference page,爲什麼GL_INVALID_VALUE應該由glBindAttribLocation生成,只有兩個原因。如果指數等於或大於MAX_VERTEX_ATTRIBS更大產生OpenGL 4.2 glBindAttribLocation無效值?

void glBindAttribLocation(GLuint program, GLuint index, const GLchar *name);

  1. INVALID_VALUE。
  2. 如果程序不是OpenGL生成的值,則會生成INVALID_VALUE。

正如你可以從下面的程序看,條件1不設置,因爲index20GL_MAX_VERTEX_ATTRIBS34921。條件2未被滿足,因爲program由OpenGL使用glCreateProgram()生成。那麼我怎麼可能得到一個GL_INVALID_VALUE錯誤?

// test.cpp 
#include <GL/glew.h> 
#include <GL/glut.h> 
#include <iostream> 

int main(int argc, char* argv[]) 
{ 
    glutInit(&argc, argv); 
    glutCreateWindow("Test"); 
    glewInit(); 

    std::cout << "Max Vertex Attributes : " << GL_MAX_VERTEX_ATTRIBS << std::endl; 
    // create program 
    GLuint program = glCreateProgram(); 
    if (program == 0) 
     std::cout << "Program error" << std::endl; 

    // clear existing errors   
    if (glGetError() != GL_NO_ERROR) 
     std::cout << "Pre-existing error" << std::endl; 

    // bind attribute location to index 20 
    glBindAttribLocation(program, 20U, "DoesNotExist"); 

    // why is this generating an INVALID_VALUE error? 
    if (glGetError() == GL_INVALID_VALUE) 
     std::cout << "Invalid value error" << std::endl; 

    glDeleteProgram(program); 
    return 0; 
} 

端子輸出

$ g++ test.cpp -lGLEW -lglut 
$ ./a.out 
Max Vertex Attributes : 34921 
Invalid value error 

而且驗證的OpenGL 4.2

$ glxinfo | grep OpenGL 
OpenGL vendor string: NVIDIA Corporation 
OpenGL renderer string: GeForce GT 540M/PCIe/SSE2 
OpenGL version string: 4.2.0 NVIDIA 304.64 
OpenGL shading language version string: 4.20 NVIDIA via Cg compiler 
OpenGL extensions: 

注意:根據reference page。 「在任何頂點着色器對象綁定到指定的程序對象之前,可以調用glBindAttribLocation,也可以將通用屬性索引綁定到在頂點着色器中從不使用的屬性變量名稱。」所以沒有着色器被加載和DoesNotExist不存在的事實不是問題。

+0

可能是一個驅動程序錯誤,但爲什麼你這樣做?我沒有看到任何一點......也有4.2你有明確的屬性位置。 – yngccc

+0

這只是一個虛擬程序,用於複製更大程序中的錯誤。我知道在4.2中,我可以在我的着色器中定義屬性位置,但我已經按照綁定位置的方式來構建我的程序是最佳的。此外,這是我的另一臺運行OpenGL 4.2與Nvidia 560 GTX的機器上可重複。我會嘗試更新驅動程序 – jodag

回答

9

這是我第二次回想起這個問題,現在在幾個月內被問到。上次被問到這個問題時,雖然不是很明顯這是同一個問題,但是是here

它歸結爲:GL_MAX_VERTEX_ATTRIBS,因爲編譯器認爲它是一個預處理器標記,它定義了一個ID,可用於在運行時向OpenGL驅動程序詢問其實現定義的限制。當您嘗試直接打印此值時,您唯一要做的就是打印所有OpenGL實現用來查詢此特定限制的通用ID。

要獲得實際實現相關的限制,您需要在運行時要做到這一點:

int max_attribs; 
glGetIntegerv (GL_MAX_VERTEX_ATTRIBS, &max_attribs); 

順便說一句,OpenGL的實現只需要每頂點屬性來提供最低16;大多數只會給你最低限度,這就解釋了爲什麼20是超出界限的。

+0

太棒了!我測試過,你是對的,GL_MAX_VERTEX_ATTRIBS實際上是16. – jodag

+1

現在來到了困難的部分:你真的使用20個頂點屬性嗎?:)如果是這樣,你將需要找出方法來大幅度簡化你的頂點數據結構。請注意,諸如'mat4'之類的東西佔用了4個頂點attrib插槽。 –

+0

哈哈,我不需要20個頂點屬性,部分原因是我使用一個單一的VBO與多個程序與不同的頂點着色器。沒有單個頂點着色器具有超過4個頂點屬性。 – jodag