OpenGL Performanceproblem
-
Verwende VBOs (Vertex Buffer Objects) anstelle der Display List.
-
Verwende VBOs (Vertex Buffer Objects) anstelle der Display List.
das passiert im treiber sowieso schon. je nach treiber-qualitaet passieren im rahmen der display-liste auch noch zusaetzliche optimierungen die allerhand eigeninitiative erfordern wuerden. vbos sind nur bei nicht-statischer geometrie zu bevorzugen.
-
Badestrand schrieb:
das Ganze läuft recht langsam
wir programmierer moegen das lieber genauer als diese weihen gefuehls definitionen

Badestrand schrieb:
edit: Läuft auf einem recht neuen Rechner unter Windows
bitte ein wenig genauer, besonders was die graka angeht.
hellihjb schrieb:
218.300 Dreiecke
ist eigentlich nicht sehr viel.
versuche sicherzustellen, dass eine displayliste nicht mehr als 64000 unterschiedliche vertices enthaellt.64000 ist bei displaylisten kein gutes limit. einfach soviel in die DL reinstecken wie man auf einmal kann und dann wird man schon sehen was rauskommt.
Andreas XXL schrieb:
(Das Hauptproblem wird überigens nicht die Grafikkarte sein sondern der Bus zur Grafikkarte.)
bei einer Statischen Displayliste ist der Bus sicherlich nicht das problem. das muss woanders liegen.
-
rapso schrieb:
Badestrand schrieb:
das Ganze läuft recht langsam
wir programmierer moegen das lieber genauer als diese weihen gefuehls definitionen

Verständlich
Ist aber schwer das an irgendwas festzumachen, weil ich ja nicht mit Frames oder so arbeite; das Bild wird einfach angezeigt (etwa Vogelperspektive, alle Dreiecke sind im Bild) und das Einzige, wo man die "Langsamkeit" merkt, ist beim Drehen oder Verschieben mit der Maus (steht ja sonst auch still :))rapso schrieb:
Badestrand schrieb:
edit: Läuft auf einem recht neuen Rechner unter Windows
bitte ein wenig genauer, besonders was die graka angeht.
Geforce 8800 GTS mit 256 MB RAM, es soll aber auch auf wesentlich schwächeren Rechnern laufen, wenn ich's hinkrieg auch auf Rechnern, wo das Mainboard die Grafikausgabe übernimmt

rapso schrieb:
64000 ist bei displaylisten kein gutes limit. einfach soviel in die DL reinstecken wie man auf einmal kann und dann wird man schon sehen was rauskommt.
Gut, wäre sonst wahrscheinlich kompliziert geworden

Der Tipp mit dem Frustrum-Culling ist zwar gut, aber hab ja leider, wie gesagt, die meiste Zeit alles auf dem Schirm, deshalb werde ich das erstmal nicht einbauen.
Bezgl. LOD werde ich mich auf jeden Fall näher einlesen, auf die Entfernung sieht man ja lange keine Details mehr, da sehe ich momentan das größte Optimierungspotential.
Mittlerweile hab ich auch die Anzahl der Dreiecke reduziert, sind jetzt nur noch 94k. Das Gute ist: Es sieht jetzt sogar besser aus
Läuft auch schon etwas flüssiger und es ruckelt auch fast nicht mehr beim Verschieben, ich werde es erstmal auf dem Labtop meiner Freundin ausprobieren. Demnächst will ich aber auch größere Gebiete darstellen, weshalb ich auf jeden Fall das LOD-Zeug einbauen will.
-
64000 ist bei displaylisten kein gutes limit. einfach soviel in die DL reinstecken wie man auf einmal kann und dann wird man schon sehen was rauskommt.
grundlegend gilt unter opengl auch das "MaxVertexIndex"-limit von direct3d (kann man im DXCapsViewer nachschauen). um unangenehmen ueberaschungen aus dem weg zu gehen, tut man gut daran 16bit indices (fuer gewoehnlich abzueglich ein paar steuercodes) anzunehmen.
Geforce 8800 GTS
wenn du da mit 200k triangles geschwindigkeitsprobleme hast, laeuft aber irgendwas verkehrt...
-
Badestrand schrieb:
rapso schrieb:
Badestrand schrieb:
das Ganze läuft recht langsam
wir programmierer moegen das lieber genauer als diese weihen gefuehls definitionen

