Hi,
im Moment verwende ich die Unit gl3ds, um Meshes (.3ds, Milkshape) zu laden. Allerdings geht selbst mein erst ein halbes Jahr alter Computer in die Knie, wenn ich mehr als 50 gleiche Objekte mit jeweils ca. 20 Triangles in meiner Szene lade.
Daraus lässt sich folgern, dass ich entweder irgendwas gründlich falsch mache oder gl3ds nicht für große Massen an Objekten ausgelegt ist.
Es muss ja noch mehr gehen, wenn man solche Spiele wie Medieval II betrachtet, in denen manchmal über 1000 Einheiten auf dem Bildschirm zu sehen sind.
An der Zahl der Polygone kann es eigentlich nicht liegen, denn 60000 Polygone mehr in der verwendeten Heightmap (wegen höherem Detaillevel) wirken sich weniger rechenlastig aus als 200 neue Objekte (=4000 Polygone).
An was könnte das liegen oder wie sonst könnte ich die Performance bei einer großen Objektanzahl noch einigermaßen hoch halten?
Über Antworten und Hinweise würde ich mich freuen.
Registriert: Do Sep 25, 2003 15:56 Beiträge: 7810 Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Die Frage stell ich mir auch gerade. Normalerweise lädt man jedes Objekt nur einmal, und rendert diese dann nur an 100 verschiedenen stellen. Eventuell tauscht man noch die textur vor dem rendern aus, um verschiedene Farben/Uniformen zu erreichen.
_________________ Blog: kevin-fleischer.de und fbaingermany.com
//undefined=Konstante, getMapHeight ermittelt die Heightmaphöhe bei x,z
gltranslatef(x,y,z);
glscalef(size,size,size);
glrotatef(rot,0,1,0);
Mesh[Index].Render;
glpopmatrix();
end;
Mit LoadMesh lade ich am Anfang (in GLForm.Create) alle benötigten Meshes,
ShowMesh wird für jedes Objekt, das gerendert werden soll, einmal aufgerufen.
Das Array Mesh ist dabei einfach eine Liste aller verfügbaren Meshes.
Wenn ich eure Fragen richtig verstanden habe, wäre damit alles beantwortet:
- Ich lade alle Meshes (momentan erst eine) bei Beginn einmal einfach(wenn ich gl3ds richtig verstanden habe)
- diese rendere ich dann via ShowMesh mehrmals
Was euch noch interessieren könnte, die Mesh ist mit einer Animation, die ich am Anfang jedes Rendervorgangs über folgende Passage fortlaufen lasse:
Code:
ifnot Paused then
for i:=0toHigh(Mesh)do
if Mesh[i].NumSkeletons >=1then
Mesh[i].Skeleton[0].AdvanceAnimation();
Allerdings sehe ich darin auch kein Problem, v.a. da das hier bis jetzt nur einmal pro Rendervorgang ausgeführt wird.
Weil bisher nur eine Mesh geladen wird, könnte man die Schleife eigentlich noch weglassen.
Wenn ihr noch zusätzlichen Quellcode zur Vervollständigung braucht, dann mailt mir doch einfach.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Es gibt bei der Meshklasse eine Eigenschaft oder Methode mit der eine Displayliste erstellt wird. Frag mich bitte nicht wie die heißt aber wenn du mal nach DisplayList suchst solltest du fündig werden. Damit sparrst du einiges an Zeit beim Render, da vor allem die Daten wenn möglich auf der Grafikkarte abgelegt werden.
Sonst sieht der Code in meinen Augen recht ungefährlich aus. Aber leider ist es mittlerweile so, dass die Geschwindigkeit nicht mehr nur von der Anzahl der Flächen abhängt sondern auch recht stark von der Anzahl der Renderaufrufe abhängt die die CPU leisten muss.
Es gibt die Möglichkeit einer Displayliste, aber wenn ich die aktiviere, dann funktioniert die Animation nicht mehr.
Und was das mit der CPU angeht, da versteh ich nicht ganz was du genau meinst.
Registriert: Di Jul 01, 2003 18:59 Beiträge: 887 Wohnort: (The Netherlands)
Programmiersprache: fpc/delphi/java/c#
gl3ds is not optimized for speed.
For static meshed you should use the displaylist feature.
Obvious not for animated meshes. But you are free to write your own faster render routine ( T3dsMesh.Render ), much can be improved there (for example you could upload al vertex data at once to the video card and use an glsl shader to do the bone animation). Do share it.
Also feel free to update bone animation at another place giving more or less updates per frame. It is just an example.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Früher als die Grafikkarten noch keinen Lüfter hatten waren in den Anwendungen ca 5000 Flächen zu finden. Und diese wurden alle iterativ gerendert. Also mehr oder weniger in einer Schleife. Und alles was man sparen konnte wurde gesparrt.
Heutzutage sind 5000 Flächen gar nichts mehr. Aber beim iterativen Rendern ist es so, dass du für jeden Vertex einmal eine Texturkoordinate setzt dann noch den Vertex himself und was weiß ich nicht noch alles. Aber bei jedem Funktionsaufruf müssen die Parameter auf den Stack gepackt werden und auf der anderen Seite wieder runtergeholt werden. Außerdem muss die Grafikkarte ständig auf neue Daten waren bzw die CPU bis die Grafikkarte wieder fertig ist. Etc etc etc. Also reichlich zu tun.
Wenn du jetzt im Vergleich eine Displayliste oder VBO erstellst und dort reichlich Flächen hineinpackst dann kannst du diese Flächen mit einem einzigen Befehl zeichnen. Niemand muss auf irgendwen anderes warten und es läuft schneller.
you could upload al vertex data at once to the video card and use an glsl shader to do the bone animation
Zitat:
feel free to update bone animation at another place
Yes, I' sure I could do all this. But only if I had some more experience with OpenGl (especially shader). In fact I'm very new to 3D-Programming.
Anyway, another question: Is it possible to create a different display list for every state
of the animation and to call the fitting one when a certain state is needed?
And if it's possible, is it also sensible?
@Lossy ex:
Besteht denn irgendwann die Gefahr, dass der Grafikkartenspeicher erschöpft, oder ist dann mit Displaylisten und Texturen allein (fast) nicht möglich?
Ich weiß nicht wer hier welche sprache versteht ....
Den Grafikkartenspeicher kann man sehr schnell aufbrauchen. Ich würde auf jeden Fal von einem massivem einsatz von Displaylisten abraten. Eine Animation per Vertexshader zu programieren ist nicht schwer als es mit der normalen CPU zu tun.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Ja natürlich kann das passieren. Das kommt halt immer darauf an wie viel Speicher du zur Verfügung hast. Aber bei Texturen oder VBOs ist es meistens dann so, dass du diese entweder nicht erstellen kannst oder sie locker Frei im Haupspeicher gelagert werden. Beim Rendern müssten sie dann zwar über den AGP/PCIe Buss geschaufelt werden was duchaus schon langsamer ist aber im Endeffekt ist das alle mal schneller als alles einzeln zu Rendern.
Ich würde mir da im übrigen eher um Texturen sorgen machen. 512x512x32Bit RGBA. Das sind mal eben 1 MB an Grafikspeicher.
Registriert: Di Jul 01, 2003 18:59 Beiträge: 887 Wohnort: (The Netherlands)
Programmiersprache: fpc/delphi/java/c#
Zitat:
Anyway, another question: Is it possible to create a different display list for every state of the animation and to call the fitting one when a certain state is needed? And if it's possible, is it also sensible?
Hmm, that is an interesting way of doing it. Do try it out. I only fear it will use up lots of videocard resources. Let us know what the outcome is.
Also on the topic of glsl and vbo there are tutorials on the subject. I know it is advanced, but it is the only way to get speedy opengl apps.
If I'm in the center of the map, 40-45 of 50 Objects are drawn (55-65fps), if I'm in a corner about 10 to 20 at 260fps.
On the other hand backface culling is enabled.
This is all I have in my project concerning the saving of performance so far.
I would have liked to include something like frustrum culling and octree, but I fear this is beyond my abilities.
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.