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

Aktuelle Zeit: Mo Nov 23, 2020 20:17

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



Ein neues Thema erstellen Auf das Thema antworten  [ 8 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Clan-Wirtschaft: Performance
BeitragVerfasst: Do Jun 20, 2013 15:43 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jun 05, 2013 15:12
Beiträge: 146
Wohnort: Glinde
Programmiersprache: Delphi 7
[size=80]Abgespalten aus [Game] Clan-Wirtschaft // Horazont[/url]

So,
ich hab bis jetzt nix anderes mehr gemacht als alle Points-Modelle durch Texturen mit Quads-Modelle zu ersetzen.
Ich bin überhaupt nicht zufrieden, denn das Resultat ist mies.
6 FPS auf der höchsten Auflösung und das, obwohl ich gerade mal nur 50 % darstellen lasse.
Vorher habe ich doppelt soviel bearbeiten können und hatte volle Grafikleistung.
Wo mache ich den Fehler ?

Ich habe mir aus den Einzelbildern, die ich zu Points umgewandelt hatte, eine Textur gebastelt.
Diese Textur ist aufgebaut wie eine animierte Textur.

Bild

PS: Ich benutze eine Kontrastfarbe, die mein 'Bilder_zu_Quelltext' Umwandler damals einfach ignoriert hatte.
Die Kontrastfarbe war auch vorher schon da und soll nun als Alpha dienen.
Ich habe nun die Stücke zu einer Textur zusammen gefügt.
Da mir empfohlen wurde, nicht hunderte kleiner Dateien zu laden.
Das Neue ist, dass ich nun eine Alpha-Textur brauche.

Code:
  1.  
  2.     // ########################################################
  3.     // ############## Feldunten Textur laden ##################
  4.     // ########################################################
  5.  
  6.     Felduntentextur := TglBitmap2D.Create; // Instanz der Klasse erstellen
  7.     // Datei laden
  8.     Felduntentextur.LoadFromFile(Hauptprogrammpfad+'Texture\Feld\Landunten.bmp');
  9.     //Aus der Kontrastfarbe Alpha erstellen
  10.     Felduntentextur.AddAlphaFromColorKey(255, //Rot
  11.                                       0,     //Grün
  12.                                       255,  //Blau
  13.                                       0); //Keine Abweicheung
  14.     //geladene Textur an OpenGL übergeben
  15.     Felduntentextur.GenTexture;
  16.  


Textur und Alpha sind geladen. Sollte so optimal gehen oder?

Als nächstes werden die Kartenfelder in eine Displaylist geladen.
Dieses habe ich nur angepasst/ausgetauscht.
Die Modelle bestanden vorher aus den Points.

Code:
  1.  
  2.     // ########################################################
  3.     // #################### Untere Felder Modelle #############
  4.     // ########################################################
  5.  
  6.     for i:= 0 to high(UnteresfeldModellist) do
  7.     begin
  8.      UnteresfeldModellist[i] := glGenLists(1);
  9.      glNewList(UnteresfeldModellist[i], GL_COMPILE);
  10.        UnteresfeldModelarchiv(i);
  11.      glEndList;
  12.     end;
  13.  


Code:
  1. Procedure UnteresfeldModelarchiv(ModelNr:Integer);
  2. var
  3.   Texturx,textury:integer;
  4. begin
  5.   try
  6.     //Die Koordinaten auf der Textur rausfinden
  7.     textury:= floor(Modelnr/10);
  8.     Texturx:= Modelnr-(textury*10);
  9.  
  10.     //Aktiviere Alpha und binde Textur
  11.     glEnable(GL_ALPHA_TEST);
  12.     Felduntentextur.Bind;
  13.     glAlphaFunc(GL_greater, 0.1);
  14.    
  15.     //Bild aus der Textur ausschneiden
  16.     glBegin(GL_QUADS);
  17.      glTexCoord2f((Texturx/10)+0  ,(textury/10)+0  ); glVertex3f(0,0,0);  //lo
  18.      glTexCoord2f((Texturx/10)+0  ,(textury/10)+0.1); glVertex3f(0,32,0); //lu
  19.      glTexCoord2f((Texturx/10)+0.1,(textury/10)+0.1); glVertex3f(32,32,0);  //ru
  20.      glTexCoord2f((Texturx/10)+0.1,(textury/10)+0  ); glVertex3f(32,0,0);   //ro
  21.     glEnd;
  22.  
  23.   gldisable(GL_ALPHA_TEST);
  24.   except
  25.     Fehlertextaktiv:=true;
  26.     Fehlertextbeschreibung:='UnteresfeldModelarchiv konnte geladen werden : '+inttostr(modelnr);
  27.   end;
  28. end;
  29.  


Soweit sogut...
Die Textur sollte nun in der Grafikkarte verankert sein und nicht mehr über den FSB gezogen werden.

Jetzt rufe ich das Bild auf.
Volle Auflösung heißt bei mir 28'416 Bilder. Ging mit GL_Points mit voller Framezahl.
Am Aufruf selber wurde nix verändert.

Code:
  1.  
  2.                 //Unters Dreieck zeichnen
  3.                 glPushMatrix;
  4.                  glTranslatef((X2)+(X1),
  5.                               -(X1)-(X4)-29,
  6.                               0);
  7.                  glcalllist(UnteresfeldModellist[Maparray[X3,0]]);
  8.                 glPopMatrix;
  9.  


1. Wo frisst der Rechner nun die Leistung?

2. Wenn die Modelle geladen sind, kann ich dann die Textur entladen?
Oder wird sie in der Grafikkarte immer wieder neu zugeschnitten?
Das würde mir erklären, wo die Leistung verloren geht.
Bei den Points brauchte ich nur das Modell entladen und wenn ich sie brauchte, konnte ich sie aus dem Quelltext neu generieren.

Ja ich weiß, wenn ich die Karte in größere Gesamtstücke unterteile "Chunks", kann ich mehr Leistung aus dem FSB holen, aber wenn das Grundgerüst schon hängt, lohnt sich eine Optimierung nicht.

Post Scriptum:
Dieses ist bereits der vierte Versuch die Maptextur zu laden.
Ich habe mich deshalb für diese herangehensweise entschieden, weil ich auch die Personen nicht als Fake3D bauen wollte.
Sondern als Bilder-Call weiterhin nutzen möchte.
Die Vorherige Lösung war eine Fließtextur. Allerdings war sie furchtbar verschwommen.
Selbst die Texturfilter konnten sie nicht retten. Dies schien mir die beste Lösung, denn auch die Ambiente ist aus Einzelbildern aufgebaut.

LG Polarwolf

_________________
幸福は笑う人に来て ~~ koufuku wa warau hito ni kite
Das Glück kommt zu denen die lachen


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: [Game] Clan-Wirtschaft
BeitragVerfasst: Do Jun 20, 2013 16:28 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Bindcalls und statewechsel im allgemeinen sind sehr teuer. Zieh mal das .Bind der Textur und die glEnable-Aufrufe aus der Displayliste raus. Mach einfach vor dem Zeichnen der Map:
Code:
  1.     glEnable(GL_ALPHA_TEST);
  2.     Felduntentextur.Bind;
  3.     glAlphaFunc(GL_greater, 0.1);

und nach dem Zeichnen
Code:
  1.   gldisable(GL_ALPHA_TEST);


(mit „Zeichnen der Map“ meine ich die schleife aus deinem letzten Code-Snippet)

Da kosten dich übrigens vermutlich auch die push/pop-matrix aufrufe einiges. Als alternative könntest du da das glTranslate mit einem weiteren glTranslate-Call nach dem glCallList-Aufruf wieder rückgängig machen. Das spart dir einen OpenGL aufruf.

Aber das ist auch nicht das gelbe vom Ei. Matrizenmultiplikationen sind relativ teuer. Und du machst hier pro Feld einen Drawcall, das ist schrecklich ineffizient. Ein Drawcall heißt, ein glCallList bzw. ein glEnd bzw. ein glDrawArrays oder sowas.

zu zweitens: Nein, die Textur muss geladen bleiben (du musst ja schließlich auch immer wieder Bind aufrufen). Die Grafikkarte ist aber sehr darauf spezialisiert, Bilder „zuzuschneiden“ und es werden dabei z.B. keine Kopien angelegt. Das ist möglicherweise sogar schneller als wenn man die Punkte selber zeichnen würde, weil viel weniger Daten über den Bus gehen und weil die Daten optimal im Grafikkartenram liegen. Was sie beim Immediate-Mode nicht tun (bei Displaylisten möglicherweise aber schon).

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: [Game] Clan-Wirtschaft
BeitragVerfasst: Sa Jun 22, 2013 17:28 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jun 05, 2013 15:12
Beiträge: 146
Wohnort: Glinde
Programmiersprache: Delphi 7
Ich danke dir Lord Horazont.
Nach einigen Tests mit deinen Vorschlägen habe ich herausgefunden, wo die Probleme liegen.
Alle Tipps habe ich ausprobiert. Hier mal die Ergebnisse.
Zum Vergleich aber schnell mal das Schema der alten Scene.

Code:
  1.  
  2. Lade Interface Fenster 1.2.3.n*
  3.  
  4. Hat sich das Feld bewegt dann
  5.  Neues Sichtfenster berechnen
  6.  
  7. Schleife der sichtbaren Felder
  8.  Berechnung der Koordinaten
  9.   Zeichne unters Dreieck des aktuellen Feldes
  10.   Zeichne oberes Dreieck des aktuellen Feldes
  11.   Zeichne Ambiente/Gebäude (wenn vorhanden)
  12.   Zeichne Person (wenn vorhanden)
  13.   wenn Spezialwünsche aktiv
  14.    Zeichne Kugel im "Bauplan" Modus (wenn vorhanden)
  15.    Zeichne Kugel im "Gelände begehbar" Modus (wenn vorhanden)
  16.    Zeichne Kugel blablabla   (halt alles was ich zwischendurch mal wissen wollte, habe ich mir hier anzeigen lassen)
  17. Ende der Schleife
  18.  


Nun habe ich natürlich ein dickes Problem. Vorher mit den Points brauchte ich keine "Bindcalls" und "Statewechsel".
Mit den Texturen kann ich aber natürlich so nicht weitermachen. Es sei denn, ich habe alle Muster und Farben in EINER EINZIGEN Textur oder aber ich baue alles voller Schleifen.
Code:
  1.  
  2. Alpha aktiv
  3. TexturMap.bind
  4. Schleife der sichtbaren Felder
  5.   Zeichne unters Felder
  6.   Zeichne oberes Felder
  7. Ende der Schleife
  8.  
  9. TexturAmbiente.bind
  10. Schleife der sichtbaren Felder
  11.   Zeichne Ambiente des Feldes (wenn vorhanden)
  12. Ende der Schleife
  13.  
  14. TexturPersonen.bind
  15. Schleife der sichtbaren Felder   (und so weiter und so weiter)
  16.  


Es gefällt mir nicht wirklich. Aber wenn es sein muss, muss es sein.

Ich habe erst einmal alles, außer die reine Map deaktivert.
Und die Textur vor der Schleife gebunden.
17 Frames aber die 85 % der Daten waren schonmal drin.

push/pop durch glTranslate ersetzen bringt mich auf 18 Frames.

Drawcall/Drawlist weglassen und den Primitiven direkt rendern.
Mein FSB bricht unter der Last zusammen und Windows wird lahm ;)
Das Spiel fällt von 18 auf 5 F/S. Nein der Drawcall mag Leistung kosten, aber ohne bricht das Spiel zusammen.
Da ganz offensichtlich anstatt des einen Calls ...
1 GL_Quad + 4 glTexCoord2f(Plus Daten) + 4 glVertex3f(Plus Daten) + 1 GL_End nun durch die Leitung müssen.