Verständlich
Ist aber schwer das an irgendwas festzumachen, weil ich ja nicht mit Frames oder so arbeite; das Bild wird einfach angezeigt (etwa Vogelperspektive, alle Dreiecke sind im Bild) und das Einzige, wo man die "Langsamkeit" merkt, ist beim Drehen oder Verschieben mit der Maus (steht ja sonst auch still :))Du hast also 120fps und dann bricht das auf so ca 60runter?... du solltest alleine schon um festzustellen was deine optimierungen bringen (und ob ueberhaupt) dir die 10min goennen und nen framecounter einbauen.
einfachste moeglichkeit ist frames zu zaehlen und nach jeder sekunde die zahl ausgeben (und framecounter resetten).rapso schrieb:
Badestrand schrieb:
edit: Läuft auf einem recht neuen Rechner unter Windows
bitte ein wenig genauer, besonders was die graka angeht.
Geforce 8800 GTS mit 256 MB RAM, es soll aber auch auf wesentlich schwächeren Rechnern laufen, wenn ich's hinkrieg auch auf Rechnern, wo das Mainboard die Grafikausgabe übernimmt

ja, damit sollte es eigentlich locker fluessig laufen selbst wenn du das voll in die graka schiebst.
Bezgl. LOD werde ich mich auf jeden Fall näher einlesen, auf die Entfernung sieht man ja lange keine Details mehr, da sehe ich momentan das größte Optimierungspotential.
sag sowas nicht;)
das A und O vom optimieren ist rauszufinden was so langsam ist. sonst verbringst du tage am optimieren und am ende bringt es 0 weil es garnicht das problem behebt.deswegen geh systematisch vor. zeichne mal alles ohne das etwas zu sehen ist. zeichne es mal ohne texturen, zeichne es mal im wireframe, zeichne es mal mit culling fuer front und backfaces (hast du das ueberhaupt schon an?
) usw. auf der nvidia seite findest du viele paper zum optimieren und die wichtigsten sagen dir wie du das bottleneck findest.und mach nen screenshot fuer unseren screenshot thread

-
hellihjb schrieb:
64000 ist bei displaylisten kein gutes limit. einfach soviel in die DL reinstecken wie man auf einmal kann und dann wird man schon sehen was rauskommt.
grundlegend gilt unter opengl auch das "MaxVertexIndex"-limit von direct3d (kann man im DXCapsViewer nachschauen). um unangenehmen ueberaschungen aus dem weg zu gehen, tut man gut daran 16bit indices (fuer gewoehnlich abzueglich ein paar steuercodes) anzunehmen.
nichts fuer ungut, aber um sowas musst du dich nicht kuemmern.
das sollte der treiber intern machen und das mesh fuer sich optimal aufsplitten. blind vermuten bringt da echt nichts, da du sonst zu allen dingen die du in die displaylists stopfst die groesst moegliche dummheit annehmen muesstest und dann gleich selber alles machen kannst.btw. @Badestrand
zeichnest du jedes dreieck einzeln zwischen glbeing und glend, oder stopfst du soviele wie moeglich zwischen nur einem glbegin und glend?
setzt du texturen usw. zwischendurch immer wieder?
-
Gut, dann baue ich den Framecounter mal ein! Ich weiß nur nicht genau wie man das macht (peinlich).. Ich zeichne bei jeder Maus-Verschiebungsaktion mit "glCallList(1)". Soll ich also in einer Schleife ständig "glCallList(1)" (und irgendwelche Matrix- und Identity-Sachen) aufrufen und dabei zählen? Ach, ich probier das morgen einfach einmal, aber danke dafür!
rapso schrieb:
deswegen geh systematisch vor. zeichne mal alles ohne das etwas zu sehen ist. zeichne es mal ohne texturen, zeichne es mal im wireframe, zeichne es mal mit culling fuer front und backfaces (hast du das ueberhaupt schon an?
)Hehe, ich hab weder Texturen, noch wireframe oder culling noch backfaces (glaube ich jedenfalls, keine Ahnung was das ist :D). Also Texturen weiß ich natürlich, was das ist, hab aber keine, die Farbe richtet sich nach der Höhe des Geländes.
Und nen Screenshot mache ich auch gerne, grad hab ich was Wichtiges fertiggekriegt; hab die Dreiecke jetzt so, wie du sie hier (ganz unten) vorgeschlagen hattest, hatte nur ein Zacken-Problemchen mit Hügelketten und Tälern, das hab ich eben gerade rausgekriegt *freu*

