Hi,
Ich will viele Würfel zu einem Hypercube zusammenstellen. 15*15*15 Würfel á 6 Quads macht 40500 triangles. So etwa 100 bis 200 Würfel brauchen eine Textur, um darauf einen Font auszugeben. Die Textur darf nicht zu klein sein, sonst werden die Buchstaben pixelig (256x256 sieht pasabel aus). Dabei geht jetzt aber meine Performance auf <5 fps runter. Habt Ihr eine Idee, wie ich das geschickter realisieren kann?
Der Hypercube ist statisch (sollte vielleicht von mehreren Seiten einsehbar sein), die Einzelwürfel müssen mit einem Alpha <0.1 gesetzt werden, um auch die hinteren Objekte sehen zu können und in den Hypercube sollen die nichttransparenten Würfel mit den Fonts eingesetzt werden.
Erste Idee: ich nehme ein "Draht"gitter, also nur Linien statt Quads. Das macht allerdings die Optik kaputt und gefällt mir nicht.
Zweite Idee: Ich zeichne nur Regionen, die überdeckt werden neu. Den organisatorischen Aufwand scheue ich etwas .
Drittens: Ich mache eine Art Screenshot des Hypercubes. Damit bekomme ich die Tiefeninformationen sicher nur schwer hin.
Viertens: Ich nehme keine Textur, sondern zeichne die Buchstaben anders in die Quads. Wie das gehen soll weiss ich nicht, zumal ich keine extra Bibliothek nehmen will.
Gibt es eine Patentlösung für mein Problem?
TIA, Heiko.
Registriert: Do Sep 25, 2003 15:56 Beiträge: 7810 Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Das sollte so gehen wie du's dir vorstellst. Aber eventuell machst du was unnötiges, wenn deine Framerate so einbricht. Also mal bisl Code zeigen. Am meisten interessiert: GL-Initialisierung, Renderschleife, Verwendete Libs, (Sprache?)
(Ein Hybercube ist noch was anderes. Wenn du sowas mit ner 3D API darstellen kannst, haste vermutlich deine GraKa ruinigert )
_________________ Blog: kevin-fleischer.de und fbaingermany.com
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Also Drahgitter würde ich gar nicht empfehlen. Das ist in der Regel noch langsamer als Quads.
Das ist ja schon eine recht gute Menge an Flächen. Da alles statisch ist würde ich dir Empfehlen deine Renderart zu ändern. Ich gehe mal davon aus, dass du deine Würfel iterativ renderst. Das solltest du nach Möglichkeit nicht tun. Also entweder legst du deine Daten in einem VBO oder einer DisplayListe ab. In einem VBO ist es dann intern schon so geregelt wie du es auch bei einer DL machen solltest. Also ganz außen um deine Renderschleife kommt ein glBegin(GL_QUADS) und dann ratterst du einfach nur die Punkte herrunter. Also so, dass dabei Quads entstehen. Wenn du die Textur wechseln muss musst du natürlich glEnd machen und hinterher wieder ein glBegin. Um so weniger glBegins und glEnds du hast um so besser ist es.
Dann solltest du bedenken, dass das Blending an der Stelle ganz gut an Performance fressen dürfte. Das könntest du Testweise mal deaktivieren. Ich würde aber auf jeden Fall erst einmal probieren was der Umstieg auf eine optimierte DL so bringt. Denke mal, dass das die einzige sinnvolle Wahl ist die du hast.
PS: Je nachdem was du für Hardware hast kann es auch sein, dass die einfach nur am Ende ihrer Leistungsfähigkeit ist. Aber eine halbwegs moderne Grafikkarte sollte damit überhaupt keine Probleme haben. Sofern diese nicht kastriert wurde.
PPS: Es gibt nie Patentlösungen! Es gibt nur eine schier unermässliche Anzahl an kleinen Bausteinen mit denen sich jedes Problem lösen lässt.
@Flash: Einen Hypercube gibts ja tatsächlich! Dann nenn ich das Ding mal besser Multicube @Lossy eX: Ich zeichne schon jetzt ein Gitter. Die Würfel brauchen eine Kante und das ist ein LINE_LOOP. VBO sagt mir nichts, aber ich denke mal, es geht um die DisplayList. So weit ich das verstanden habe, ist diese Liste nur eine einfache Art, viele Objekte zu verwalten. Das Zeichnen wird mir wohl niemand abnehmen. glDisable(GL_BLEND) bringt tatsächlich was: bei 15*15*15 Cubes, davon 100 mit einer Textur von 128x128 geht die Leistung von ~8fps auf 14fps hoch. Ohne Blending bekomme ich aber keine Transparenz hin, und die brauche ich, um den Multicube durchschauen zu können. Aber prinzipiell suche ich nach solchen Ideen...
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Ich bin ein grenzenloser verfechter von Objekten aber an diese Stelle sind Objekte alles andere als praktisch. Ich habe ein Ähnliches Problemmit glScene mal gehabt. Da sind auch alles Objekte. Es geht schneller, wenn du es in etwa so machst wie ich es beschrieben habe. Also so gut wie kaum Redundanzen setzen. Da würde ich dir eher empfehlen eine Liste mit den Koordinaten + Textur zu machen und diese dann nach Texturen zu sortieren, damit du die kaum wechseln musst.
Das du mehrere Tausend mal ein und die Selbe Blendfunc + LineSmooth etc setzt macht eigentlich keinen Sinn. An der Stelle solte die Geschwindigkeit ganz oben stehen.
Registriert: Do Sep 25, 2003 15:56 Beiträge: 7810 Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Hm...Denke das der Verwaltungsaufwand dir hier ein Bein stellt. Lagere das setzen von eigenschaften mal in eine Funktion aus, welche du vor deinem Multicube aufrufst, und nicht jedesmal wieder. 15^3 sind ja immerhin 3375 aufrufe. Is klar, dass das in einer Sekunde nur begrenzt oft zu schaffen ist. Ich glaube das Line_Smooth kostet auch nochmal Zeit. Ich denke das auslagern hat erstmal einen größeren effekt als das auflösend er Objekt-Struktur.
_________________ Blog: kevin-fleischer.de und fbaingermany.com
Registriert: Di Dez 27, 2005 12:44 Beiträge: 393 Wohnort: Berlin
Programmiersprache: Java, C++, Groovy
Hallo,
du hast nicht zufälligerweise vor eine Art 3D-Scrabble zu programmieren, oder?
Für so eine Art Hypercube müssten eigentlich 90 Quads ausreichen.
Du fasst dann von den einzelnen Würfeln immer 15 mal 15 Faces, die in einer Ebene liegen, zu einem Face zusammen und legst dann eine einzelne Textur rüber.
Allerdings musst du es dann irgendwie schaffen die Fonts geschickt auf die Texturen rendern.
Bei 90 mal X x Y - Texturen könnte dein Grafikspeicher aber ziemlich schnell voll werden.
Eine alternative Idee, falls es jetzt wirklich um 3D-Scrabble geht und du für jeden Cube nur einen Buchstaben verwenden möchtest : Du könnstest jeden Buchstaben als 3D-Objekt erstellen und in den jeweiligen Würfel platzieren, fall nötigs (wieder in deinen Hypercube, bestehend aus 90 Faces), das wären dann aber wieder sehr viel Geometriedaten, falls dein Würfel 'voll' wird.
Was mir noch einfällt : wozu benötigt man eigentlich eine hohe Framerate?
Solange du den Würfel nicht drehst und nichts an deiner Scene änderst brauchst du deine OpenGL-Scene nicht immer wieder neu zu rendern (falls du nicht unbedingt vorhast noch irgendwelche animierende Effekte, wie z.B. eine Partikel-Engine, unterzubringen ).
Falls du den Würfel dann drehen willst, zeichnest du nicht alle Buchstaben, sondern z.B. nur die äußeren, das dürfte dann doch ziemlich flüssig werden oder ?
Das Argument sehe ich nicht ein (oder verstehe es nicht). OK, da sind ein, zwei Schritte, die objektfrei nicht wären, z.B. Liste auslesen, aber so lange dauert das nun auch wieder nicht. Ich hab natürlich schon rumprobiert, ob die glEnable(s) eine sonderliche Auswirkung haben. Allein Blend hat einen Effekt.
Zitat:
@dj3hut1: du hast nicht zufälligerweise vor eine Art 3D-Scrabble zu programmieren
In der Tat soll Scrabble 3D werden. In einer weiteren Ausbaustufe könnte jede Seite der Würfel einen anderen Buchstaben haben, die alle miteinander kombiniert werden müssen. Das wäre auch ein schöner Test für Hochbegabte . Falls jemand an dem Projekt mitarbeiten will, liese sich das hier diskutieren...
Wie Du auf 90 kommst, ist mir schleierhaft. Wenn ich den Gedanken richtig verstanden habe, dann sollte ich eine Ebene á 15x15 Felder als ein Kasten definieren, dort eine Texture mit 15x15 Farben drüber ziehen und hätte nur 15 große Kästen zu zeichnen (statt 15^3 kleine). Das könnte wirklich klappen, wobei ich über die Transparenz noch nachdenken muss. Ich dachte mir, dass ich die Ebene, in die der aktuelle Stein hineingezogen wird, weniger transparent mache. Dadurch würde die Orientierung sicher verbessert werden. 15 Objekte hintereinander sind halt nur dann sichtbar, wenn sie sehr durchlässig sind. Gute Idee aber!
Einen 3D Buchstaben in den Würfel reinzeichnen, geht sicher auch. Ich stelle mir das Ergebnis aber nicht sonderlich schön vor, der Kubuseffekt fehlt dann sicherlich.
Eine hohe Framerate brauche ich tatsächlich nicht immer. Wenn aber ein neuer Spielstein gedragt werden soll, dann muss das schon flüssig gehen. Und vielleicht fällt mir ja wirklich noch eine Erweiterung ein, die den Multi- zu einem Hypercube macht. Zum Beispiel ändern sich die Buchstaben in einem festen zeitlichen Rhythmus, was beim Legen mit bedacht werden muss. 4D wird aber die linguistischen Grenzen noch vor den ergonomischen sprengen Gruss, Heiko.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Heiko. Es geht nicht primär darum was bei dir dauert oder nicht dauert sondern mehr um das was du bei der Grafikkarte an Optimierungen/Vereinfachungen vornehmen kannst. Wenn du zum Beispiel sagst, dass du eine BlendFunc hast, dann muss eine Funktion aufgerufen werden und der Treiber muss das entgegen nehmen. Wenn er gut gemacht ist, dann wissen sie ob das stumpfe Setzen schneller geht als es vorher noch mal abzuprüfen. Ähnlich ist das wie mit glBegin und glEnd. Nur, dass er da nicht viel optimieren kann.
So ist zum Beispiel folgender Code schneller
Code:
glBegin(GL_QUADS);
for X :=1to15000dobegin
glVertex3f(x, y, z+1);
glVertex3f(x+1, y, z+1);
glVertex3f(x+1, y+1, z+1);
glVertex3f(x, y+1, z+1);
end;
glEnd;
als dieser
Code:
for X :=1to15000dobegin
glBegin(GL_QUADS);
glVertex3f(x, y, z+1);
glVertex3f(x+1, y, z+1);
glVertex3f(x+1, y+1, z+1);
glVertex3f(x, y+1, z+1);
glEnd;
end;
Auch wenn so etwas mittlerweile sehr gut optimiert wurde und kaum noch groß ins Gewicht fallen dürfte. Entscheidend dabei ist aber die Masse an Aufrufe. Du kennst den Spruch mühsam ernährt sich das Eichhörnchen. Abgesehen davon kann es auch sein, dass deine Anwendung mal auf Systemen läuft auf denen so ein Phänomen mehr zum Tragen kommt. Bei mir ist hier derzeit aber alles langsam, da meine Karte über keinen echten Speicher verfügt und den Haupspeicher benutzt. Also muss immer alles über den Bus transportiert werden.
Als Alternative zum iterativen Rendern solltest du wirklich mal überlegen ob du nicht lieber DLs oder VBOs benutzen möchtest. Auch wenn das deine Objektstruktur auseinanderreßt. Aber bei beiden können die Daten auf der Grafikkarte abgelegt werden. Was definitiv schneller ist als sie jedes Mal über den Bus zu schicken. Und das ist sogar sehr gut messbar. Wobei du bei DLs auf jeden Fall schauen solltest dass du da redundante aufrufe verhinderst. Auch wenn es deiner Meinung nach kaum etwas bringen mag. Redundanzen sollte man in jedem Falle vermeiden außer der eigene Aufwand würde zu groß werden.
Wobei du ja auch irgendwo linien zeichnest? Wie viele sind denn das? Ich frage weil Linien sehr Performancefressend sind.
Anderenfalls würde es sich wohl in jedem Falle anbieten sich mal einen Kopf zu machen ob es nicht ganz anders geht. Siehe beispiel von dj3hut1. Aber das ist eine Sache die wir dir nicht abnehmen können, da wir nur schlecht wissen was genau du vor hast. Evtl solltest du dann auch auf den ein oder anderen Effekt verzichten um es nicht zu kompliziert werden zu lassen. Oder aber mal nach Alternativen fragen. Löcher in einem Quad kann man zum Beispiel auch mit dem Alphakanal in der Textur regeln. Wenn diese nicht gefiltert ist solltest du sogar das Ergebniss bekommen was du mit einzelnen Quads bekommen würdest.
PS: Hattest du eigentlich mal abgeprüft ob dein OpenGL Code fehlerfrei ist? Also mit glGetError? Wenn er dort nämlich einen Fehler hat kann es mitunter zum argen Ausbremsen des Systems kommen. Es wäre auch mal interessant zu erfahren was du da für eine Grafikkarte hast?
Registriert: Di Dez 27, 2005 12:44 Beiträge: 393 Wohnort: Berlin
Programmiersprache: Java, C++, Groovy
Hallo Ocye,
naja auf die 90 kommt man ganz einfach : Bei 15x15x15 Würfeln hast du 15x15x15x6 Flächen.
Wenn du immer 15x15 Flächen zu einer machst, hast du nur noch 15x6=90 Flächen.
Lossy eX: Abgesehen davon kann es auch sein, dass deine Anwendung mal auf Systemen läuft auf denen so ein Phänomen mehr zum Tragen kommt.
Genau deshalb versuche ich zu optimieren. Mit den DL hast Du wohl Recht, ich werde mir das mal ansehen. Linien zeichne ich per LINE_LOOP (2x4 glVertex3f) und LINES (1x8) um den Würfel herum. Lass ich die weg, dann gehen die fps um knapp 20% hoch. Fehler habe ich auf Dein Anraten hin gerade geprüft (if glGetError<>GL_NO_ERROR then showmessage('Fehler'); nach jedem Rendern) -> alles sauber
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Auf was für einem System testest du denn das gerade? Meines hier ist von der Grafikleistung her sehr beschränkt und da hatte ich bei 15^3 geblendeten Würfeln und auf jedem Würfel eine andere Textur (2 Immer abwechseln) immer noch eine FPS von knapp über 30 und das obwohl die Karte (ATI X300) keinen eigenen Speicher für Textur/Vertexdaten hat.
Auf was für einem System testest du denn das gerade?
Nicht hauen: P4 3.2, 512MB, Intel 82915G. Ich muss unbedingt mal zu Hause testen...
Aber wie gesagt: ich will versuchen, die Anforderungen an die Hardware möglichst gering zu halten. Mich überrascht der große Unterschied zu Deinem System aber doch etwas. 30fps bekomme ich nur hin, wenn ich das Fenster auf etwa QVGA-Größe setze.
Mitglieder in diesem Forum: 0 Mitglieder und 6 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.