Results 1 to 6 of 6

Thread: Vertex buffers

  1. #1
    Junior Member Newbie
    Join Date
    Jun 2012
    Posts
    6

    Vertex buffers

    Hi,

    how many vertex buffers can I use simultaneously? I have a scene with many objects and each object has his own vertex buffer.

    OpenGL doesn't return any error but when I execute the program OpenGL draws only the last bufferVertex that I create.

    Thanks for any help.

  2. #2
    Senior Member Regular Contributor
    Join Date
    Jan 2012
    Location
    Germany
    Posts
    325

    Re: Vertex buffers

    You can fetch attributes from up to MAX_ATTRIB_LOCATIONS different VBOs at the same time (often 16) assuming you read one attribute per VBO. Those will be used for one rendercall.
    But that might not be what you meant, so i guess you want to render a lot of VBOs in sequence:

    activate VBO_0
    draw model
    activate VBO_1
    draw model
    ...

    there is no real limit to that (to be pedantic, you could get an out-of-memory or run out of names for the VBOs, but GLuint is 32bits...).

    Maybe you bind your VBOs and _then_ try to render? In that case only the last one will be bound during the render calls.
    Can you share some code so we can see how you try to render your scene?

  3. #3
    Junior Member Newbie
    Join Date
    Jun 2012
    Posts
    6

    Re: Vertex buffers

    Thanks for the answer. I'm binding each VBO before draw it like your example.

    The code is this:
    main.cpp
    Code :
    void display() {
    	glMatrixMode(GL_MODELVIEW);
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    	t->draw();
    	glutSwapBuffers();
    }
     
    T* t = new T();
     
    int main() {
    	glutInit...
     
    	glutDisplayFunc(display);
     
    }

    T.cpp
    Code :
    T::T() {
    	for (unsigned int i = 0; i < 15; i++)
    		for (unsigned int j = 0; j < 15; j++)
    			items.push_back(new T2(i, j)); //items is an attribute of the class. His type is std::list<T2>
    }
     
    void T::draw() {
    	std::list<T2>::iterator it;
     
    	for (it = items.begin(); it < items.end(); it++)
    		it->draw();
    }

    T2.cpp
    Code :
    T2::T2(int i, int j) {
    	float *vertexBuffer = getMyVertexArray(i, j);
    	unsigned int *indexBuffer = getMyIndexArray(i, j);
     
    	glGenBuffer(1, &amp;vertexBufferID);
    	glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
    	glBufferData(GL_ARRAY_BUFFER, numVertex * 3 * sizeof(float), vertexBuffer, GL_STREAM_DRAW);
    	glVertexPointer(3, GL_FLOAT, 0, (GLvoid*)((char*)NULL));
    	glEnableClientState(GL_VERTEX_ARRAY);
     
    	glGenBuffer(1, &amp;indexBufferID);
    	glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndexElements * sizeof(unsigned int), indexBuffer, GL_STREAM_DRAW);
    	glIndexPointer(GL_INT, 0, (GLvoid*)((char*)NULL));
    }
     
    void T2::draw() {
    	glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
    	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
    	glDrawElements(GL_TRIANGLE_STRIP, numIndexElements, GL_UNSIGNED_INT, (GLvoid*)((char*)NULL));
    }

    The trace of the program should be

    CreateVertexBuffer1
    CreateIndexBuffer1
    CreateVertexBuffer2
    CreateIndexBuffer2
    CreateVertexBuffer3
    CreateIndexBuffer3
    CreateVertexBuffer4
    CreateIndexBuffer4
    ...
    Later, when I draw
    BindVertexBuffer1
    BindIndexBuffer1
    drawElements
    BindVertexBuffer2
    BindIndexBuffer2
    drawElements
    BindVertexBuffer3
    BindIndexBuffer3
    drawElements
    ...

    And OpenGL draws only the vertexBuffer4 (supposing it is the last vertex buffer created)

    Thanks for any help

  4. #4
    Senior Member Regular Contributor
    Join Date
    Jan 2012
    Location
    Germany
    Posts
    325

    Re: Vertex buffers

    Buffer creation looks ok, but the glDrawElements will draw numIndexElements vertices as a tri-strip from the set vertex pointers/index pointer. those were defined in your constructor and implicitly used the currently bound VBOs as additional parameters to define the source of the data.
    So your constructors are overriding each other with the definition of what OpenGL should draw so each drawElements call will draw the same geometry. Binding the VBOs does not change what you draw. The glVertexPointer/glEnableClientState/glIndexPointer calls need to be called in your draw() method as well.

    If you switch to GL3 you can use VAOs which encapsulate all information needed for OpenGL to draw from VBOs, so with VAOs you would only need 2 calls for drawing: binding the VAO and a drawElements call. But first I would suggest fixing your draw function to understand how drawing works with just the elements you have now.

  5. #5
    Senior Member OpenGL Lord
    Join Date
    Mar 2015
    Posts
    6,674

    Re: Vertex buffers

    Code :
    glIndexPointer(GL_INT, 0, (GLvoid*)((char*)NULL));

    Never call `glIndexPointer`. It absolutely does not do what you think it does. That's not your problem, but you shouldn't be calling it.

    In any case, your problem is that you're not quite understanding how buffer objects work with vertex data.

    This:

    Code :
    glGenBuffer(1, &amp;vertexBufferID);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
    glBufferData(GL_ARRAY_BUFFER, numVertex * 3 * sizeof(float), vertexBuffer, GL_STREAM_DRAW);

    is an example of how to create a buffer object (though unless you are actually streaming vertex data, which you aren't, you shouldn't be using GL_STREAM_DRAW. You should use GL_STATIC_DRAW). You create the buffer object, allocate a particular size, and copy some data into it. All well and good.

    The problem is what you do next.

    Code :
    glVertexPointer(3, GL_FLOAT, 0, (GLvoid*)((char*)NULL));
    glEnableClientState(GL_VERTEX_ARRAY);

    This is the correct code, but it shouldn't be here. This is not initialization-time code. This is code you use to draw with a particular buffer object.

    See, because of legacy BS of the API, how you render with buffer objects is slightly convoluted. The buffer you bind to GL_ARRAY_BUFFER does not get used for rendering. To specify how to render data from a buffer object, you need two things: the buffer object itself, and the vertex format. The latter is provided by `glVertexPointer` for position data, coupled with `glEnableClientState(GL_VERTEX_ARRAY)`.

    So, when it comes time to draw, you have to provide both the buffer object and its format. So the above code isn't initialization code; it is rendering code:

    Code :
    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
    glVertexPointer(3, GL_FLOAT, 0, (GLvoid*)((char*)NULL));
    glEnableClientState(GL_VERTEX_ARRAY);
     
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
    glDrawElements(GL_TRIANGLE_STRIP, numIndexElements, GL_UNSIGNED_INT, (GLvoid*)((char*)NULL));

  6. #6
    Junior Member Newbie
    Join Date
    Jun 2012
    Posts
    6

    Re: Vertex buffers

    It's that!! Thanks for the help!

Similar Threads

  1. how to bind two vertex buffers to vertex shader input, as in DirectX
    By saman_artorious in forum OpenGL: Basic Coding
    Replies: 14
    Last Post: 07-01-2013, 10:35 PM
  2. Indexed Vertex Buffers?
    By Raeldor in forum OpenGL: Basic Coding
    Replies: 6
    Last Post: 07-10-2005, 02:14 AM
  3. Intermediate vertex buffers
    By santyhamer in forum OpenGL: General
    Replies: 8
    Last Post: 03-29-2004, 02:32 AM
  4. vertex-buffers and vertex-program
    By close2 in forum OpenGL: GLSL
    Replies: 4
    Last Post: 02-11-2004, 09:59 AM
  5. Vertex Buffers and render/texture Buffers
    By schelter in forum OpenGL: General
    Replies: 4
    Last Post: 02-03-2002, 08:00 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Proudly hosted by Digital Ocean