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

Aktuelle Zeit: Mi Mai 15, 2024 07:32

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 9 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Vertex Daten Optimieren
BeitragVerfasst: Di Jul 03, 2012 12:35 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Hallo zusammen,

ich versuche mich gerade an einem OBJ Loader für Java.
Zum testen nehm ich das Sponza Model von Crytek, das ich mit folgenden infos ausgelesen habe:

Code:
  1. [OBJ] 153635 vertices, 91964 texcoords, 147510 normals
  2. [OBJ] 0 parameter space vertices
  3. [OBJ] 1 material libraries
  4. [OBJ]   sponza.mtl
  5. [OBJ] 382 objects
  6. [OBJ] 143842 total faces
  7. [OBJ] 566847 total indices
  8.  


Danach erzeuge ich für alle Faces dreiecke, da die Geometry definition Polygone, bzw. Triangle-Fans sind und nicht dreiecke.
Während ich diese erzeuge generiere ich ein Mesh mit frischen Indices und Vertices:

Code:
  1. [MESH] 837489 vertices
  2. [MESH] 837489 indices
  3. [MESH] 143842 faces


Wie man sieht, haben vertices und indices die gleiche anzahl, was natürlich Speichertechnisch nicht wirklich so toll ist.
Denn wie wir wissen hat z.b. ein Quad das aus 2 Dreicken besteht, wenn es paralell liegt 4 Vertices mit jeweils 6 Indices. Man sparrt sich also schon 2 Vertices bei einem Quad.

Deswegen nutzen ja brauchbare modelling tools - Algorythmen die schon vorhandene Vertices mit entsprechendem Index herausfinden können und die Indices anpassen, oder schon von vornerein keine vertices duplizieren.

Das habe ich nun selbst versucht, allerdings klappt das nicht so wie es ich mir vorgestellt habe oder ich habe etwas falsch verstanden.

Was ich versucht habe, ist beim Generieren der neuen Vertices, den vorhandenen Vertex-Index in meinem vorhandenem Vertex-Array zu suchen und dann entsprechend keinen neuen Vertex erzeugen, sondern den Index einfach auf den gefunden zu setzten.
Klingt einfach, funktioniert aber überhaupt nicht... es wird nie ein vorhander Vertex gefunden und immer ein neuer angelegt.

Die Equals Funktion für das Vertex Class funktioniert aber, diese habe ich alleine schon überprüft.

Vielleicht ist irgendwo ein logigfehler?

Hier ist ein wenig code, wäre super wenn ihr mir mit dem Problem helfen könntet.
Sorry für java aber wenn ich was ausprobieren will dann mach ich das nur noch mit java und LWJGL, da kann man wesentlich schneller und effizienter Programmieren, zumindest wenn man nicht im Speicher rumwusseln muss -.-

OBJLoader.java (Yay, ein wavefront obj loader)
http://pastebin.com/qbhY4t1y

Vertex.java (Simple vertex klasse)
http://pastebin.com/3v4psaVd

Face.java (Face vom Mesh)
http://pastebin.com/zZT8y3Br

Mesh.java (Das finale Mesh das aus dem OBJLoader erzeugt wird, hier sind auch die vertex such methoden drin)
http://pastebin.com/pRfPsyqd

Compares.java (Vertex, Vector3f, Vector4f nutzen dieses zum vergleichen von floats und überschreiben alle equals)
http://pastebin.com/NW0p5Zw7

Hier der eigentliche code der das Mesh befüllt (ist auch im OBJLoader.java enthalten):
Code:
  1.  
  2.         // Create mesh from loaded data
  3.         int tmp = 0;
  4.         int vertexIndex = 0;
  5.         for (OBJObject e : objects) {
  6.             for (OBJFace f : e.getFaces()) {
  7.                 OBJTriangle[] faceTriangles = f.createTriangles();
  8.  
  9.                 Face nface = new Face(vertexIndex, faceTriangles.length * 3);
  10.                 mesh.addFace(nface);
  11.  
  12.                 for (OBJTriangle triangle : faceTriangles) {
  13.                     Vector4f color = new Vector4f((float) Math.random(),
  14.                             (float) Math.random(), (float) Math.random(), 1.0f);
  15.                     for (int i = 0; i < 3; i++) {
  16.                         OBJFaceIndex faceIndex = triangle.get(i);
  17.                         Vertex nvertex = new Vertex();
  18.                         nvertex.pos = vertices.get(faceIndex.vertex); // Pos
  19.                                                                         // must
  20.                                                                         // always
  21.                                                                         // be
  22.                                                                         // exists
  23.                         nvertex.texcoord = faceIndex.texcoord != null ? texcoords
  24.                                 .get(faceIndex.texcoord) : new Vector3f();
  25.                         nvertex.normal = faceIndex.normal != null ? normals
  26.                                 .get(faceIndex.normal) : new Vector3f();
  27.                         nvertex.color = new Vector4f(color);
  28.                         int vindex = mesh.addVertex(nvertex, false);
  29.                         mesh.addIndex(vindex);
  30.                        
  31.                         vertexIndex++;
  32.                         tmp++;
  33.                        
  34.                         if (tmp > 10000) {
  35.                             System.out.println(vertexIndex);
  36.                             tmp = 0;
  37.                         }
  38.                     }
  39.                 }
  40.             }
  41.         }
  42.  


