![]() |
|
This thread is locked; no one can reply to it.
![]() ![]() |
1
2
|
TRIANGLE_STRIP : how to render it with proper CCW order [ OpenGL ] |
kronoman
Member #2,911
November 2002
![]() |
Well, I want to use triangle strips, but I can't get to figure the order of vertex right. B--D--F--H--J--L |\ |\ |\ |\ |\ | | \| \| \| \| \| A--C--E--G--I--K Now, which order should I feed the vertex (ABCD...) to OpenGL to render it properly in CCW fashion? (so my lights gets right) If you wish, please re order the vertex naming in another ASCII art Thanks a lot. |
Jakub Wasilewski
Member #3,653
June 2003
![]() |
I believe it would be LJKIHGFEDCBA, but I didn't have the time to check it thoroughly. However, you could consider using quad strip if the actual shape resembles that on your ASCII art. I think it's easier, and that would have the simple order LKJIHGFEDCBA (just pairs of points, always starting with the lower, or with the upper for CW). --------------------------- |
Bob
Free Market Evangelist
September 2000
![]() |
ACBDEFGH... See the OpenGL specification 2.0, section 2.6.1. -- |
kronoman
Member #2,911
November 2002
![]() |
OK, I understand, thanks. Now, to make my loop simple, would work if I do some like: or BADCFEHG... ? (maybe?) Maybe quad strips would be better, right? Thanks again. p.s Bob,great documentation! very interesting. |
Krzysztof Kluczek
Member #4,191
January 2004
![]() |
Quote:
Now, to make my loop simple, would work if I do some like: or BADCFEHG... ? (maybe?) It always worked for me this way (one gives you CW, the other CCW). ________ |
kronoman
Member #2,911
November 2002
![]() |
Would it work too if I decide to use QUAD_STRIPS instead? B--D--F--H--J--L..... | | | | | | : | | | | | | : A--C--E--G--I--K.....
CW : ABCDEFGHIJKL... ? Damn, I still can't get the CW & CCW idea... |
HoHo
Member #4,534
April 2004
![]() |
Quote:
Maybe quad strips would be better, right? It would be better if all four points of all the quads lay on the same same plane. On a heightmap terrain this is rarely the case. __________ |
relpatseht
Member #5,034
September 2004
![]() |
i would recomend triangle strips, nd as Bob said, simply go ACBDEFGH... with your example anyway. CW and CCW is just the order in which you call the vertices, think about it. With CCW, you move right, with CW you move left. A->right->C->up->B->right->D->down right->E->up->F->down right->G->up->H ... just think about the order in which you call the vertices, and ask yourself "if these vertices were on a clock, would they be going against the movement of the hand, or with them?"
|
Krzysztof Kluczek
Member #4,191
January 2004
![]() |
Quote:
CW : ABCDEFGHIJKL... ?
Just write some code and test it. I usually pick one culling method (usually CW) and flip everything that is rendered incorrectly. ________ |
relpatseht
Member #5,034
September 2004
![]() |
i find its easier (for testing) to set polygon mode on one side to lines, and leave the other side on fill, that way if you do set up the vertices wrong, you can still see that they do exist (and aren't way off screen, as is sometimes the case)
|
kronoman
Member #2,911
November 2002
![]() |
Thanks for all the advice. Now, here is my drawing about how I will organize this, theoretically. http://xs50.xs.to/pics/05414/dsc04334.jpg At left, is the original mesh, then, I divide it on nXn zones, and each zone (middle) has nXn triangles on them, so I divide each zone on triangle strips (right). I don't know if this sounds right or not, and I'm very confused about how I'm going to implement this Well, thanks for all the advice, and any more advice is very appreciated. p.s if helps, I'm using C++ to do this, so no malloc/free, but new and delete. |
Krzysztof Kluczek
Member #4,191
January 2004
![]() |
Quote: At left, is the original mesh, then, I divide it on nXn zones, and each zone (middle) has nXn triangles on them, so I divide each zone on triangle strips (right).
Just use GL_TRIANGLES and store every zone as one index buffer and a set of vertex buffers. It's usually better to render one bigger chunks of geometry with GL_TRIANGLES than more smaller with GL_TRIANGLE_STRIPs, especially when you are using index buffers and vertex buffer objects. ________ |
HoHo
Member #4,534
April 2004
![]() |
Triangle strips can be useful because with them there should be better use of vertex cache. I used NvTriStrip Library to build triangle strips out of my models. Btw, when you divide your heightmap to pieces see that it is not in too little pieces. I think the best size is somewhere around 512-2048 triangles per chunk. __________ |
Krzysztof Kluczek
Member #4,191
January 2004
![]() |
Quote: Triangle strips can be useful because with them there should be better use of vertex cache. You can achieve the same cache usage with GL_TRIANGLES and index buffers. Quote: I used NvTriStrip Library to build triangle strips out of my models. I'm going to use it, too (or write something like it myself), but to generate one optimized list of triangles (NvTriStrip can do it, too). Quote: Btw, when you divide your heightmap to pieces see that it is not in too little pieces. I think the best size is somewhere around 512-2048 triangles per chunk.
Being forced to render in strips 256 tile long doesn't seem to be optimal, as most of them will be mostly outside view frustum or quite far from the camera. Also I can't see any good way of suing levels of detail when rendering in strips. ________ |
relpatseht
Member #5,034
September 2004
![]() |
Well, let me first start off by telling you that your idea is flawed. You have to draw all squares that the player can see, not only the one that the player is in. Furthermore, what you are doing is basically quadtree based culling, here is a good tutorial on it: Gamedev.net Quadtree Tutorial After you have what you are trying to do down, I also suggest you look into GeoMipmapping, but I'll save the information on that to when you get there.
|
kronoman
Member #2,911
November 2002
![]() |
I really wish to thank all this help, I think that I will get the terrain done in the next weeks. What do you think about this ? Sounds good ? Thanks again!! p.s I got (somewhat) working the triangle strips \\o o// screenshoot (click!): |
HoHo
Member #4,534
April 2004
![]() |
Quote: I'm going to use it, too (or write something like it myself), but to generate one optimized list of triangles (NvTriStrip can do it, too). Sure you can but if there is a tool that can generate the same thing I see little point in coding your own wheel Quote: Being forced to render in strips 256 tile long doesn't seem to be optimal, as most of them will be mostly outside view frustum or quite far from the camera. I can't give any heightmap rendering specific test results but general batch size and speed relation can be found here: __________ |
Krzysztof Kluczek
Member #4,191
January 2004
![]() |
Quote:
I can't give any heightmap rendering specific test results but general batch size and speed relation can be found here: I'm not talking about batch sizes, but about limitations of triangle strips. When you are using VBO with index buffers, I don't think it doesn't really matter whether you are rendering triangle strip or triangle list, as long as VBO's orderings are cache-friendly. When using triangle lists, all you "waste" is 4-8 bytes per triangle in index buffer, but flexibility gained this way is incomparable to this (for example, you can render 2048 triangles in one batch, which otherwise would require a lot of tiny strips). In case of terrain engines using triangle lists you can store entire zone as one batch, which is useful in visibility checking and implementing level of detail. Of course everything I wrote assumes you are using ARB_vertex_object_buffer, which is first thing to do when you want good framerates. ________ |
relpatseht
Member #5,034
September 2004
![]() |
just because your using triangle strips doesnt mean you need a separate renering call for each strip of triangles, you just need to use degenerate triangles. A good post describing this method can be found here.
|
Krzysztof Kluczek
Member #4,191
January 2004
![]() |
Quote:
just because your using triangle strips doesnt mean you need a separate renering call for each strip of triangles, you just need to use degenerate triangles. A good post describing this method can be found here.
This can be good optimization to non-VBO rendering, but I'm sure triangle strips aren't better than triangle lists when using VBOs with index buffers and GPU-friendly vertex/index ordering. ________ |
HoHo
Member #4,534
April 2004
![]() |
Afaik, the nv tristrip library could stitch together whatever model you gave it to a single triangle strip __________ |
Krzysztof Kluczek
Member #4,191
January 2004
![]() |
Quote: Afaik, the nv tristrip library could stitch together whatever model you gave it to a single triangle strip
AFAIK not. It generates a set of strips and a list of remaining triangles, that it haven't managed to put into any reasonably long strip. Instead, you can tell NvTriStrip to generate no strips and just generate one list of triangles with optimized ordering. ________ |
gillius
Member #119
April 2000
|
I've been watching this thread and have been interested. This, of course, has been done many times before but is an example of one of those things that is very useful that someone goes through "new" on the first time, learning this stuff. Landscape engines are the "pong" of 3D, imo Anyway, generating triangle strips and segments to use for complete hardware implementation is pretty easy and probably using a tool like NvTriStrip is not needed. Definitely one should implement the rendering using VBO or even better vertex + index buffers since in each patch the verts are shared at least twice if not up to 4 times. I don't know how it would go in OGL but I used D3D, which although initially harder than OGL basically forces you to do things at least a "very good way" if not the "best way" by not allowing immediate mode rendering. I've one other very important point to mention. The intersection of the frustum and the land is actually a trapezoid and not a triangle, and even that is only when the ground is flat. An ultimate solution probably involves a bounding box and frustum check if you allow great distances in height, or a quadtree/octmap if the land allows for concavity. However, if your view is always on the ground and ground is "flat enough", using a triangle is an excellent optimizing approximation. Interestingly enough in my university I learned a very fast algor for rendering a triangle without clipping on the screen given three points. The frustum problem is the exact same thing if you treat the landscape (in the form of a quadmap) as a "pixellated screen". Literally all I did was replace the "putpixel(x,y)" in the algor with "drawTerrainBlock(x,y)" and you have an extremely fast clipping algor Gillius |
Bob
Free Market Evangelist
September 2000
![]() |
Quote: It's usually better to render one bigger chunks of geometry with GL_TRIANGLES than more smaller with GL_TRIANGLE_STRIPs, especially when you are using index buffers and vertex buffer objects. Triangle strips (when used in combination with VBOs) are alway superior to regular triangles. At worst, a triangle strip degenerates into a triangle. At best, you get to reuse transformed vertices. -- |
Krzysztof Kluczek
Member #4,191
January 2004
![]() |
Quote: Triangle strips (when used in combination with VBOs) are alway superior to regular triangles. At worst, a triangle strip degenerates into a triangle. At best, you get to reuse transformed vertices. My point is, that when triangle list is properly ordered (eg. you generate strips and fans and merge them all into one triangle list) it shouldn't make much difference whether you are using GL_TRIANGLES or GL_TRIANGLE_STRIP, since post-transform vertex cache will work the same way in both cases. Using GL_TRIANGLES this way seems to be always better than GL_TRIANGLE_STRIP, because you can render geometry in strips using triangle list, while rendering complex object using GL_TRIANGLE_STRIPS usually requires using degenerated triangles or rendering geometry in many parts. To put it simply, if you are using: [ mode ] [ index buffer contents ] GL_TRIANGLE_STRIP 1 2 3 4 5 6 GL_TRAINGLES 1 2 3 3 2 4 3 4 5 5 4 6
you should get the same performance because of transformed vertex cache. Is there any error in my logic? ________ |
|
1
2
|