views:

384

answers:

2

Hi, I'm trying to draw many lines on the screen at the same time using OpenGL line strips and performance is slow, and it was suggested I use a vertex buffer. I'm new to vertex buffers - do I need a new one for each line I want to draw, or do I use a single buffer for all of the lines (they are not necessarily connected to each other)? At this point I have a list of lines (where each line is a list of vertices), but I'm not sure how to render these quickly. Any help would be appreciated.

EDIT: Here is my current code that gives an exception of: EDIT2: Rewinding the buffer before calling glVertexPointer fixed the exception since the put was advancing the buffer. This is now fixed.

java.lang.IndexOutOfBoundsException: Required 1 remaining elements in buffer, only had0
at com.sun.gluegen.runtime.BufferFactory.rangeCheck(BufferFactory.java:247)
at com.sun.opengl.impl.GLImpl.glVertexPointer(GLImpl.java:27937)

    for (int i = 0; i < lines.size(); i++)
    {
        List<Vertex> v = lines.get(i);
        DoubleBuffer buf = BufferUtil.newDoubleBuffer(v.size() * 3);

        Iterator<Vertex> iter = v.iterator();
        while (iter.hasNext())
        {
            Vertex vt = iter.next();
            buf.put(new double[] { vt.x, vt.y, vt.z });
        }
        gl.glVertexPointer(3, GL.GL_DOUBLE, 0, buf);
        gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
        gl.glDrawArrays(GL.GL_LINES, 0, v.size());
        gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
    }

Hopefully this will provide some better insight into my problem (I know this code has issues, trying to learn here though).

Thanks, Jeff

A: 

I am also an opengl beginner, and not familiar with the java bindings, but I'll try to point you in the right direction until a better answer comes along.

As far as I know, there is only one vertex buffer. You can render directly to the vertex buffer with client side data. If you want to do that, look into calls like glEnableClientState(GL_VERTEX_ARRAY), glBindBuffer, glVertexPointer, glDrawElements. You will also need to write to the index array.

According to the opengl site, these calls are now deprecated in favor of Vertex Buffer Objects. I don't know much about them, but based on your question this is what people were suggesting for you. They are pretty well explained with sample code here:

http://www.opengl.org/wiki/Vertex_Buffer_Objects

As for your performance issues, it seems strange that you would be getting problems just from line strips. I would also check to see if you have the right opengl drivers for your video card, or maybe try a native language like c++ instead of java.

FranticPedantic
no, there is not "only one" vertex buffer. You can have as many as you want. You don't "render" to VBOs, you fill them in with glBufferData and/or glBufferSubData. you _refer_ to the data by offseting in a vbo with glBindBuffer+glVertexPointer, and actually use the data on the consecutive Draw. VBOs _are_ vertex buffers.
Bahbar
A: 

vertex buffers are just memory allocated and managed by the GL. As such, they don't relate directly to Draws.

Now, yes, storing the vertex data directly inside GL can improve performance if that data does not change much (it avoids having to transfer the data every frame).

Your question is not very quantitative though. What exactly do you meant by "it's slow" ? How many lines do you want to draw ? how many draw calls do you currently perform ? What kind of performance do you get ? What kinds of lines do you draw ?

It's hard to draw many lines strips fast, because they each require a separate draw call. It is possible with GL_LINES, though, to batch multiple lines in the same draw. And that should perform significantly better.

Edit to add:

Ok, I looked at your code... I'm not that familiar with GL in java, but that code looks suspicious in that it does not pass buf to VertexPointer. It passes v ? Also your put looks suspicious. Aren't you supposed to push doubles rather than a double array ?

Bahbar
Sorry for the vagueness. I am trying to use GL_LINES as shown in my edit above, but I can't seem to get it to work.
Jeff Storey
Yes, you are correct. that was a type-o. The code works now. I'm using it with NASA WorldWind, but the rendering is still very slow. I'm not sure if this is WorldWind or OpenGL related...
Jeff Storey