Requesting help with VBO's

classic Classic list List threaded Threaded
17 messages Options
Reply | Threaded
Open this post in threaded view
|

Requesting help with VBO's

Braindrool

I'm new to the forums, so short introduction? Hi.

Next on the agenda, I'd like to clear out that I have been programming for years, but I have very little experience with OpenGL. I started a project a few days ago and was hoping that a kind spirit would make a complete step-by-step tutorial for VBO's. I have looked up documentation and "tutorials," but with little luck.

As for as the OpenGL progress goes I have a packed vertex array and an index array. I already have the project setup in Eclipse.

Help greatly appreciated! ~Braindrool

P.s. I frequently check email, if you need any more information please do ask
Reply | Threaded
Open this post in threaded view
|

Re: Requesting help with VBO's

gouessej
Administrator
Hi

I used these classes (still based on JOGL 1) to handle vertex arrays and VBOs:
http://tuer.svn.sourceforge.net/viewvc/tuer/alpha/drawer/VertexArray.java?revision=123&content-type=text%2Fplain
http://tuer.svn.sourceforge.net/viewvc/tuer/alpha/drawer/DynamicVertexBufferObject.java?revision=123&content-type=text%2Fplain

Just look at the key differences. When you create a VBO, you need to call glGenBuffers (to create the identifier), glBindBuffer (to bind the current buffer) and glBufferData (to associate the data store on the GPU to a buffer on the CPU if any and to set the "update" mode). This "update" mode can be ignored by the driver, it is an hint, it changes nothing under very early implementations of VBO whereas it can be very efficient on recent graphics cards.

Call glBindBuffer when you want to use a VBO just before drawing. Sometimes you might have to call glBindBuffer with 0 to unbind a buffer.

Good luck.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Requesting help with VBO's

Wade Walker
Administrator
In reply to this post by Braindrool
Reply | Threaded
Open this post in threaded view
|

Re: Requesting help with VBO's

Braindrool
Looks useful. But a few questions stand.

//================================================================
/**
 * Creates vertex buffer object used to store vertices and colors
 * (if it doesn't exist). Fills the object with the latest
 * vertices and colors from the data store.
 *
 * @param gl2 GL object used to access all GL functions.
 * @return the number of vertices in each of the buffers.
 */
protected int [] createAndFillVertexBuffer( GL2 gl2, List<DataObject> listDataObjects ) {

    int [] aiNumOfVertices = new int [] {listDataObjects.size() * 4};
       
    // create vertex buffer object if needed
    if( aiVertexBufferIndices[0] == -1 ) {
        // check for VBO support
        if(    !gl2.isFunctionAvailable( "glGenBuffers" )
            || !gl2.isFunctionAvailable( "glBindBuffer" )
            || !gl2.isFunctionAvailable( "glBufferData" )
            || !gl2.isFunctionAvailable( "glDeleteBuffers" ) ) {
            Activator.openError( "Error", "Vertex buffer objects not supported." );
        }

        gl2.glGenBuffers( 1, aiVertexBufferIndices, 0 );

        // create vertex buffer data store without initial copy
        gl2.glBindBuffer( GL.GL_ARRAY_BUFFER, aiVertexBufferIndices[0] );
        gl2.glBufferData( GL.GL_ARRAY_BUFFER,
                          aiNumOfVertices[0] * 3 * Buffers.SIZEOF_FLOAT * 2,
                          null,
                          GL2.GL_DYNAMIC_DRAW );
    }

    // map the buffer and write vertex and color data directly into it
    gl2.glBindBuffer( GL.GL_ARRAY_BUFFER, aiVertexBufferIndices[0] );
    ByteBuffer bytebuffer = gl2.glMapBuffer( GL.GL_ARRAY_BUFFER, GL2.GL_WRITE_ONLY );
    FloatBuffer floatbuffer = bytebuffer.order( ByteOrder.nativeOrder() ).asFloatBuffer();

    for( DataObject dataobject : listDataObjects )
        storeVerticesAndColors( floatbuffer, dataobject );

    gl2.glUnmapBuffer( GL.GL_ARRAY_BUFFER );

    return( aiNumOfVertices );
}

1. listDataObjects is just the vertex data?

2. aiVertexBufferIndices is?