Ich lade den Sourcecode (MSVC++ 2003) morgen einfach mal hoch, vielleicht kannst du dann auch mal über die Zeichnen-Methode (glLoadIdentity-, gluPerspective-, glMatrixMode-, usw -Aufrufe) drübergucken? Ist ziemlich chaotisch, ich blicke da nicht wirklich durch..

edit:
rapso schrieb:
zeichnest du jedes dreieck einzeln zwischen glbeing und glend, oder stopfst du soviele wie moeglich zwischen nur einem glbegin und glend?
glNewList( 1, GL_COMPILE ); glBegin( GL_TRIANGLES ); // Riesige Schleife glEnd(); glEndList();Ich hatte erst jedes Dreieck zwischen glBegin und glEnd, hatte aber das Gefühl, dass das langsamer war

-
glNewList( 1, GL_COMPILE );eigentlich ist das so gedacht, dass du dir die id (bei dir "1") fuer eine displaylist von opengl mit glGenLists geben laesst und dir nicht einfach eine ausdenkst...
das sollte der treiber intern machen [...] blind vermuten bringt da echt nichts
und ich haett's nicht erwaehnt, wenn ich das nicht schon mal erlebt haette.
-
@Badestrand:
Du sagst, du hast das Ganze in eine GUI eingebettet? Vielleicht ist das der springende Punkt?! Was ist das für ne GUI? MFC Anwendung? Wie wird das Rendering darin gesteuert?
-
hellihjb schrieb:
glNewList( 1, GL_COMPILE );eigentlich ist das so gedacht, dass du dir die id (bei dir "1") fuer eine displaylist von opengl mit glGenLists geben laesst und dir nicht einfach eine ausdenkst...
Gut, also glGenList um die Listen-ID zu bekommen und wenn ich die Liste neu füllen will, glNewList?
Cpp_Junky schrieb:
@Badestrand:
Du sagst, du hast das Ganze in eine GUI eingebettet? Vielleicht ist das der springende Punkt?! Was ist das für ne GUI? MFC Anwendung? Wie wird das Rendering darin gesteuert?Stimmt, ist MFC! Das Modell wird am Anfang erstellt und bei jeder Höhenänderung oder Farbänderung neu berechnet. Neu gerendert wird bei WM_PAINT oder wenn das Modell mit der Maus gedreht oder geschoben wird. Aber hast Recht, ich hab noch gar nicht dran gedacht, dass die GUI auch etwas langsam sein könnte (mit den Nachrichten), obwohl ich's grad zu Testzwecken in einer kleinen schmalen WinAPI-Anwendung laufen lasse - da fällt mir ein, dass in der MFC-Anwendung ja zwei Modelle nebeneinander angezeigt werden