Dann dachte ich mir, hey deaktiviere doch mal den Alpha und lass die Textur mal ungeschnitten. Vielleicht kostet dich das Schneiden was.
Das Spiel fällt auf 7 Frames, da sehr oft übereinander gezeichnet wird.

Ich habe daher meine Textur zusammengefasst.
Und rechne nun an einer neuen Kamera. Das Ergebnis ist schon mal vielversprechend.

Bild

Bis dann.
Polarwolf

_________________
幸福は笑う人に来て ~~ koufuku wa warau hito ni kite
Das Glück kommt zu denen die lachen


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: [Game] Clan-Wirtschaft
BeitragVerfasst: So Jun 23, 2013 11:15 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Schön, dass es besser wird!

Zu den Drawcalls: Naja, glEnd ist ja auch ein Drawcall. Was du eigentlich statt dessen machen wolltest, ist, alle Quads in einem glBegin/glEnd block zusammen zu packen. Das ist vermutlich etwas schneller als die DL, vorrausgesetzt, die Daten passen über den Bus (was sie eigentlich können sollten, ist ja nicht wirklich viel was du da renderst. 1000 Quads?). Optimum ist natürlich, wenn du deine ganze Map in Chunks aufteilst (z.B. immer so 100×100 Felder oder 20×20 Felder), die zusammen in eine Displaylist mit genau einem glBegin/glEnd-Block packst und dann immer die Listen aufrufst, von denen gerade Felder sichtbar sind. Diese Technik lässt sich dann auch später sehr einfach auf VBOs übertragen, was dann das non-plus-ultra an Geschwindigkeit wäre.

