PDA

View Full Version : GL_TRIANGLE_STRIP and VBO fail.



Darkpower
05-24-2012, 09:23 PM
Hey!

I have a big problem that I can't solve right now... I have searched all over the internet for hours... :-/

Look at this picture:

http://oi50.tinypic.com/v67rl4.jpg

If I draw the terrain with Immediate mode:



for (int z = 0; z < DEPTH; z++)
{
glBegin(GL_TRIANGLE_STRIP);
for (int x = 0; x < WIDTH; x++)
{
//Draw everything here...
}
glEnd();
}

Everything works just fine, no lines.

But if i use just one interleaved VBO for colors, vertices and textures. Everything fail and end up with lines.

I draw the terrain with glDrawArrays(GL_TRIANGLE_STRIP, 0, numberVertices).

I know that glDrawArrays just draw all data.
glDrawArrays + GL_TRIANGLE_STRIP = lines.
glDrawArrays + GL_TRIANGLES = no lines. Terrain looks bad.

I have the exact same problem as this guy: http://stackoverflow.com/questions/9115056/opengl-vertex-arrays-and-gl-triangle-strip-drawing-error

thokra
05-25-2012, 01:09 AM
Please post a stripped down example showing buffer setup and rendering code.

mhagain
05-25-2012, 02:20 AM
Is numberVertices == DEPTH * WIDTH? In other words, are you trying to draw multiple strips in a single call? If so, a single glDrawArrays with GL_TRIANGLE_STRIP won't work; your options are to either use primitive restart or GL_TRIANGLES (both of which will need indexes) or join your strips with degenerate triangles.

Personally I'd use GL_TRIANGLES with indexes (via glDrawElements) for this; strips are just so 1998.

thokra
05-25-2012, 02:22 AM
strips are just so 1998

this one made me smile. :)

BionicBytes
05-25-2012, 05:34 AM
strips are just so 1998.
What's wrong with strips?
I've been using strips for years and IMHO they're more efficient than triangles as you only need to send 2 verticies/indicies per triangle comapred to 3.

thokra
05-25-2012, 05:41 AM
What's wrong with strips?

What bothers me most about strips is that if you don't have a DDC Tool and exchange format which stores stripified geometry, you'll have to do the conversion from raw triangles or indexed geometry yourself and for most models it's not as simple as using the indexed geometry or removing doubles from a list of triangles and indexing yourself or as simple using strips for a regular grid or something. Do you proceed differently somehow?

mhagain
05-25-2012, 06:58 AM
What's wrong with strips? Generally if someone like Tom Forsyth says something I tend to assume that the likelihood he knows what he's talking about is reasonably high, so here's what he has to say (link: http://tomsdxfaq.blogspot.com/)

Let me say this just once, because academics are still spending time and money researching this subject. You're wasting your time. Strips are obsolete - they are optimising for hardware that no longer exists. Indexed vertex caches are much better at this than non-indexed strips, and the hardware is totally ubiquitous. Please go and spend your time and money researching something more interesting.

http://home.comcast.net/~tom_forsyth/blog.wiki.html#Strippers


The ultimate stripper will get you one vertex per triangle. But even a very quick and dirty indexer will get you that, and a good indexer will get close to 0.65 vertices per triangle for most meshes with a 16-entry FIFO vertex cache.

BionicBytes
05-25-2012, 08:03 AM
I think that the original post was with regard to a terrain - and that's where I'm coming from too. My terrains are a rendered by repeating a regular patch with a 'stitched' border between patches to avoid cracks. All of these are rendered using triangle strips and degenerate triangles.
Since the actual rendering is done with indicides and draw elements, I wonder just how it could be more efficient with GL_TRIANGLES and indicies when, by definition, you are sending more indicies in the case of GL_TRIANGLES than for GL_TRIANGLE_STRIPS.
For general purpose models, then yes, indexed triangles would be the way to go. For a regular grid - I don't think you can beat a Tri_strip as that's the best case scenareo.

Darkpower
05-26-2012, 06:50 AM
Ok, so I should try degenerate triangles? Does anyone know any good tutorials?

mhagain
05-26-2012, 07:13 AM
I'd personally use primitive restart rather than degenerates as it's just a single extra index. With degenerates you need to add extra vertexes, which can be done either via indexes (which is quite small overhead) or full fat vertexes (which can be a large overhead).

As always with GPUs, what seems more intuitively faster in theory does not always turn out so in practice - witness the performance difference between GL_RGB and GL_BGRA texture formats, for example, despite the latter seeming to require more memory. So for a regular grid, using indexed triangles does have more indexes, yes, but it also allows you to remove more shared vertexes - the infinite regular grid case is the one that gets you 0.5 verts/tri which is the optimal case with indexes. Here's Tom F again:

The theoretical limit for a regular triangulated plane with an infinitely large vertex cache is 0.5 verts/tri (think of a regular 2D grid - there's twice as many triangles as vertices)

So it's quite clearly a balancing act - you accept more indexes in exchange for a greater reduction in vertexes, and come out of it on the right side of less data overall.

menzel
05-26-2012, 08:45 AM
What's wrong with strips? Generally if someone like Tom Forsyth says something I tend to assume that the likelihood he knows what he's talking about is reasonably high, so here's what he has to say (link: http://tomsdxfaq.blogspot.com/)

http://home.comcast.net/~tom_forsyth/blog.wiki.html#Strippers (http://home.comcast.net/%7Etom_forsyth/blog.wiki.html#Strippers)

You have to note however, that Tom Forsyth compared index triangles against non-indexed stips in your quote. 7 years into the future we can use index stips with primitive restart instead of degenerated triangles. He also writes about that:

"Some APIs (not PC DX5-DX9, but some consoles, and possibly future PC APIs) also allow a "restart" index, which means you don't need to use degenerate triangles, and they can make strips better than lists" (http://tomsdxfaq.blogspot.de/).

As each strip needs 2+N indices for N triangles, in a list with primitive restart we need (3*M)+N-1 for N triangles in M strips (the last strip does not need a restart index). A plain list needs 3*N indices.

So when will we save space in the index?
3M +N-1 < 3N
3M +N < 3N
3M < 2N
M < 0.66N
When we have less that 0.66 stips than triangles. As the average stripsize is N/M that means that an average strip must contain 1.5 triangles. Let's check that: A strip of 2 triangles needs 4 indices + 1 restart index == 5 indices while 2 triangles seperated need already 6 indices.

To take advantage of your post transformation cache, your stripsize has to be short, but as we have seen, shortness is not a problem, we will still save memory.

So in theory short strips that make use of the post transformation cache with primitive restart should be the optimal solution (in practice you DCC tools might not be optimized for this setup or the restart itself is a hidden bottleneck, but i'd like to see benchmarks on newer hardware to beleave that).


BTW: Does anyone have numbers of the post transformation cache sizes of current GPUs?

Dark Photon
05-26-2012, 07:06 PM
To take advantage of your post transformation cache, your stripsize has to be short...
This does not follow.


BTW: Does anyone have numbers of the post transformation cache sizes of current GPUs?
I haven't seen anything on that in ages. Back in ancient days of fixed-function GPUs, sizes were up to 45 in the GeForce 7 days. And way back in GeForce 8 days (unified shader core generation), saw some info in the NVidia GPU Programmer's guide for that generation that indicates the size of the vertex cache was dynamic and subject to the amount of varyings output by the vertex shader (more varyings, shorter vertex cache, and vice versa). I'm guessing they were/are using the shared memory on the SMs as a vertex cache, but that's a total guess.

So in practice, I expect your minimum vertex cache length is more than you need. And if you read studies by Forsyth and others, you see that in practice 45 is way more than you need for near-optimal performance with a half-decent vertex cache optimizing triangle sorting.

Darkpower
05-27-2012, 03:08 AM
I need a little bit help.
I have to use glDrawElements(GL_TRIANGLE_STRIP, indices), glEnable(GL_PRIMITIVE_RESTART) and glPrimitiveRestartIndex(restartIndex).

But how can I get all the indices? Look at the example code below. I think I'm going to have to create a new buffer that holds all the indices.

Inner loop=Filling the buffer with indices. But, what kind of values?
Outer loop=add "restartIndex".



float[][][] heightMap = new float[WIDTH][DEPTH][q];
int restartIndex = 0xfffff;

//First: Loop and fill array with data and other stuff.


FloatBuffer buffer = BufferUtils.createFloatBuffer(heightMapSize);
IntBuffer indices = BufferUtils.createIntBuffer(how big??????);

//indices.put(), what kind of values? (inner loop)

for (int z = 0; z < DEPTH-1; z++)
{
for (int x = 0; x < WIDTH-1; x++)
{
buffer.put(heightMap[x][z][q]).put(data).put(data); //Vertex
buffer.put(0.0f).put(0.0f); //Texture

buffer.put(data).put(data).put(data);
buffer.put(data).put(data);

buffer.put(data).put(data).put(data);
buffer.put(data).put(data);

buffer.put(data).put(data).put(data);
buffer.put(data).put(data);
}
indices.put(restartIndex);
}

tonyo_au
05-27-2012, 05:31 AM
The indices are the relative offset into the vertex buffer.

restartIndex must not be a valid vertex buffer index.

If you have 2 strips with say 6 unique vertices each, the vertex buffer will have 12 vertices and the index buffer will be
0,1,2,3,4,5,restartIndex,6,7,8,9,10,11,restartInde x

Darkpower
05-27-2012, 06:07 AM
Ok, tried it. The result: http://oi47.tinypic.com/5k5280.jpg

Something is terribly Wrong Here. Lines + holes, yes....

Before: glDrawArrays(GL_TRIANGLE_STRIP, 0, numberVertices) = lines.
Before: glDrawArrays(GL_TRIANGLES, 0, numberVertices) = no lines.

Now: glDrawElements(GL_TRIANGLE_STRIP, indices) = lines.
Now: glDrawElements(GL_TRIANGLES, indices) = lines.


Have to check my code again.

Darkpower
05-27-2012, 06:52 AM
Look at this picture: http://oi50.tinypic.com/2me4a3k.jpg

GL_TRIANGLES, so you can see the lines more clearly.

All lines goes from one side to the other. Why?

Darkpower
05-29-2012, 06:09 AM
Nobody knows?

Mars_999
05-29-2012, 06:32 AM
I haven't read any of these two pages but I will state this are you using degenerate triangles? If so you will probably need to and mess with the winding order on the row ends to keep going to the next row and run back again.

Darkpower
05-29-2012, 06:33 AM
No, i'm using primitive restart.

Darkpower
05-29-2012, 09:20 AM
WOHO, solved everything now!=D=D=D

Mars_999
05-29-2012, 12:14 PM
and the problem was....