iDevGames Forums
Advantage of GL_TRIANGLE_STRIP? - Printable Version

+- iDevGames Forums (http://www.idevgames.com/forums)
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: Graphics & Audio Programming (/forum-9.html)
+--- Thread: Advantage of GL_TRIANGLE_STRIP? (/thread-7850.html)

Pages: 1 2


Advantage of GL_TRIANGLE_STRIP? - Bersaelor - Jul 13, 2010 10:17 AM

Hey,

I'm using
Code:
    glDrawElements(GL_TRIANGLES, _edgeCount, GL_UNSIGNED_SHORT, _Indices);

to draw my Scene. Right now I'm drawing around 30k triangles per frame in a midsized map.
I wondered if using "GL_TRIANGLE_STRIP" would improve performance(fps), how is your experience here?

And if so, is there some library/program that may transform saved Geometries vom GL_TRIANGLES into GL_TRIANGLE_STRIP, that you know of?
Right now I use my own program to parse obj-Files I exported from blender into c-header files I can import in my project.


RE: Advantage of GL_TRIANGLE_STRIP? - Skorche - Jul 13, 2010 10:38 AM

Triangle strips tend to be more efficient because you don't have duplicated vertexes to copy and there are probably optimizations where it only has to transform each shared vertex once.

However, each triangle strip must be drawn as a separate draw call, and you can't use a single strip to draw more than one object. I'm not sure if there are simple algorithms for taking a set of triangles and turning that into an optimized set of triangle strips either. I suspect not.


RE: Advantage of GL_TRIANGLE_STRIP? - AnotherJake - Jul 13, 2010 10:49 AM

(Jul 13, 2010 10:38 AM)Skorche Wrote:  I'm not sure if there are simple algorithms for taking a set of triangles and turning that into an optimized set of triangle strips either. I suspect not.

There was something mentioned in the PowerVR docs that triangle strip "ordering" improves cache performance and so they recommend it. I've tried it but can't claim to have seen improvement, although my testing wasn't extensive. You can find a really good triangle stripper (IMHO) in the oolong engine codebase. There are other triangle strip algorithms I've tried out but for some reason that one seems to do the best. You can easily use the output from it to generate actual triangles strips instead of just triangle strip ordering.


RE: Advantage of GL_TRIANGLE_STRIP? - Bersaelor - Jul 13, 2010 12:57 PM

(Jul 13, 2010 10:38 AM)Skorche Wrote:  [..]
However, each triangle strip must be drawn as a separate draw call, [...]

Well I could always add 3 vertices with alpha = 1 to the end of each individual geometry that I add into my one big array.

Then I would only have to change the saved default header-files of my 3D modells.

Still this might be a little work-overkill, I have many other things to do then writing a stripping algorithm.

The problem is , that with Multisampling I lost half of my fps so I thought I could regain some of them by using GL_TRIANGLE_STRIP.

On a more basic OpenGL note:
I don't refill my single big interleaved Array for each frame, I only change it once the actual geometry changed (e.g. when the player built a unit).
But I still call
Code:
    glVertexPointer(3, GL_FLOAT, sizeof(iVertex3D), &_interleavedVerts[0].v);
    glTexCoordPointer(2, GL_FLOAT, sizeof(iVertex3D), &_interleavedVerts[0].uv);
    glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(iVertex3D), &_interleavedVerts[0].color);
    glNormalPointer(GL_FLOAT, sizeof(iVertex3D), &_interleavedVerts[0].n);
    glDrawElements(GL_TRIANGLES, _edgeCount, GL_UNSIGNED_SHORT, _Indices);
each time I render.

Does this mean I'm sending the Data to the GPU for each frame?
In normal Gameplay the matrix doesn't change (only the viewing angles and scales, i.e. the viewing Matrices) so may there be some advanced OpenGL ways of telling the GPU to only change the model-projections of the already stored Vertex-Array?


RE: Advantage of GL_TRIANGLE_STRIP? - Skorche - Jul 13, 2010 01:12 PM

Yes, you are still submitting vertex data to driver memory every time you call glDraw*() if you don't have a VBO set up. Using VBOs are faster on the 3GS devices, but not on the older devices for whatever reason. (iirc)


RE: Advantage of GL_TRIANGLE_STRIP? - Bersaelor - Jul 13, 2010 01:16 PM

(Jul 13, 2010 01:12 PM)Skorche Wrote:  Yes, you are still submitting vertex data to driver memory every time you call glDraw*() if you don't have a VBO set up. Using VBOs are faster on the 3GS devices, but not on the older devices for whatever reason. (iirc)

Hmm, well I could always turn of antialiasing on older devices and use the VBO's to increase the performance I lost with antialiasing on the newer iPod 3G, 3GS and iPhone 4.


RE: Advantage of GL_TRIANGLE_STRIP? - dazza - Jul 14, 2010 01:17 PM

Drawing strips is faster in my experience if only because you store/move less data. You'll need one strip per material you want to render, you can stitch together disparate strips with degenerate triangles as long as the whole strip doesn't go over 65535 indices.

I wrote a short blog post about using NvTriStrip with blender, including a download of a version that compiles on OSX here. I've only really used NvTriStrip but I've used it for the last 10 years or so.

You sometimes get artefacts with degenerate triangles but I don't seem to see them on any iOS devices.

Hope that helps, good luck.


RE: Advantage of GL_TRIANGLE_STRIP? - Bersaelor - Jul 15, 2010 01:02 AM