//Edit: Wo ich gerade dein Bild sehe: Du willst vielleicht auf Dreiecke umsteigen, anstatt Quads. Die sind noch ein stück schneller zu rendern und du sparst dir den alpha-test (weil deine Terrain-Primitivien nun mal Dreiecke sind).

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: Clan-Wirtschaft: Performance
BeitragVerfasst: So Jun 23, 2013 21:10 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jun 05, 2013 15:12
Beiträge: 146
Wohnort: Glinde
Programmiersprache: Delphi 7
Danke fürs verschieben. ;)

Lord Horazont hat geschrieben:
Das ist vermutlich etwas schneller als die DL, vorrausgesetzt, die Daten passen über den Bus (was sie eigentlich können sollten, ist ja nicht wirklich viel was du da renderst. ).


Durch das Bauen und damit verändern der Mapdaten müsste ich im Gebiet den Chunk recht oft neu laden.

Lord Horazont hat geschrieben:
//Edit: Wo ich gerade dein Bild sehe: Du willst vielleicht auf Dreiecke umsteigen, anstatt Quads.


Quads sind es nicht mehr. In der aktuellen "Test"-Reihe sind es tatsächliche bereits GL_TRIANGLES.

Lord Horazont hat geschrieben:
1000 Quads?

Die gebrauchte Anzahl ist je nach Auflösung:
(ClientWidth/20) * (ClientHeight/10)
In meinem Fall also:
(1280/20)*(1024/10)=6554
Naja und der Rest der links, rechts, oben und unten als Puffer dient damit keine Löcher entstehen.
Sagen wir grob 7000 aktiv gezeichnete Felder.

