Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Mo Jul 14, 2025 05:21

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 6 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Terrain Rendern
BeitragVerfasst: Do Apr 30, 2009 16:19 
Offline
DGL Member

Registriert: Sa Mär 14, 2009 17:48
Beiträge: 99
Programmiersprache: D, Java, C++
Hi,
ich hätte da mal eine Frage bezüglich des Renderns eines Terrains: Wie krieg ich das ding am Speichersparendsten auf den Bildschirm? Derzeit Render ich jedes Dreieck unabhängig von den anderen, also im GL_TRIANGLES Modus, gibt es da nicht was eleganteres bspw. mit GL_TRIANGLE_STRIP, um weniger Vertices übertragen zu müssen? Mir fügt sich da einfach kein Bild zusammen, wie man das machen könnte, TRIANGLE_STRIP scheint wohl nur aneinanderreihungen von Dreiecken in eine Richtung zu beherschen? Also so wie hier skizziert: http://wiki.delphigl.com/index.php/glBegin

Wäre über Tipps & Tricks Dankbar :).


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Apr 30, 2009 16:59 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Da gibt es viele Möglichkeiten, die wohl sparsamste und zugleich aufwändigste wäre über eine Heightmap und ein geometryshader, eine weitere Möglichkeit wäre das mesh in trianglestrip umwandeln zu lassen(nicht gerade trivial aber nv und ati bieten da tools) oder du baust ein symetrisches terrerain,welches wie ein Gitter aufgebaut ist.
Letztes kannst du mit 2 Forschleifen erreichen.
Code:
  1. TVertex Vert[10*((10+1)*2)]//pro quad werden 2 weitere punkte benötigt und es sind 2 startpunkte zusätzlich notwendig
  2. int ind=0;
  3. for (int x=0;x<10;x++)
  4. {
  5.   for (int y=0;y<10;y++)
  6.   {
  7.     Vert[ind]=Vertex(x,GetHeight(x,y),y);
  8.     ind++;
  9.     Vert[ind]=Vertex(x+1,GetHeight(x+1,y),y);
  10.     ind++
  11.   }
  12.   Vert[ind]=Vertex(x,GetHeight(x,y+1),y+1);
  13.   ind++;
  14.   Vert[ind]=Vertex(x+1,GetHeight(x+1,y+1),y+1);
  15. }
  16.  
  17. for (int x=0;x<10;x++)
  18. {
  19.   glBegin(GL_TRIANGLE_STRIP);
  20.   for (int i=x*22;i<(x+1)*22;i++)
  21.     glVertexf(Vert[i].x,Vert[i].y,Vert[i].z);
  22.   glEnd();
  23. }


Das geht noch platzsparender, wenn man nur noch eine Schleife verwendet und damit nur ein Trianglestrip für das ganze Terrain aber dementsprechend ist auch die Funktion komplexer und die kann ich mir nicht mehr so schnell aus den Finger saugen wie die 2 Schleifen Variante. Es ist auch wesentlich besser nicht glBegin zu nehmen, sondern VBO oder Vertex-Array, um die Performance aufrecht zu halten.

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Apr 30, 2009 17:13 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Am speichersparendsten ist sicher eine Lösung über Shader. Dazu gibt es im Wiki einen Beispielshader. Dieser ist zwar für ShaderModel 4.0, wenn man das Prinzip verstanden hat, sollte dies aber auch mit älteren Grafikkarten, zur Not auch mit ShaderModel 1.0, realisierbar sein.

Falls Shader keine Option sind (wir sind im Einsteiger-Forum ;) ), sind wahrscheinlich Indices die Lösung die du suchst. Also Indices in Kombination mit GL_TRIANGLES. Mit glBegin kommst du da nicht weit. Schau dir mal die Vertexbuffer-Objects (VBO) an, ich glaub im VBO-Tutorial steht alles wichtige. Ansonsten GL_ARB_vertex_buffer_object anschauen.

Ich umreiße vorsichtshalber auch nochmal kurz die Idee hinter "Indices".
Wenn man sich ein durchschnittliches Mesh anschaut stellt man fest, das im Durchschnitt jeder Vertex von 6 Dreiecken verwendet wird. (mathematischer Beweis) Jeder Vertex, zusammen mit seiner Position, Normale, Texcoords, usw. wird also 6 mal gespeichert. Das ist natürlich Unfug. Die Idee hinter Indices (Plural von "Index") ist nun zwei Listen zu verwenden:
- ein Array speichert die Vertices.
- eine zweites Array definiert nun die Dreiecke. In diesem Array werden aber nicht die Vertices direkt gespeichert, sondern der jeweilige Index an dem sich der Vertex im ersten Array befindet.
Statt einem riesigen 32 Byte (oder mehr) großen Vertex (Position+Normale+Texcoords) wird nur ein 2 oder 4 Byte großer Index gespeichert. Dies reduziert die Datenmenge gewaltig.

Wenn du mit VBOs arbeitest, wirst du zwei Buffer benötigen:
1. GL_ARRAY_BUFFER für die Vertices
2. GL_ELEMENT_ARRAY_BUFFER für die Indices

_________________
Yeah! :mrgreen:


Zuletzt geändert von Coolcat am Do Apr 30, 2009 17:23, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Apr 30, 2009 17:22 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
@TAK2004: Es ist möglich GL_TRIANGLE_STRIPs mittels zwei degenerierten Dreiecken aneinander zu heften.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Apr 30, 2009 17:28 
Offline
DGL Member

Registriert: Sa Mär 14, 2009 17:48
Beiträge: 99
Programmiersprache: D, Java, C++
Danke euch beiden für die Antworten ;)... Naja an Shader wage ich mich noch nicht, aber VBOs sind kein Problem, die Sache mit den Indices gefällt mir, dass werde ich wohl mal umsetzen....

Code:
  1. for (int x=0;x<10;x++)
  2. {
  3.   glBegin(GL_TRIANGLE_STRIP);
  4.   for (int i=x*22;i<(x+1)*22;i++)
  5.     glVertexf(Vert[i].x,Vert[i].y,Vert[i].z);
  6.   glEnd();
  7. }


Genau solche Code Fragmente wollte ich nicht haben, ich dachte eigentlich, ich könnte das gesamte Terrain (am besten in VBO freundlicher Reihenfolge :)) zeichnen, und nicht jede Spalte in einen neuen glBegin/glEnd Block. Derzeit hab ich mein VBO so aufgeteilt, dass das gesamte Terrain in viele kleinere Blöcke geschnitten wird, sodass ich mittels Frustum Culling nur die Blöcke Zeichne, die sich auch im Sichtfenster befinden (wobei der Frustum Culling Teil noch nicht implementiert ist ;)).

Ich werde mich dann wieder melden, falls Probleme auftreten, für weitere gute Ideen bin ich natürlich weiterhin offen :).


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Apr 30, 2009 23:22 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Das ist definitiv der bessere Weg(VBO), den du gehen willst allerdings würde ich dann nicht auf Triangle Strip setzen, da es langsamer als Triangle Listen(mit indices) ist.

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 6 Beiträge ] 
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.008s | 16 Queries | GZIP : On ]