Hello Guest

# Vertex Array / VBO

• 10 Replies
• 16722 Views

#### Rainer

• 71
##### Vertex Array / VBO
« on: December 11, 2007, 08:34:58 »
I need to render a lot of dynamic poligons.
After some searching i found that VBO would be the right solution to do this.
Now there are some tutorials about VBO (http://lwjgl.org/wiki/doku.php/lwjgl/tutorials/opengl/basicvbo and http://lwjgl.org/wiki/doku.php/lwjgl/tutorials/opengl/speedyvbo), but they tell me i should understand vertex arrays first.
So i googled for lwjgl vertex array, but can't find any tutorial about how to do the vertex arrays in lwjgl.
Is there somewhere a tutorial i couldn't find, or can someone give me an instruction?

#### grom358

• 5
##### Re: Vertex Array / VBO
« Reply #1 on: December 11, 2007, 10:04:54 »
Here is an example of using vertex array to draw a Cube. With LWJGL you have to use nio buffers for the arrays.

Code: [Select]
`private void initGL() {        GL11.glEnable(GL11.GL_TEXTURE_2D); // Enable Texture Mapping        GL11.glShadeModel(GL11.GL_SMOOTH); // Enable Smooth Shading        GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background        GL11.glClearDepth(1.0); // Depth Buffer Setup        GL11.glEnable(GL11.GL_DEPTH_TEST); // Enables Depth Testing        GL11.glDepthFunc(GL11.GL_LEQUAL); // The Type Of Depth Testing To Do        GL11.glMatrixMode(GL11.GL_PROJECTION); // Select The Projection Matrix        GL11.glLoadIdentity(); // Reset The Projection Matrix        // Calculate The Aspect Ratio Of The Window        GLU.gluPerspective(          45.0f,          (float) WINDOW_WIDTH / (float) WINDOW_HEIGHT,          0.1f,          100.0f);        GL11.glMatrixMode(GL11.GL_MODELVIEW); // Select The Modelview Matrix        // Really Nice Perspective Calculations        GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);                     vertices = BufferUtils.createFloatBuffer(3 * 4 * 6);        vertices.put(new float[] {        -1.0f, -1.0f, 1.0f,        1.0f, -1.0f, 1.0f,        1.0f, 1.0f, 1.0f,        -1.0f, 1.0f, 1.0f,                -1.0f, -1.0f, -1.0f,        -1.0f, 1.0f, -1.0f,        1.0f, 1.0f, -1.0f,        1.0f, -1.0f, -1.0f,                -1.0f, 1.0f, -1.0f,        -1.0f, 1.0f, 1.0f,        1.0f, 1.0f, 1.0f,        1.0f, 1.0f, -1.0f,                -1.0f, -1.0f, -1.0f,        1.0f, -1.0f, -1.0f,        1.0f, -1.0f, 1.0f,        -1.0f, -1.0f, 1.0f,                1.0f, -1.0f, -1.0f,        1.0f, 1.0f, -1.0f,        1.0f, 1.0f, 1.0f,        1.0f, -1.0f, 1.0f,                -1.0f, -1.0f, -1.0f,        -1.0f, -1.0f, 1.0f,        -1.0f, 1.0f, 1.0f,        -1.0f, 1.0f, -1.0f});        } /** * Render the current frame */ private void render() {        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer        GL11.glLoadIdentity(); // Reset The Current Modelview Matrix        GL11.glTranslatef(0.0f, 0.0f, z); // Move Into The Screen 5 Units        GL11.glRotatef(xrot, 1.0f, 0.0f, 0.0f); // Rotate On The X Axis        GL11.glRotatef(yrot, 0.0f, 1.0f, 0.0f); // Rotate On The Y Axis        GL11.glRotatef(zrot, 0.0f, 0.0f, 1.0f); // Rotate On The Z Axis        GL11.glColor3f(1.0f, 1.0f, 1.0f);                // Enable vertex arrays        GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);        // Setup vertex array pointer        vertices.rewind();        GL11.glVertexPointer(3, 0, vertices);        // Draw using vertex array        GL11.glDrawArrays(GL11.GL_QUADS, 0, 24);        // Disable vertex arrays        GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY); }`

#### Rainer

• 71
##### Re: Vertex Array / VBO
« Reply #2 on: December 12, 2007, 09:09:20 »
Thanks, this helps me

Next thing: how can i add normals?

#### Rainer

• 71
##### Re: Vertex Array / VBO
« Reply #3 on: December 12, 2007, 11:54:42 »
i now finished implementing the vertexarrays in my engine, it works fine on smaller arrays, but if it's a large array (lets say 150000) it crashes:

#
# An unexpected error has been detected by Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0xb7ed19ac, pid=9665, tid=2897963920
#
# Java VM: Java HotSpot(TM) Client VM (1.6.0_03-b05 mixed mode)
# Problematic frame:
# C  [libc.so.6+0x6e9ac]  memcpy+0x1c
#
# An error report file with more information is saved as hs_err_pid9665.log
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#

should i divide it into several smaller arrays, or doesn't this problem exist if i change it to vbo?

#### Rainer

• 71
##### Re: Vertex Array / VBO
« Reply #4 on: December 12, 2007, 13:20:32 »
I now tried to do the VBO, I followed the above mentioned tutorial.

I have a Problem at:
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB, indexBufferID);
GL12.glDrawRangeElements(GL11.GL_TRIANGLES, 0, maxIndex, indexBufferSize,
GL11.GL_UNSIGNED_INT, 0);

