2012-08-24 40 views
4

这里是交易。如果我用glGenBuffers(1,vertexBuffers)离开代码,代码编译是可行的。但是,我认为它应该是2,因为vertexBuffers的大小是2。帮助我了解的OpenGL glGenBuffers

我错过了什么吗?下面

代码:

-(void)drawRect:(NSRect)dirtyRect 
{  
    // get program ID for shader program 
    GLuint programID = [self loadShaders]; 

    // get new dimensions 
    NSSize dim = [self frame].size; 

    // clear the background with color 
    glClearColor(0.0, 0.0, 0.0, 0.4); 
    glDepthRange(0.1, 100.0); 
    glViewport(0, 0, dim.width, dim.height); 
    glClear(GL_COLOR_BUFFER_BIT); 

    // vertex data 
    GLfloat vertexPositionData[] = {-dim.width/2, -dim.height/2, 0.0, 5.0, 
     dim.width/2, -dim.height/2, 0.0, 5.0, 
     0.0, dim.height/2, 0.0, 5.0}; 

    GLfloat vertexColorData[] = {1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.5, 0.0, 0.0, 1.0, 0.5}; 

    GLfloat scaleMatrixData[] = {1/(dim.width/2), 0.0, 0.0, 0.0, 
     0.0, 1/(dim.height/2), 0.0, 0.0, 
     0.0, 0.0, 1.0, 0.0, 
     0.0, 0.0, 0.0, 1.0}; 

    GLint scaleMatrixUniform = glGetUniformLocation(programID, "scaleMatrix"); 

    // generate a buffer for our triangle 
    glGenBuffers(1, vertexBuffers); 

    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[0]); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositionData), vertexPositionData, GL_STATIC_DRAW); 
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[1]); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexColorData), vertexColorData, GL_STATIC_DRAW); 
    //glBindBuffer(GL_ARRAY_BUFFER, 0); 

    glUseProgram(programID); 

    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[0]); 
    glEnableVertexAttribArray(VERTEX_POS_INDEX); 
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[1]); 
    glEnableVertexAttribArray(VERTEX_COLOR_INDEX); 
    glVertexAttribPointer(VERTEX_POS_INDEX, VERTEX_POS_SIZE, GL_FLOAT, GL_FALSE, 0, vertexPositionData); 
    glVertexAttribPointer(VERTEX_COLOR_INDEX, VERTEX_COLOR_SIZE, GL_FLOAT, GL_FALSE, 0, vertexColorData); 

    glUniformMatrix4fv(scaleMatrixUniform, 1, GL_FALSE, scaleMatrixData); 

    glDrawArrays(GL_TRIANGLES, 0, 3); 

    glDisableVertexAttribArray(0); 
    glDisableVertexAttribArray(1); 
    glUseProgram(0); 

    // flush buffer 
    glFlush(); 
    [[self openGLContext] flushBuffer]; 
} 
+2

什么'vertexBuffers'的声明? – JWWalker

+0

@JWWalker,我提到vertexBuffers的大小是两个数组。 – xBACP

回答

8

假设vertexBuffers声明,就像这样:

GLuint vertexBuffers[2]; 

那么你的代码可能不太做你的想法。 glGenBuffers()的第一个参数是要生成的缓冲区的数量,第二个参数是指向那么多缓冲区的数组的指针。所以,你可能想要做:

glGenBuffers (2, vertexBuffers); 

这告诉OpenGL,产生2个缓冲区名字并将它们存储在内存2个连续位置开始的vertexBuffers地址。

+0

我了解您的评论。然而,vertexbuffers的大小是2,但在我的代码中我有这个:glGenBuffers(1,vertexBuffers),程序工作正常。如果我将1更改为2,则不再显示三角形。 – xBACP

+0

如果你看看Tim的回答,他解释了为什么它即使在你不生成缓冲区的情况下也能正常工作。这是OpenGL如何工作的一个怪癖,但可能不是你想要的。 – user1118321

20

glGenBuffers并不很喜欢你所期望的工作。当你拨打glGenBuffers时,它实际上并没有创建什么。它只是返回一个当前未用作缓冲区名称的整数列表。

实际的“对象”不创建直到调用glBindBuffer。所以你可以构造你喜欢的任何整数,并将它传递给glBindBuffer,并在该索引处创建一个有效的缓冲区。实际上根本不需要glGenBuffers,它只是作为一个便利功能给你一个未使用的整数。

所以如果你只是创建一个随机整数数组,只要它们没有重叠,你可以使用它作为你的缓冲区列表而不需要调用glGenBuffers。这就是为什么你的代码工作,无论你告诉glGenBuffers创建1或2缓冲区。只要你有两个不同名称的缓冲区,整数来自何处并不重要。

小演示:

int buf; 
glGenBuffers(1, &buf); 
glIsBuffer(buf); //FALSE - buffer has not been created yet 
glBindBuffer(GL_ARRAY_BUFFER, buf); 
glIsBuffer(buf); //TRUE - buffer created on bind 
+0

在最近的OpenGL中,glGenBuffers是必需的。 – KillianDS

+0

此外,IsBuffer应根据规范返回true:'如果buffer是缓冲区对象的名称,则返回TRUE。如果缓冲器是零,或者如果缓冲器是 非零值,该值不是一个缓冲对象的名称,IsBuffer返回FALSE.' – KillianDS

+0

规格约'glGenBuffers'要求:'如果缓冲器不是零或产生一个错误INVALID_OPERATION名称 从以前的调用GenBuffers返回,或者如果这样的名字已经被用DeleteBuffers' – KillianDS

2

昨天我想通了这一点,我需要做一个glBindBuffer(GL_ARRAY_BUFFER,0)后,每个glBufferData(...)。