G Polarwolf

_________________
幸福は笑う人に来て ~~ koufuku wa warau hito ni kite
Das Glück kommt zu denen die lachen


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Clan-Wirtschaft: Performance
BeitragVerfasst: So Jun 23, 2013 21:25 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
7000 sollten wirklich kein Problem sein. Nicht im geringsten. Das neubauen der Chunks ist vergleichweise günstig. Gerade beim VBO musst du dann nur die Texturkoordinaten der entsprechenden Dreiecke anpassen und per glBufferSubData hochladen. Bei Displaylisten geht das natürlich nicht, da musst du die DL neu bauen – das ist aber auch ok, passiert ja nicht jeden Frame. Damit ist es trotzdem günstiger und du sparst eine Menge, weil du viel weniger Drawcalls machst. Die sind wirklich das teuerste.

Wichtig ist es halt, möglichst viele Primitivien mit einem Drawcall (also einem glBegin/glEnd, glDrawArrays, …) zu rendern. Also bei den Chunks auch unbedingt die ganzen Triangles gemeinsam in ein glBegin/glEnd packen.

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: Clan-Wirtschaft: Performance
BeitragVerfasst: Mi Jun 26, 2013 12:15 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jun 05, 2013 15:12
Beiträge: 146
Wohnort: Glinde
Programmiersprache: Delphi 7
Ich bin zu der Erkenntnis gelangt, das ich doch lieber nochmal Nachfrage.