(Jul 14, 2010 01:17 PM)dazza Wrote:  Hope that helps, good luck.

Thanks, I'll try it once I find the time. Sadly I have over 20 models, each consisting of several objects that would all needed to be parsed. As I see it all the degenerate vertices I need to stitch them together would increase my vertex count and therefore I'd have to modify the code that fills the interleaved array.
I appreciate you providing is with your sample code Smile


RE: Advantage of GL_TRIANGLE_STRIP? - Bersaelor - Jul 19, 2010 04:25 PM

Again, I didn't wanna open a new thread.

It's just a tried VBO's but I'm still doing something the wrong way, I just can't figure it out.
I'm calling the two functions:
Code:
void CreateVertexBuffers(GLuint vertexBuffer, GLuint indexBuffer)
{
    glGenBuffers(1, &vertexBuffer);    
    glGenBuffers(1, &indexBuffer);
    
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(_interleavedVerts), _interleavedVerts, GL_DYNAMIC_DRAW);
    
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(_interleavedEdges), _interleavedEdges, GL_DYNAMIC_DRAW);
}

void DrawVBOs(GLuint vertexBuffer, GLuint indexBuffer)
{
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glVertexPointer(3, GL_FLOAT, sizeof(iVertex3D), (void*)offsetof(iVertex3D,v));
    glTexCoordPointer(2, GL_FLOAT, sizeof(iVertex3D), (void*)offsetof(iVertex3D,uv));
    glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(iVertex3D), (void*)offsetof(iVertex3D,color));
    glNormalPointer(GL_FLOAT, sizeof(iVertex3D), (void*)offsetof(iVertex3D,n));

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glDrawElements(GL_TRIANGLES, _edgeCount, GL_UNSIGNED_SHORT, (void*)0);
}

But I always get a EXC_BAD_ACCESS in:
Code:
#0    0x0d0f132a in gleRunVertexSubmitImmediate
#1    0x0d0f0eb3 in gleLLVMArrayFunc
#2    0x0d0f0e5b in gleSetVertexArrayFunc
#3    0x0d0e7938 in gleDrawArraysOrElements_ExecCore
#4    0x0d0cbfe1 in glDrawElements_Exec
#5    0x02aa0a91 in glDrawElements



RE: Advantage of GL_TRIANGLE_STRIP? - dazza - Jul 20, 2010 01:07 AM

Code:
void CreateVertexBuffers(GLuint vertexBuffer, GLuint indexBuffer)

Here you are passing in two GLuint by value and then calling

Code:
glGenBuffers(1, &vertexBuffer);    
glGenBuffers(1, &indexBuffer);

setting your function parameters values to the buffer id's. These values are thrown away when the CreateVertBuffers function returns (but the GL buffers are leaked).

I think you need something like
Code:
void CreateVertexBuffers(GLuint *vertexBuffer, GLuint *indexBuffer){
   glGenBuffers(1, vertexBuffer);    
   glGenBuffers(1, indexBuffer);
...
}

calling it thus:

Code:
GLuint vBuffer, iBuffer;
CreateVertexBuffers(&vBuffer, &iBuffer);

does that make sense?


RE: Advantage of GL_TRIANGLE_STRIP? - Bersaelor - Jul 20, 2010 02:06 AM

@Dazza
Of course you are right!
(Its mainly because I learned programming in Fortran and sometimes I still forget its call by value now)

Still it doesn't seem to add normals and colors, do I have to Enable Normal_Array and Color-Array everytime I bind the vbo's?


RE: Advantage of GL_TRIANGLE_STRIP? - Skorche - Jul 20, 2010 07:11 AM

Binding the VBO just changes what chunk of memory your pointers are referencing relative to. With the '0' VBO being main memory and not driver managed VBO memory. It does not change which pointers are bound or what value they are bound to.


RE: Advantage of GL_TRIANGLE_STRIP? - Bersaelor - Jul 20, 2010 07:58 AM

(Jul 20, 2010 07:11 AM)Skorche Wrote:  Binding the VBO just changes what chunk of memory your pointers are referencing relative to. With the '0' VBO being main memory and not driver managed VBO memory. It does not change which pointers are bound or what value they are bound to.
Maybe its too warm here (32° currently) but I'm sorry I don't get you....

You mean if I only move pointers to the data around, the state of glEnable(GL_NORMAL_ARRAY) should not change?
The problem was that I can draw with VBO's now, but there are neither textures on my geometry nor is there any light except ambient (because of no normals).


RE: Advantage of GL_TRIANGLE_STRIP? - Skorche - Jul 20, 2010 08:33 AM

I mean that VBOs do not remember which pointers you enabled or where they are pointing to. So when you switch VBOs you have to do all your enables and pointer rebinding again unless they are the same between different VBOs.


RE: Advantage of GL_TRIANGLE_STRIP? - Bersaelor - Jul 20, 2010 08:55 AM

(Jul 20, 2010 08:33 AM)Skorche Wrote:  I mean that VBOs do not remember which pointers you enabled or where they are pointing to. So when you switch VBOs you have to do all your enables and pointer rebinding again unless they are the same between different VBOs.

Well to save redundant state calls, I only enable Colors, Vector_Array, Texture_Coord and Normal_Array in my init and disable them when the user leaves the view.
That's why I didn't see any problems here, still the VBO's don't seem to show Textures or normals. Whats more interesting is that they do show the color correctly, so colors are switched on.

I mean I basically left the whole program the way it was, in the place that I formerly called " flush()" I just now call "drawVBO's".