Brutal langsam ist das ganze leider auch, also das Suchen nach dem passenden Vertex das nicht funktioniert -.-

Danke,
Final


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Vertex Daten Optimieren
BeitragVerfasst: Di Jul 03, 2012 12:49 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
So schnell kanns gehen, ich musste ja unbedingt zufällige Farben pro Face haben...
Color auf default wert gesetzt, passt.

Naja, viel spass mit dem code, ist ja immerhin ein halbwegs funktionierender Wavefront OBJ Loader.



Allerdings hätte ich noch eine Frage:

Wie kann man dann die Vertex-Index-Suche Beschleunigen ? Ich habe ja schon einen Cache eingebaut... der aktuell auskommentiert ist.
Mal schauen ob der was bringt...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Vertex Daten Optimieren
BeitragVerfasst: Di Jul 03, 2012 13:08 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
OMG, das war richtig schnell... 2 sekunden das Sponza modell geladen mit java:

Code:
  1. [MESH] 192267 vertices
  2. [MESH] 837489 indices
  3. [MESH] 143842 faces
  4.  


Und wie wir sehen, yay... nicht annährend mehr soviele vertices wie vorher :)

Java hashCode() und HashMap sind toll:
Code:
  1.     @Override
  2.     public int hashCode() {
  3.         return new Float(x).hashCode() ^ new Float(y).hashCode() ^ new Float(z).hashCode() ^ new Float(w).hashCode();
  4.     }
  5.  


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Vertex Daten Optimieren
BeitragVerfasst: Di Jul 03, 2012 13:10 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jul 29, 2003 00:11
Beiträge: 436
Ich weiß nicht, ob das eine gute Lösung ist, aber in einem aktuellen Projekt verwende ich dafür folgendes:
Ich habe eine HashMap von Vertex auf Index. Entsprechend natürlich eine Hashfunktion definiert für den Vertex.
Dann eine Liste von Vertices und eine Liste Indices.
Beim Hinzufügen eines Dreiecks in das Mesh prüfe ich für jeden Vertex, ob die Map ihn schon enthält. Wenn ja, hab ich meinen Index. Wenn nicht, generiere ich einen neuen Index und schmeiß das Paar in die Map sowie den Vertex in die Vertexliste. Der Index wird auf jeden Fall in die IndexListe geschrieben.
Beim Aufbau der Buffer kann ich nun einfach über meine Vertexliste iterieren und reinschreiben. Der Indexbuffer dito.
Source (Ogre3D):
https://bitbucket.org/philiplb/ogrevolu ... hBuilder.h
https://bitbucket.org/philiplb/ogrevolu ... uilder.cpp


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Vertex Daten Optimieren
BeitragVerfasst: Di Jul 03, 2012 17:38 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Musst du da wirklich vier Floats erzeugen um den Hash zu berechnen…?

grüße

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Vertex Daten Optimieren
BeitragVerfasst: Di Jul 03, 2012 18:58 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Aug 18, 2007 18:47
Beiträge: 694
Wohnort: Köln
Programmiersprache: Java
Na toll. Den Loader hätte ich ein paar Monate früher gebrauchen können. Jetzt hab ich schon einen. :)

Aber mal Spaß bei Seite: Mein Loader war performance-technisch nicht so der Bringer.
Habe dann einen Cache im ModelManager zwischengeschaltet, der die Vertex / Indizes etc. in eine Binar-Datei haut.
Das ist dann doch noch um einiges schneller. Meistens um ein Faktor zwischen 20 und 30 schneller als jedes Mal die OBJ Datei durchzuparsen. Hab leider keine genauen Zahlen zur Hand, aber das Sponza Modell hat doch schon einige Sekunden gebraucht im OBJ Format. Aus dem Cache nur einige 100 ms.

_________________
Es werde Licht.
glEnable(GL_LIGHTING);
Und es ward Licht.


Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"

on error goto next


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Vertex Daten Optimieren
BeitragVerfasst: Mi Jul 04, 2012 09:22 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Philip hat geschrieben:
Ich weiß nicht, ob das eine gute Lösung ist, aber in einem aktuellen Projekt verwende ich dafür folgendes:
Ich habe eine HashMap von Vertex auf Index. Entsprechend natürlich eine Hashfunktion definiert für den Vertex.
Dann eine Liste von Vertices und eine Liste Indices.
Beim Hinzufügen eines Dreiecks in das Mesh prüfe ich für jeden Vertex, ob die Map ihn schon enthält. Wenn ja, hab ich meinen Index. Wenn nicht, generiere ich einen neuen Index und schmeiß das Paar in die Map sowie den Vertex in die Vertexliste. Der Index wird auf jeden Fall in die IndexListe geschrieben.
Beim Aufbau der Buffer kann ich nun einfach über meine Vertexliste iterieren und reinschreiben. Der Indexbuffer dito.
Source (Ogre3D):
https://bitbucket.org/philiplb/ogrevolu ... hBuilder.h
https://bitbucket.org/philiplb/ogrevolu ... uilder.cpp