3. Could you do the traditional Byte / FloatBuffer as in X = Bytebuffer.allocateDirect( size ).asFloatBuffer().order(Buffer.nativeOrder())? Or however that goes.
Reply | Threaded
Open this post in threaded view
|

Re: Requesting help with VBO's

Wade Walker
Administrator
Braindrool wrote
1. listDataObjects is just the vertex data?
2. aiVertexBufferIndices is?
3. Could you do the traditional Byte / FloatBuffer as in X = Bytebuffer.allocateDirect( size ).asFloatBuffer().order(Buffer.nativeOrder())? Or however that goes.
1. Oops, I missed a @param when I wrote this :) Yes, listDataObjects is just a list of class instances, each of which is a colored quad in my case. A DataObject is just meant to represent some object in the host application that needs to be drawn. storeVerticesAndColors() is responsible for turning such an object into vertex and color data and putting it in the VBO. Normally apps copy their data into the VBO when it's time to draw, instead of just maintaining it there always (because VBO memory is allocated and managed by the OpenGL kernel driver).

2. There's should be comment for aiVertexBufferIndices at the top of the file. It's the array of integer VBO indices returned by gl2.glGenBuffers().

3. I don't think so. The VBO must be allocated by OpenGL, then you put data into it by "mapping" a FloatBuffer over it as shown. If you call Bytebuffer.allocateDirect() as you showed, you're allocating the memory yourself, it's not being managed by the OpenGL driver, so its contents are unknown to OpenGL.
Reply | Threaded
Open this post in threaded view
|

Re: Requesting help with VBO's

Braindrool
2. What if you already have an array of indices?
Reply | Threaded
Open this post in threaded view
|

Re: Requesting help with VBO's

Wade Walker
Administrator
You might be thinking of a different kind of indices :) These "indices" are essentially just the names of VBOs created by the OpenGL driver (like file handles). This example uses a vertex buffer, but not an index buffer, so there are no primitive indices that map primitives onto vertices in the buffer -- the glDrawArrays() call just assumes an index buffer of the form {0, 1, 2, 3, 4, 5, ... }.
Reply | Threaded
Open this post in threaded view
|

Re: Requesting help with VBO's

Braindrool
This might sound a bit greedy, but do you think you could just write a short, working example from my code?

The basics of course:

package com.braindrool.game;

import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;

public class Renderer implements GLEventListener {


        public void display(GLAutoDrawable drawable) {
        }

        public void dispose(GLAutoDrawable arg0) {

        }

        public void init(GLAutoDrawable drawable) {
        }

        public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3,
                        int arg4) {

        }

}

I already have a .ply model loader / scanner / transformer. E.g. model.load("models/monkey.ply") will return a FloatBuffer of the packed Vertices from file. But if you do decide to do this (which I very much hope you do ^^), would you please put in detail step-by-step what you're doing? I'd prefer to have all my questions answered in one response, but everyone knows a panacea doesn't exist :P
Reply | Threaded
Open this post in threaded view
|

Re: Requesting help with VBO's

Wade Walker
Administrator
Braindrool wrote
... do you think you could just write a short, working example from my code?
Dude, for reals?  Seriously, the only way to learn that stuff is just dig in and start writing it -- if I write it for you, you'll never get any better at it  Just start from a working tutorial (mine or someone else's), then just hack your code into it a bit at a time. That way you've always got something that works, and you can't get too far off the track. Good luck!
Reply | Threaded
Open this post in threaded view
|

Re: Requesting help with VBO's

Braindrool
Meh, I suppose you are right. I believe this will be my final question though!

ByteBuffer bytebuffer = gl.glMapBuffer( GL.GL_ARRAY_BUFFER, GL2.GL_WRITE_ONLY );
    FloatBuffer floatbuffer = bytebuffer.order( ByteOrder.nativeOrder() ).asFloatBuffer();

Mind elaborating on glMapBuffer a bit? I see several C tutorials. Another question would be, how would I just use my FloatBuffer parameter? It would be more convenient for me.

And to make sure I have this understood correctly. Use an int to create a VBO handle, generate VBO, allocate space, map data, return the VBO handle as a drawing object. Yes?
Reply | Threaded
Open this post in threaded view
|