-
Und ist da ein spürbarer Unterschied zwischen WinAPI und der MFC Anwendung?
-
Das Modell wird am Anfang erstellt und bei jeder Höhenänderung oder Farbänderung neu berechnet
und wie oft passiert das so durchschnittlich?
wenn du deine geometrie haeufig veraenderst, solltest du doch vbos erwaegen.
-
hellihjb schrieb:
Das Modell wird am Anfang erstellt und bei jeder Höhenänderung oder Farbänderung neu berechnet
und wie oft passiert das so durchschnittlich?
wenn du deine geometrie haeufig veraenderst, solltest du doch vbos erwaegen.Das passiert eigentlich recht selten, etwa alle 3 Minuten oder so
(oder was ist 'häufig'?)Cpp_Junky schrieb:
Und ist da ein spürbarer Unterschied zwischen WinAPI und der MFC Anwendung?
Ja, das könnte aber auch daran liegen, dass in der MFC-Anwendung ja zwei der Modelle nebeneinander liegen. Könnte man denn das MFC-Nachrichten-System irgendwie optimieren?
-
Badestrand schrieb:
... Könnte man denn das MFC-Nachrichten-System irgendwie optimieren?
Kommt drauf an wie du das Rendering auslöst und was das für ein Fenster ist. Wenn dein RC an einem Standard MFC Control hängt, solltest du dessen Paint Nachrichten überschreiben, damit nicht vor jedem Frame auch noch das olle Windows-Fenster neu gezeichnet wird.
hellihjb schrieb:
Das Modell wird am Anfang erstellt und bei jeder Höhenänderung oder Farbänderung neu berechnet
und wie oft passiert das so durchschnittlich?
wenn du deine geometrie haeufig veraenderst, solltest du doch vbos erwaegen.Sollte man nicht gerade dann besser normale Vertex Buffer nehmen? Die VBOs müssen doch bei jeder Änderung neu übertragen werden oder nicht?

-
Man sollte immer besser VOBs verwenden, ganz egal ob statischer oder dynamischer Inhalt.
-
Cpp_Junky schrieb:
Sollte man nicht gerade dann besser normale Vertex Buffer nehmen? Die VBOs müssen doch bei jeder Änderung neu übertragen werden oder nicht?

sobald du etwas zeichnest, wird es eh zur graka uebertragen. deswegen:
hustbaer schrieb:
Man sollte immer besser VOBs verwenden, ganz egal ob statischer oder dynamischer Inhalt.
wenn man hingegen weniger ahnung hat von ogl, bieten sich displaylisten an, weil darin mehr als nur die vertex optimierungen gemacht werden.
-
Achso *niemitvbogearbeitethat*
Ich hatte VBOs immer so verstanden, das man sie vorab "kompilieren" muss und sie anschliessend unveränderbar im VRAM verbleiben, während normale Vertex-Arrays lediglich aus dem "lokalen" RAM gelesen werden und somit jederzeit angepasst werden können.
-
Cpp_Junky schrieb:
Achso *niemitvbogearbeitethat*
Ich hatte VBOs immer so verstanden, das man sie vorab "kompilieren" muss und sie anschliessend unveränderbar im VRAM verbleiben, während normale Vertex-Arrays lediglich aus dem "lokalen" RAM gelesen werden und somit jederzeit angepasst werden können.vielleicht verwechselst du das mit displaylists. die werden compiliert und werden unveraendert im (V)Ram verbleiben.
-
rapso schrieb:
Cpp_Junky schrieb:
Sollte man nicht gerade dann besser normale Vertex Buffer nehmen? Die VBOs müssen doch bei jeder Änderung neu übertragen werden oder nicht?

sobald du etwas zeichnest, wird es eh zur graka uebertragen. deswegen:
hustbaer schrieb:
Man sollte immer besser VOBs verwenden, ganz egal ob statischer oder dynamischer Inhalt.
wenn man hingegen weniger ahnung hat von ogl, bieten sich displaylisten an, weil darin mehr als nur die vertex optimierungen gemacht werden.
Das ist rüchtüg.
Allerdings kann man IIRC ja auch VBOs mit display lists kombinieren. Oder täusche ich mich da jetzt?Trotzdem würde ich jedem Anfänger empfehlen gleich mit VBOs anzufangen, da man mit display lists irgendwann ansteht. Bzw. auch weil display lists in OGL 3.0 (hoffentlich) einfach nichtmehr da sein werden.