TRIANGLE LIST oder STRIP?
-
Hey!
Ich möchte gerne einen Heightmap-Terraingenerator bauen. Ganz simpel. Graustufe = Höhe. Nur bekomme ich es im Moment nicht mal hin, einen TRIANGLESTRIP zu zeichnen. Zumindest bekomme ich nur ein Dreieck anstatt 3.
Und, wie ist nun genau die Reihenfolge bei einer LIST und bei einem STRIP? Irgendwie steht es überall anders!
Soll ich LIST oder STRIP für ein Terrain verwenden?
MfG
... struct TVertex { D3DXVECTOR3 position; DWORD color; }; #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE) LPDIRECT3DVERTEXBUFFER9 D3D_VertexBuffer; LPDIRECT3DINDEXBUFFER9 m_pIB; TVertex v[5]; v[0].position = D3DXVECTOR3(-0.5f, -0.5f, 0.0f); v[0].color = D3DCOLOR_XRGB(255,0,0); v[1].position = D3DXVECTOR3(-0.5f, 0.5f, 0.0f); v[1].color = D3DCOLOR_XRGB(0,255,0); v[2].position = D3DXVECTOR3(0.5f, -0.5f, 0.0f); v[2].color = D3DCOLOR_XRGB(0,0,255); v[3].position = D3DXVECTOR3(0.5f, 0.5f, 0.0f); v[3].color = D3DCOLOR_XRGB(0,0,255); v[4].position = D3DXVECTOR3(1.0f, -0.5f, 0.0f); v[4].color = D3DCOLOR_XRGB(0,0,255); WORD i[9] = {0, 1, 2, 2, 1, 3, 3, 4, 2}; Direct3D9::getInstance().getDevice()->CreateVertexBuffer(5 * sizeof(TVertex), D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &D3D_VertexBuffer, NULL); VOID* pVertex; D3D_VertexBuffer->Lock(0, sizeof(v), (VOID**)&pVertex, 0); memcpy(pVertex, v, sizeof(v)); D3D_VertexBuffer->Unlock(); Direct3D9::getInstance().getDevice()->CreateIndexBuffer(sizeof(i), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pIB, NULL); WORD* pIndices; m_pIB->Lock(0, sizeof(i), (void**)&pIndices, 0); memcpy(pIndices, i, sizeof(i)); m_pIB->Unlock(); while(msg.message != WM_QUIT) { if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } Direct3D9::getInstance().getDevice()->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,255,0), 1.0f, 0); Direct3D9::getInstance().getDevice()->BeginScene(); Direct3D9::getInstance().getDevice()->SetFVF(D3DFVF_CUSTOMVERTEX); Direct3D9::getInstance().getDevice()->SetIndices(m_pIB); Direct3D9::getInstance().getDevice()->SetStreamSource(0, D3D_VertexBuffer, 0, sizeof(TVertex)); Direct3D9::getInstance().getDevice()->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, 0, 5, 0, 3); Direct3D9::getInstance().getDevice()->EndScene(); Direct3D9::getInstance().getDevice()->Present( NULL, NULL, NULL, NULL ); } ...
-
Du sollst immer, wo möglich, strips verwenden:
1--3--5--7 |\ |\ |\ | | \| \| \| 2--4--6--8
jetzt einfach
2 1 4 3 6 5 8 7 hochschieben.
-
?--?--?--? |\ |\ |\ | | \| \| \| ?--?--?--? |\ |\ |\ | | \| \| \| ?--?--?--?
Und wie sehen die Indizes dann am besten aus?
Was meinst du mit hochschieben?MfG
-
Hat sich erledigt. Geht auch ohne Indizes. Was ist eigentlich der Vorteil?
Ich nehme einfach degenerierte Dreiecke...MfG
-
Geht auch ohne Indizes.
Was ist eigentlich der Vorteil?die gpu haelt bereits transformierte vertices in einem cache und kann diese bei mehrfach vorkommende indices einfach wiederverwenden.
vertices die bereits im cache liegen gehen so quasi kostenlos durch die t&l-einheit.
nur aufgrund des indexing selbst koennen diese daten ueberhaupt zugeordnet werden.
durch dieses konzept faellt der vorteil von strips gegenueber (entsprechend sortierten) indexed-triangle-lists auch nur noch minimal aus.
im falle von triangle-strips sollten diese so arrangiert werden, dass wiederverwendbarkeit erhalten bleibt.
-
Hallo, ich sitze zur Zeit am selben Problem.
(Ich weiß auch nicht in welcher Reihenfolge ich die Koordinaten der Dreiecke übergeben muß)Irgendwie verstehe ich aber die aufgezeigte Lösung nicht.
Kann mir das Jemand erklähren?
-
in welcher Reihenfolge ich die Koordinaten der Dreiecke übergeben muß
0--2--4--6 | /| /| /| |/ |/ |/ | 1--3--5--7 | /| /| /| |/ |/ |/ | 8--9--A--B
(hier counter-clockwise)
indices fuer 2 triangle-strip:
1: 0 1 2 3 4 5 6 7
2: 1 8 3 9 5 A 7 Bdiese lassen sich (unter beachtung der polygon-orientierung) durch einfuegen doppelter indices verbinden.
die daraus entstehenden null-polygone werden im rasterizer verworfen.
genaueres findet man in der direct3d-dokumentation.
-
Tri-Strips sind IMHO was für old-school Anhänger. Mittlerweile verwendet man normalerweise Vertex-Buffer und Index-Buffer, damit sind Tri-Strips ziemlich umsonst, man kann einfach Tri-Lists nehmen. Klar sind es auch 2 Index-Werte mehr pro Dreieck, bloss ein Index ist 4 Byte, also nix verglichen mit einem "normalen" Vertex (Position, Texturkoordinaten, Normale), und nebenbei steht der sowieso auch im lokalen Grafikkartenspeicher (bzw. sollte er immer) -- von daher egal.
Verwendung von Tri-Strips ist eines dieser Dinge die einem vielleicht 5% (wenn überhaupt) Performance bringen wenn man sie macht, dafür aber tierisch nerven können wenn man anfängt an seiner Geometrie was zu ändern.
In Zeiten wo es noch keine Index-Buffer gab freilich sah die Sache anders aus, da hat's definitiv einiges gebracht, da die Vertices sonst mehrfach im Speicher liegen mussten und auch mehrfach durch den Shader laufen.
Viel viel wichtiger (wenn auch ein anderes Thema) ist es mittlerweile einigermassen nach gleichen Renderstates (Texturen, Shader etc.) zu gruppieren um ordentliches "batching" zu erreichen.
-
[EDIT] sorry, bitte löschen
-
Tri-Strips sind IMHO was für old-school Anhänger.
Mittlerweile verwendet man normalerweise Vertex-Buffer und Index-Buffer,
damit sind Tri-Strips ziemlich umsonst, man kann einfach Tri-Lists nehmen.das konzept des indexings erlaubt allerdings, ziemlich wahllos im grafikspeicher rumzuspringen - was der performance erheblichen schaden zufuegen kann.
man muss sich also auch ueber eine sinnvolle sortierung des indexbuffers gedanken machen.
-
hustbaer schrieb:
Klar sind es auch 2 Index-Werte mehr pro Dreieck, bloss ein Index ist 4 Byte
Ich glaub spaetestens danach hab ich aufgehoert den restlichen Unsinn zu lesen... f'`8k
Bye, TGGC (Das Eine, welches ist.)
-
Trianglestrip ist das schnellste was gibt. Sofern Man seine Daten so organisieren kann.
-
Ja klar wenn ihr meint.
@TGGC: was bitte ist daran Unsinn -- ich meine wenn dus nichtmal gelesen hast? Ok, toll, man kann 2 Byte pro Index verwenden, war mein Fehler, also 2 oder 4 Byte. Der Rest ist trotzdem kein Unsinn, Tri-Strips bringen bei Verwendung von Index-Buffern kaum einen Vorteil.
-
Jetzt kann man ja aber sowohl eine Triangle List als auch ein Triangle Strip indizieren...
-
Hallo ihr Papnasen,
Trianglestrip mit glDrawArrays , nix Indexbuffer und indizieren .
Schon mal ausprobiert??
-
Hey!
So habe ich es jetzt gemacht: (Ohne Index-Buffer)
http://krautland.net/primitives.jpg = http://krautland.net/primitives2.JPG
Geht es vielleicht noch einfacher? Denn ohne diesen degenerierten(?) Dreiecken erscheint nochmals eine Diagonale durch jede Reihe.
Und warum muss ich 30 Primitives angeben? Ich zähle nur 28...
MfG
-
So habe ich es jetzt gemacht
Geht es vielleicht noch einfacher?um zwei einzelne strips zu mergen braucht man lediglich zwei polygone (im strip also jeweils ein zusaetzlicher eckpunkt) mit jeweils zwei gleichen eckpunkten - ein solches polygon hat folglich einen flaecheninhalt von 0 und wird im rasterizer verworfen.
auf diese weise gelangt man quasi "unsichtbar" vom ende von strip1 zum anfang von strip2.
je nach anzahl deiner polygone im strip (gerade/ungerade) aendert sich dadurch die orientierung (gegen-/uhrzeigersinn) des folgenden (kompletten) polygons.
du benoetigst also anstatt 4 lediglich zwei oder drei zusaetzliche eckpunkte.Jetzt kann man aber sowohl eine Triangle List als auch ein Triangle Strip indizieren...
strips sparen index-daten waehrend triangle-lists flexiblere index-strukturen ermoeglichen.
es lassen sich jeweils beispiele finden fuer die das eine bessere loesungen ergibt als das andere.
-
@ABC++: Es heisst Pappnasen, und hier war nie von OGL die Rede. Und wieso sollte man in OGL was anderes als Index-Buffer verwenden? Vergiss glDrawArrays und vergiss Display Lists. Mach dir nen Vertex Buffer, schreib deine Vertices rein, mach nen Index Buffer, schreib deine Index Daten rein, und render es einfach (z.B. mit glDrawRangeElementsEXT). Ohne Display List, ohne sonstwas. Gleich wie man es in D3D machen würde. Die notwendige Extension heisst ARB_vertex_buffer_object, und ist in so gut wie jedem halbwegs aktuellen Treiber implementiert.
@xindon: Klar kann man Tri-Strips und Tri-Lists indizieren, bloss wenn man erstmal einen Index-Buffer verwendet, dann ist es ziemlich egal ob man nun Lists oder Strips rendert, da es kaum mehr einen Performance Unterschied gibt. Vorausgesetzt man organisiert seine Lists so dass die Indizes nicht "wild in der Gegend rumspringen". Mit Tri-Lists kann man eben meistens grössere Batches machen als mit Tri-Lists, und das bringt oft einiges. In OGL wohl weniger als in D3D, aber egal.
-
Mit Tri-Lists kann man eben meistens grössere Batches machen als mit Tri-Lists, und das bringt oft einiges
erklaer' mal.
-
hellihjb schrieb:
Mit Tri-Lists kann man eben meistens grössere Batches machen als mit Tri-Lists, und das bringt oft einiges
erklaer' mal.
Ja, ok, ich hätte sagen sollen "solange man nicht auf diverse Tricks zurückgreift". Wenn du degenerierte Dreiecke verwendest um Strips zu verbinden ist das natürlich nichtmehr so.
Auf jeden Fall würde ich die Performance von Strips vs. Lists in der speziellen Anwendung um die's geht vergleichen, und dann erst entscheiden ob es wert ist den zusätzlichen Aufwand zu treiben Strips zu verwenden.
-
Also bei statischer Geometrie in OGL sind Displaylisten durchaus eine Überlegung wert. Ich denke nicht, dass du da mit deinen VBOs schneller kommst.