Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assist me to understand OpenGL glGenBuffers()

Here is the deal: If I leave the code with glGenBuffers(1, vertexBuffers), the code compiles and works. But, I thought that it should be 2 since vertexBuffers is of size two.

Am I missing something?

Code below:

-(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];
}
like image 763
xBACP Avatar asked Aug 24 '12 03:08

xBACP


People also ask

What is a target in OpenGL?

In General Most OpenGL objects must be bound to locations in the OpenGL context called "targets" for them to be used. A target is nothing more than a place in the context where objects are bound. Different object types (buffers, textures, etc) have different sets of targets.

What does glBufferData do?

Description. glBufferData creates a new data store for the buffer object currently bound to target . Any pre-existing data store is deleted. The new data store is created with the specified size in bytes and usage .

What is binding in OpenGL?

A Binding Point specifies the behavior of the OpenGL object. Binding Points, also known as Targets, allows OpenGL objects to be used for different purposes. The most common binding points are: GL_ARRAy_BUFFER.

What is glGenBuffers?

Description. glGenBuffers returns n buffer object names in buffers . There is no guarantee that the names form a contiguous set of integers; however, it is guaranteed that none of the returned names was in use immediately before the call to glGenBuffers .


2 Answers

Assuming that vertexBuffers is declared as something like:

GLuint vertexBuffers[2];

then your code is probably not quite doing what you think. The first argument to glGenBuffers() is the number of buffers you want to generate, and the second argument is a pointer to an array of that many buffers. So you probably want to do:

glGenBuffers (2, vertexBuffers);

This tells OpenGL to generate 2 buffer names and to store them in 2 contiguous locations in memory starting at the address of vertexBuffers.

like image 145
user1118321 Avatar answered Sep 23 '22 23:09

user1118321


glGenBuffers doesn't work quite like what you expect. When you call glGenBuffers, it doesn't actually create anything. It just returns a list of integers that are not currently used as buffer names.

The actual 'object' is not created until you call glBindBuffer. So you can just make up any integer you like and pass it to glBindBuffer and a valid buffer will be created at that index. glGenBuffers is actually not required at all, it's just there as a convenience function to give you an unused integer.

So if you just create an array of random integers, as long as none of them overlap, you can use that as your list of buffers without calling glGenBuffers. That's why your code works whether you tell glGenBuffers to create 1 or 2 buffers. As long as you have two buffers with two different names, it doesn't matter where the integer came from.

A little demonstration:

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
like image 32
Tim Avatar answered Sep 25 '22 23:09

Tim