Re: Requesting help with VBO's

Wade Walker
Administrator
Braindrool wrote
ByteBuffer bytebuffer = gl.glMapBuffer( GL.GL_ARRAY_BUFFER, GL2.GL_WRITE_ONLY );
FloatBuffer floatbuffer = bytebuffer.order( ByteOrder.nativeOrder() ).asFloatBuffer();

Mind elaborating on glMapBuffer a bit? I see several C tutorials. Another question would be, how would I just use my FloatBuffer parameter? It would be more convenient for me.
glMapBuffer() is needed because to write to a VBO using the CPU, the VBO must be in system memory, but to render a VBO with your GPU, the VBO must be in your graphics card's memory. On a desktop PC, those two memories are physically separate, and the only communication between them is via the PCI bus. So (naively speaking) glMapBuffer() copies the VBO from graphics card memory into system memory, then returns a pointer to it that the CPU can use (the pointer is inside the returned ByteBuffer). Then bytebuffer.order( ByteOrder.nativeOrder() ).asFloatBuffer() re-wraps that pointer so you can write floats to it from Java. Finally glUnmapBuffer() flushes the system-memory copy of the VBO back out to graphics card memory so the GPU can render it.

This picture may be a bit more complex in reality, since the OpenGL driver can try to optimize memory traffic over the PCI bus by not copying data that hasn't changed (so it may not copy the VBO back from the graphics card, it may just keep a local copy). The driver can also batch up bus operations, so they may not happen right when you make the OpenGL calls. And finally, on a mobile platform like a cell phone or tablet, the system and GPU memories are not physically separate, so there's no bus flushing at all, though the driver may still have to keep CPU and GPU data in separate address spaces.

Braindrool wrote
And to make sure I have this understood correctly. Use an int to create a VBO handle, generate VBO, allocate space, map data, return the VBO handle as a drawing object. Yes?
glGenBuffers() - create VBO "handle" (really just an integer index to some driver-maintained list of VBOs)
glBufferData() - "allocates space" (exactly where and how is left up to the OpenGL driver)
glMapBuffer() - get system pointer to VBO
glUnmapBuffer() - flush VBO changes out to graphics card

plus:

glBindBuffer() - tells OpenGL which VBO subsequent OpenGL calls will refer to

All these calls are documented in detail at http://www.opengl.org/, though not in a very beginner-friendly form.
Reply | Threaded
Open this post in threaded view
|

Re: Requesting help with VBO's

Braindrool
You have my thanks for helping me. I successfully created a VBO renderer. Would have helped though if I knew the model I was using was bugged.

http://imgur.com/dG8Fz
Reply | Threaded
Open this post in threaded view
|

Re: Requesting help with VBO's

Wade Walker
Administrator
You're welcome!  I'm glad things are working now.
Reply | Threaded
Open this post in threaded view
|

Re: Requesting help with VBO's

Braindrool
You seem plenty experienced with JOGL so far, so thought I might notify you of my most recent post. http://forum.jogamp.org/Loading-attributes-in-a-packed-buffer-td4027450.html

I would greatly appreciated more help!
Reply | Threaded
Open this post in threaded view
|

Re: Requesting help with VBO's

sunnystormy
Did you manage to get things working, Brain? I'm kind of going through the same stuff myself. I want to learn an efficient way to create VBOs so I can move beyond "immediate mode" OpenGL... >_>
Reply | Threaded
Open this post in threaded view
|

Re: Requesting help with VBO's

gouessej
Administrator
I already gave several examples, there is one using interleaved arrays in my source code.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Requesting help with VBO's

Braindrool
In reply to this post by sunnystormy
Found an easy way for OpenGL, not OpenGLES. But yes, I got it to work.

On Tue, Mar 5, 2013 at 3:53 PM, sunnystormy [via jogamp] <[hidden email]> wrote:
Did you manage to get things working, Brain? I'm kind of going through the same stuff myself. I want to learn an efficient way to create VBOs so I can move beyond "immediate mode" OpenGL. : P


If you reply to this email, your message will be added to the discussion below:
http://forum.jogamp.org/Requesting-help-with-VBO-s-tp4027348p4028522.html
To unsubscribe from Requesting help with VBO's, click here.
NAML