Ich habe meine Personen in eine animierten Textur gepackt.
So sieht es aus:
Bild

:!: Kontrastfarbe für Alpha sollte klar sein.
:!: Die T-Shirt Farbe soll die Farbe des Spielers annehmen.

Lösungsansatz 1 Bitte nicht schlagen :twisted:
Ich habe 5 * 5 * 5 Spielerfarben. Ich erstelle also 125 mal den Personen-Frame (ein 1600*1600 Pixel großes Monster) mit jeder Farbe als eigene Datei...
Aua... Au...

Ok ok
Lösungsansatz 2 :D
Ich lade die Textur:
Code:
  1.  
  2.     // ########################################################
  3.     // #####################  Personen ########################
  4.     // ########################################################
  5.  
  6.     Persontextur := TglBitmap2D.Create; // Instanz der Klasse erstellen
  7.     Persontextur.LoadFromFile(Hauptprogrammpfad+'Texture\Person\Frame.bmp'); // Datei laden
  8.     Persontextur.AddAlphaFromColorKey(255, //Rot
  9.                                     0,     //Grün
  10.                                     255,  //Blau
  11.                                     0); //Keine Abweicheung
  12.  
  13. Tausche hier die weißen Pixel gegen Spielerfarbe und lege sie 125 mal in den Grafikspeicher *hust
  14. Natürlich nur die, die auch im nächsten Spielstand benötigt werden.
  15. Aber was, wenn 100 KI's mitspielen. :idea:
  16.  
  17.     Persontextur.GenTexture; // geladene Textur an OpenGL übergeben
  18.  


Nun muss ich mit Textur.bind bei jeder Figur... :shock: *ruckel ruckel shit

Lösungsansatz 3
Hey :idea:, ich mach das so wie vorher mit den Points... Mit glcolor3f Farbe austauschen und malen... warum sieht die Person so Schlumpfartig im Gesicht aus :?:

Ich hoffe ich habe mein Problem gut "versteckt" unter eure Großhirnrinde geschoben.
Wie kann ich die weiße Farbe mit GUTER Performance tauschen, ohne jedesmal .Bind oder oder oder aufrufen zu müssen.

Keine Sorge es sind wenn es hoch kommt 100-200 Personen maximal.
Davon werden sicherlich nicht alle 125 Farben auf einen Bildschirm zur gleichen Zeit kommen.
Rendern sollte also drin sein.

LG Polarwolf

_________________
幸福は笑う人に来て ~~ koufuku wa warau hito ni kite
Das Glück kommt zu denen die lachen


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Clan-Wirtschaft: Performance
BeitragVerfasst: Mi Jun 26, 2013 12:43 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Pixelshader sind eine Option. Eine andere Option ist, die Textur einfach aufzuteilen: Den unveränderlichen Teil einmal, und das Shirt ein anderes mal. Das Shirt ist weiß, kann also mit glColor3f einfach eingefärbt werden.

Übrigens solltest du weniger Rand in den Texturen lassen, spart platz und geht gut, solange du nicht zoomen willst.

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  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 8 Beiträge ] 
Foren-Übersicht » Programmierung » OpenGL


Wer ist online?

Mitglieder in diesem Forum: Bing [Bot] und 10 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:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.035s | 18 Queries | GZIP : On ]