Registriert: Mi Jan 05, 2011 14:55 Beiträge: 47
Programmiersprache: Delphi, C++,C
Ich hab jetzt vor ca 1 Monat mit OpenGL angefangen. Ich habe nun angefangen, einen kleinen Mapeditor zu schreiben. Das klappt auch ganz gut nur das Problem ist, das ab einer bestimmten Größe nur der Basismap, also ohne aufwändige Texturen, meine Framerate in den Keller geht. Nun würde ich gerne wissen, welche Möglichkeiten ich habe das zu ändern. Ach ja mit culling hab ich probiert, da verschiendet allerdings meine halbe map.
So wie ich das sehe machst du eine 2D-Welt, sollte dies zutreffen ist Back-Face-Culling um ehrlich zu sein Blödsinn, auch wenn das so im Tutorial steht (da ja alle Flächen eh der Kamera zu gewandt sind (daher wäre es sogar Performancelastig durch Zusatzberechnungen)). (Wenn trotzdem wer einen Sinn dahinter sieht soll mir den mal nennen.) In diesem Fall empfiehlt sich ein 2dimensionales Array und 2 verschachtelte For-Schleifen.
Sollte das nicht zutreffen ist Back-Face-Culling eine gute Sache. Die halbe Szene verschwindet da bei dir? Dann hast du die Reihenfolge der Vertexe falsch festgelegt. --> http://wiki.delphigl.com/index.php/glBegin Solltest du ALLE Flächen genau andersherum definiert haben dann versuchs damit --> http://wiki.delphigl.com/index.php/glFrontFace glFrontFace(GL_CW); Ist vllt nicht ganz so sauber aber zum Test ganz gut. (Meines Wissens ist das eigentlich für Skalierung im negativen Bereich gedacht).
Registriert: Mi Jan 05, 2011 14:55 Beiträge: 47
Programmiersprache: Delphi, C++,C
Danke erstmal für die schnellen Antworten. Also ich denke ich hab mein Problem nicht genau genug beschrieben. Ich bin dabei ein 3d Mapeditior zu schreiben und hab beide Culling-Möglichkeiten ausprobiert. Bei Back-Face-Culling verschwinden Teil der Map aber ich weiß nun wiso. Ich hatte einfach die Punke zum Zeichnen nicht immer in der gleichen Reienfolge angegeben. Aber da ich noch nichts außer der Mapbegerezung , den Boden und einer Skybox habe bringen diese Methoden nichts. Mein Problem ist, das ich noch nicht verstanden habe wie ich mit den Displaylisten umzugehen habe. Im Moment zeichne ich alles mit For schleifen und glbegin...glend. Das heißt jetzt ich hab bei Mapgrößen über 100 mehr als 10 begin..end aufrufe. Ich denke mal das mir das die Permormance nimmt. Könnte meine Vermutung richtig sein?
Du solltest vllt erstmal erklären was du mit "Mapgröße" meinst. Bei Mapgröße denke ich an die Vierecke in den Dimensionen in einer 2 dimensionalen Welt. (Z.B. 300x400 (300 Vierecke pro Zeile und 400 Spalten.) Das meinst du aber wahrscheinlich nicht weil du ja eine 3D-Szene hast.
Wichtig wäre vllt das du nicht bei jedem Rendervorgang die Displaylisten erstellst sondern nur einmal beim Programmstart, diese nicht löschst (solange du sie brauchst) und diese dann aufrufst. Ich hab die noch nie benutzt und dank meinem RedBook weiß ich das Displaylisten in Zukunft nicht mehr "core" sind (das heißt neuere Grafikkarten MÜSSEN Displaylisten NICHT MEHR unterstützen (was nicht heißt das sie es nicht doch tun (zur Abwärtskompatibilität))).
Wenn du wissen willst was deine Grafikkarte an OpenGL-Funktionen unterstützt empfehl ich dir glView --> http://www.realtech-vr.com/glview/ (Das ist ein Programm und keine Funktion^^.)
Sonst wäre es noch hilfreich wenn du uns ein wenig Quelltext zeigst (insbesondere deine Renderfunktion).
Achja ein Fehler den manche machen: laden und löschen der Texturen bei jedem Rendervorgang.
Registriert: Mi Jan 05, 2011 14:55 Beiträge: 47
Programmiersprache: Delphi, C++,C
Nein die Texturen werden nur einmal geladen. Mit Mapgröße meine ich auch immoment großteils nur eine 2d map, da ich durch die schlechte Permormanche noch nicht weiterprogrammiert habe. Nur außen wird eine Wand gezeichnet.
Bei erstelle_rohmap geben die Werte die Größe der Map in X und Z an und bei Erstelle_umrandung die Höhe und die Textur.
Code:
glClearColor(0.4,0.4,1,1); glClear(GL_COLOR_BUFFER_BIT OR GL_DEPTH_BUFFER_BIT);
var ZeichneX, ZeichneZ : integer; begin MaplengthX := X; MAplengthZ := Z; for ZeichneX := 0 to X do For ZeichneZ := 0 to Z do begin glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,Gras); glPushMatrix(); glTranslatef((ZeichneX),0,(ZeichneZ)); glBegin(GL_QUADS); glTexCoord2f(0,0); glVertex3f(0,0,0); glTexCoord2f(0,1); glVertex3f(1,0,0); glTexCoord2f(1,1); glVertex3f(1,0,1); glTexCoord2f(1,0); glVertex3f(0,0,1); glEnd; glPopMatrix(); gldisable(GL_TEXTURE_2D); end; end;
Der Code funktioniert soweit auch ganz gut nur sobald es man eine zugroße Map erstellt sinkt die Framerate unter1, Ach ja hab mal nachgeschaut und meine GPU ist nicht limitieret. Die läuft bei ca. 30 Procent nur 2 meiner CPU kerne haben 100% Last.
Registriert: Do Jul 23, 2009 04:33 Beiträge: 157
Programmiersprache: Turbo Delphi Pro
Ja, das ist ja auch kein Wunder, denn du halst ja auch alles der CPU auf. Arbeite die Wiki-Seite zur DisplayList durch, und du wirst merken dass du eine wesentlich bessere Performance bekommen wirst Die beiden Prozeduren müssen dann nämlich nicht mehr bei jedem Renderdurchlauf ausgeführt werden, sondern nur noch einmal zum erzeugen der DL.
_________________ Bringe einen Menschen zum grübeln, dann kannst du heimlich seinen Reis essen. (Koreanisches Sprichwort)
Zuletzt geändert von Tilman am Mi Jan 05, 2011 17:23, insgesamt 2-mal geändert.
Dein Hauptproblem ist das immer nur wenige Quads in einem Draw-Call renderst! Warum machst du die Grundmap-Schleife nicht z.B. so:
Code:
glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,Gras); glPushMatrix(); MaplengthX := X; MAplengthZ := Z; glBegin(GL_QUADS); for ZeichneX := 0 to X do For ZeichneZ := 0 to Z do begin glTexCoord2f(0,0); glVertex3f(ZeichneX+0,0,ZeichneZ+0); glTexCoord2f(0,1); glVertex3f(ZeichneX+1,0,ZeichneZ+0); glTexCoord2f(1,1); glVertex3f(ZeichneX+1,0,ZeichneZ+1); glTexCoord2f(1,0); glVertex3f(ZeichneX+0,0,ZeichneZ+1); end; glEnd; glPopMatrix(); gldisable(GL_TEXTURE_2D);
Aber SDH.Prod hat natürlich recht. VertexBufferObjects (VBO) sind normalerweise die bessere Wahl.
Registriert: Mi Jan 05, 2011 14:55 Beiträge: 47
Programmiersprache: Delphi, C++,C
Ok danke ich werde versuchen mich in VOB einzulesen, aber da ich opengl noch nicht wirklich lange verwende wollte ich mich drum drücken. Und das mit begin end war von mir wirkich dämlich. Allein der letzte tip hat die cpu last gedrittelt. Danke nochmal an alle.
Es ist nicht ersichtlich was die Parameter bewirken.
glDisable(GL_TEXTURE_2D); Sollte nur aufgerufen werden, wenn du auch wirklich keine Texturen mehr verwenden willst, aber das scheint nicht der Fall zu sein, du zeichnest durchgehend mit Texturen. WEG DAMIT. AUS BEIDEN FUNKTIONEN. glEnable(GL_TEXTURE_2D); Diese Aufrufe werden damit überflüssig (da du ja die Disables rausnimmst (solltest du^^)). ABER: Einmal beim Programmstart, nachdem du OpenGL "gestartet" hast, musst du es aufrufen. ABER WEG RAUS AUS DER RENDERFUNKTION.
glBindTexture(GL_TEXTURE_2D,Gras); Du bindest (X+1)*(Y+1) mal die Textur "Gras". Das ist performancelastig. Dies schiebst du aus der Schleife raus. Am besten nach "MAplengthZ := Z;". Selbes in der 2. Funktion. "glBindTexture(GL_TEXTURE_2D,textur);" VOR die Schleife setzen und nicht bei jedem Schleifendurchlauf aufrufen.
Sonst halt noch Displaylisten oder besser VBOs nutzen.
Du kannst ausserdem noch bei den Würfeln GL_QUAD_STRIP nutzen. Nehm dir mal einen 6-seitigen Würfel zur Hand und halte ihn vor dir. Die Flächen mit den Augenzahlen 2, 3, 4 und 5 sollten eine Art "Band" ergeben welche du mit glBegin(GL_QUAD_STRIP) sich schneller zeichnen lassen müssten (du brauchst auch weniger glVertex3f-Aufrufe). Die anderen beiden Flächen musst du dann wohl oder übel mit glBegin(GL_QUAD_STRIP) machen.
glEnable(GL_TEXTURE_2D); .... ABER: Einmal beim Programmstart, nachdem du OpenGL "gestartet" hast, musst du es aufrufen.
Eigentlich nicht, habe das jedenfalls noch nie gebraucht. Damals in irgendwelchen uralten OpenGL-Versionen brauchte man das vielleicht mal, aber spätestens seit OpenGL 2.0 nicht mehr.
Mitglieder in diesem Forum: 0 Mitglieder und 4 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.