Ähm, genau das habe ich am ende auch gemacht.

damadmax hat geschrieben:
Na toll. Den Loader hätte ich ein paar Monate früher gebrauchen können. Jetzt hab ich schon einen. :)

Aber mal Spaß bei Seite: Mein Loader war performance-technisch nicht so der Bringer.
Habe dann einen Cache im ModelManager zwischengeschaltet, der die Vertex / Indizes etc. in eine Binar-Datei haut.
Das ist dann doch noch um einiges schneller. Meistens um ein Faktor zwischen 20 und 30 schneller als jedes Mal die OBJ Datei durchzuparsen. Hab leider keine genauen Zahlen zur Hand, aber das Sponza Modell hat doch schon einige Sekunden gebraucht im OBJ Format. Aus dem Cache nur einige 100 ms.


Naja, klar das ASCII parsen langsamer ist als binary vordefinierte Strukturen zu lesen, aber ich finde es schon das hier ziemlich flott für java:

Code:
  1.  
  2. [OBJ] 'content\sponza\sponza.obj' loaded in 1498 msecs
  3. [OBJ:Warning] Unsupported identifier: s
  4. [OBJ] 153635 vertices, 91964 texcoords, 147510 normals
  5. [OBJ] 0 parameter space vertices
  6. [OBJ] 1 material libraries
  7. [OBJ]   sponza.mtl
  8. [OBJ] 382 objects
  9. [OBJ] 143842 total faces
  10. [OBJ] 566847 total indices
  11. [MESH] --- created in 655 msecs
  12. [MESH] 192278 vertices
  13. [MESH] 837489 indices
  14. [MESH] 143842 faces
  15.  


Total also 2,1 Sekunden für den Gesamten ladevorgang.

Allerdings muss ich dazusagen, das ich erstens noch kein VBO+IBO dafür erstelle und zweitens das auf meinem Alienware Notebook laufen lassen.
http://www.sysprofile.de/id34565

Allerdings habe ich nun das Problem, das zu Rendern... Im Wireframe, Immediate mode unoptimiert gerendert mit GTX 580M sehr ruckelig.

Es gibt aber eine Sache die ich Java hasse und das sind FloatBuffer oder ByteBuffer -.- Da wünscht man sich Pointer von C++ :(
Leider notwendig für Texturen und alle arten von Buffern in OpenGL bei java :(


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Vertex Daten Optimieren
BeitragVerfasst: Mi Jul 04, 2012 10:30 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2621
Wohnort: Berlin
Programmiersprache: Go, C/C++
Hihi, 2sekunden sind für ein so generisches Format wie Obj schon recht flink.
Willst du das als Zwischenformat verwenden oder soll das das endgültige Binaryformat werden ?
Als zwischenformat würde ich heute eher auf FBX setzten, da gibt es auch Bibliotheken von Autodesk.
Als Binaryformat würde ich besser gucken wie dein Code die Daten haben will und entsprechend anpassen.
Lieber ein paar bytes verfeuern als noch irgendwas zur ladezeit zu generieren und zu konvertieren.

Die meiste Zeit geht für den Festplattenzugriff drauf.
Ich hatte damals ein Hardwarenahes format für C++ gebastelt.
http://wiki.delphigl.com/index.php/Modelformat
Zitat:
Ein weiterer Vorteil ist der Codeumfang, denn dieser ist in meiner Implementierung gerademal 205 Zeilen lang. Mein Testmodel hatte ~15k Vertice, Normals, Texcoords, ~46k Indices, 15k Faces, 1Material und keine Properties. Die Dateigröße betrug 1,5MB und wurde in 7ms ungecached (erster Aufruf der Datei) und 3ms gecached(die Datei wurde seit dem Start von Windows schonmal angefasst) geladen, Pointer angepasst, VBOs für alle Daten erstellt und der Ladeprozess für die Textur angestoßen (alles in stolzen 7ms). Das Laden des ganzen Models mit der einer Textur (512x512 dxt5) hat knapp 20ms gedauert.

Das war zu HDD Zeiten also knapp 66% der Zeit sind nur für das laden vom Filesystem.

_________________
"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: Re: Vertex Daten Optimieren
BeitragVerfasst: Mi Jul 04, 2012 17:01 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
*schnief* Irgendwie hat das mit dem hashCode und das zusammen packen der Koordinaten nicht wirklich funktioniert, nun brauch ich 6.5 Sekunden zum laden und optimieren. Naja, aber ich habe eine Idee wie ich das noch schneller hinbekomme.

Habe mal ein Screenshot vom gerenderten Sponza Model dazu gepackt.
Nicht wundern, die Farben sind pro Face zufällig gesetzt, sieht lustig aus ^^


Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 5 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.023s | 17 Queries | GZIP : On ]