How do i have to do the Rendering? What is the indexBudderID and where do i get it?

#### grom358

• 5
##### Re: Vertex Array / VBO
« Reply #5 on: December 12, 2007, 14:11:51 »
indexBufferID is the texture id

Code: [Select]
`public static int createVBOID() {  if (GLContext.getCapabilities().GL_ARB_vertex_buffer_object) {    IntBuffer buffer = BufferUtils.createIntBuffer(1);    ARBVertexBufferObject.glGenBuffersARB(buffer);    return buffer.get(0);  }  return 0;}int indexBufferID = createVBOID();`

#### Rainer

• 71
##### Re: Vertex Array / VBO
« Reply #6 on: December 12, 2007, 21:07:19 »
Well, now i have no errors anymore, and some nice FPS count, only problem: my landscape completly disappeared
Is there somewhere a complete piece of code how to create the VBO?
I can't get it to work

#### grom358

• 5
##### Re: Vertex Array / VBO
« Reply #7 on: December 13, 2007, 08:03:54 »
Btw.. in my last post I meant to say its the vertex buffer object ID. Its like a texture ID. Below is working VBO example

Code: [Select]
`import java.nio.FloatBuffer;import java.nio.IntBuffer;import org.lwjgl.BufferUtils;import org.lwjgl.LWJGLException;import org.lwjgl.Sys;import org.lwjgl.input.Keyboard;import org.lwjgl.opengl.ARBVertexBufferObject;import org.lwjgl.opengl.Display;import org.lwjgl.opengl.DisplayMode;import org.lwjgl.opengl.GL11;import org.lwjgl.opengl.GL12;import org.lwjgl.opengl.GLContext;import org.lwjgl.opengl.Util;import org.lwjgl.opengl.glu.GLU;public class CubeDemo { private static final String TITLE = "Cube Demo"; private static final int FRAMERATE = 60; private static final int WINDOW_WIDTH = 640; private static final int WINDOW_HEIGHT = 480; private volatile boolean isPaused = false; private volatile boolean isRunning = false;    private float xrot = 0f;       // X Rotation    private float yrot = 0f;       // Y Rotation    private float zrot = 0f;       // Z Rotation    private float xspeed = 0.3f;   // X Rotation Speed    private float yspeed = 0.2f;   // Y Rotation Speed    private float zspeed = 0.4f;   // Z Rotation Speed    private float z = -5.0f;       // Depth Into The Screen /** * Application init * * @param args *            Commandline arguments */ public static void main(String[] args) { CubeDemo animation = null; try { animation = new CubeDemo(); animation.run(); } catch (Exception e) { e.printStackTrace(System.err); Sys.alert(TITLE, "An error occured and the game will exit."); } finally { if(animation != null) animation.cleanup(); } System.exit(0); } /** * Determine an available display that matches the specified paramaters. * * @param width *            The desired width of the screen * @param height *            The desired height of the screen * @param bpp *            The desired colour depth (bits per pixel) of the screen * @return The display mode matching the requirements or null if none could *         be found * @throws LWJGLException *             Indicates a failure interacting with the LWJGL library. */ private static DisplayMode findDisplayMode(int width, int height, int bpp) throws LWJGLException { DisplayMode[] modes = Display.getAvailableDisplayModes(); DisplayMode mode = null; for (int i = 0; i < modes.length; i++) { if ((modes[i].getBitsPerPixel() == bpp) || (mode == null)) { if ((modes[i].getWidth() == width) && (modes[i].getHeight() == height)) { mode = modes[i]; } } } return mode; } /** * Initialise the animation * * @throws Exception *             if init fails */ public CubeDemo() throws Exception { // find out what the current bits per pixel of the desktop is int currentBpp = Display.getDisplayMode().getBitsPerPixel(); // find a display mode at 800x600 DisplayMode mode = findDisplayMode(WINDOW_WIDTH, WINDOW_HEIGHT, currentBpp); // if can't find a mode, notify the user the give up if (mode == null) { Sys.alert("Error", WINDOW_WIDTH + "x" + WINDOW_HEIGHT + "x" + currentBpp + " display mode unavailable"); return; } Display.setTitle(TITLE); Display.setDisplayMode(mode); Display.setFullscreen(false); // Enable vsync if we can Display.setVSyncEnabled(true); Display.create(); initGL(); } /** The time since the last record of fps */ private long lastFpsTime = 0; /** The recorded fps */ private int fps = 0; /** * Runs the animation (the "main loop") */ private void run() { long lastLoopTime, delta; Thread.currentThread().setPriority(Thread.MAX_PRIORITY); isRunning = true; lastLoopTime = System.nanoTime(); while (isRunning) { delta = System.nanoTime() - lastLoopTime; lastLoopTime = System.nanoTime(); lastFpsTime += delta; fps++; // update our FPS counter if a second has passed if (lastFpsTime >= 1000000000L) { Display.setTitle(TITLE +" (FPS: " + fps + ")"); lastFpsTime = 0; fps = 0; } // Always call Display.update(), all the time Display.update(); if (Display.isCloseRequested()) { // Check for O/S close requests isRunning = false; } else if (Display.isActive()) { // The window is in the foreground, so we should play the game logic(delta); render(); Display.sync(FRAMERATE); } else { // The window is not in the foreground, so we can allow other // stuff to run and // infrequently update try { Thread.sleep(100); } catch (InterruptedException e) { } logic(delta); if (Display.isVisible() || Display.isDirty()) { // Only bother rendering if the window is visible or dirty render(); } } } } private boolean pausePressed = false; private boolean resetPressed = false; /** * Do all calculations, handle input, etc. */ private void logic(long delta) { if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) { isRunning = false; } if (Keyboard.isKeyDown(Keyboard.KEY_P) && !pausePressed) { pausePressed = true; isPaused = !isPaused; } if (!Keyboard.isKeyDown(Keyboard.KEY_P)) { pausePressed = false; } if (isPaused) return; if (Keyboard.isKeyDown(Keyboard.KEY_R) && !resetPressed) { resetPressed = true; // Reset speeds xspeed = 0.3f;     yspeed = 0.2f;     zspeed = 0.4f; } if (!Keyboard.isKeyDown(Keyboard.KEY_R)) { resetPressed = false; }        if (Keyboard.isKeyDown(Keyboard.KEY_PRIOR)) {            z -= 0.02f;        }        if (Keyboard.isKeyDown(Keyboard.KEY_NEXT)) {            z += 0.02f;        }        if (Keyboard.isKeyDown(Keyboard.KEY_UP)) {            xspeed -= 0.01f;        }        if (Keyboard.isKeyDown(Keyboard.KEY_DOWN)) {            xspeed += 0.01f;        }        if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) {            yspeed += 0.01f;        }        if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) {            yspeed -= 0.01f;        }        if (Keyboard.isKeyDown(Keyboard.KEY_A)) {        zspeed -= 0.01f;        }        if (Keyboard.isKeyDown(Keyboard.KEY_Z)) {        zspeed += 0.01f;        }        if (Keyboard.isKeyDown(Keyboard.KEY_COMMA)) {        xspeed -= 0.01f;        yspeed -= 0.01f;        zspeed -= 0.01f;        }        if (Keyboard.isKeyDown(Keyboard.KEY_PERIOD)) {        xspeed += 0.01f;        yspeed += 0.01f;        zspeed += 0.01f;        }        xrot += xspeed; // X Axis Rotation        yrot += yspeed; // Y Axis Rotation        zrot += zspeed; // Z Axis Rotation }    private void initGL() {        GL11.glEnable(GL11.GL_TEXTURE_2D); // Enable Texture Mapping        GL11.glShadeModel(GL11.GL_SMOOTH); // Enable Smooth Shading        GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background        GL11.glClearDepth(1.0); // Depth Buffer Setup        GL11.glEnable(GL11.GL_DEPTH_TEST); // Enables Depth Testing        GL11.glDepthFunc(GL11.GL_LEQUAL); // The Type Of Depth Testing To Do        GL11.glMatrixMode(GL11.GL_PROJECTION); // Select The Projection Matrix        GL11.glLoadIdentity(); // Reset The Projection Matrix        // Calculate The Aspect Ratio Of The Window        GLU.gluPerspective(          45.0f,          (float) WINDOW_WIDTH / (float) WINDOW_HEIGHT,          0.1f,          100.0f);        GL11.glMatrixMode(GL11.GL_MODELVIEW); // Select The Modelview Matrix        // Really Nice Perspective Calculations        GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);                     vertices = BufferUtils.createFloatBuffer(3 * 4 * 6);        vertices.put(new float[] {        -1.0f, -1.0f, 1.0f,        1.0f, -1.0f, 1.0f,        1.0f, 1.0f, 1.0f,        -1.0f, 1.0f, 1.0f,                -1.0f, -1.0f, -1.0f,        -1.0f, 1.0f, -1.0f,        1.0f, 1.0f, -1.0f,        1.0f, -1.0f, -1.0f,                -1.0f, 1.0f, -1.0f,        -1.0f, 1.0f, 1.0f,        1.0f, 1.0f, 1.0f,        1.0f, 1.0f, -1.0f,                -1.0f, -1.0f, -1.0f,        1.0f, -1.0f, -1.0f,        1.0f, -1.0f, 1.0f,        -1.0f, -1.0f, 1.0f,                1.0f, -1.0f, -1.0f,        1.0f, 1.0f, -1.0f,        1.0f, 1.0f, 1.0f,        1.0f, -1.0f, 1.0f,                -1.0f, -1.0f, -1.0f,        -1.0f, -1.0f, 1.0f,        -1.0f, 1.0f, 1.0f,        -1.0f, 1.0f, -1.0f});        vertices.rewind();                vertexBufferID = createVBOID();        bufferData(vertexBufferID, vertices);    }        private int vertexBufferID;    private FloatBuffer vertices;        public static int createVBOID() { if (GLContext.getCapabilities().GL_ARB_vertex_buffer_object) { IntBuffer buffer = BufferUtils.createIntBuffer(1); ARBVertexBufferObject.glGenBuffersARB(buffer); return buffer.get(0); } return 0; }        public static void bufferData(int id, FloatBuffer buffer) { ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, id); ARBVertexBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, buffer, ARBVertexBufferObject.GL_STATIC_DRAW_ARB); }    /** * Render the current frame */ private void render() {        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer        GL11.glLoadIdentity(); // Reset The Current Modelview Matrix        GL11.glTranslatef(0.0f, 0.0f, z); // Move Into The Screen 5 Units        GL11.glRotatef(xrot, 1.0f, 0.0f, 0.0f); // Rotate On The X Axis        GL11.glRotatef(yrot, 0.0f, 1.0f, 0.0f); // Rotate On The Y Axis        GL11.glRotatef(zrot, 0.0f, 0.0f, 1.0f); // Rotate On The Z Axis        GL11.glColor3f(1.0f, 1.0f, 1.0f);                vertices.rewind();                GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);        ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, vertexBufferID);        GL11.glVertexPointer(3, GL11.GL_FLOAT, 0, 0);        GL11.glDrawArrays(GL11.GL_QUADS, 0, 24);        GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY); } /** * Do any animation-specific cleanup */ private void cleanup() { // Close the window Display.destroy(); }}`

#### Rainer

• 71
##### Re: Vertex Array / VBO
« Reply #8 on: December 14, 2007, 07:21:32 »
Thanks
Got it to work now, at similar speeds as the DisplayList before.
Now the next thing todo is to add the array with the normals...

#### Rainer

• 71
##### Re: Vertex Array / VBO
« Reply #9 on: December 20, 2007, 10:04:11 »