Problem: Mein Programm läuft auf verschiedenen PCs unterschiedlich schnell, unterschiede bis zu 100 FPS langsamer bei höherer Rechenleistung kommt vor.
Die Ursache lässt sich finden: Ich habe eine Routine, die an eine bestimmte Stelle des Bildschirms (2D-Anwendung) einen Text ausgibt (z.B. aktuelle Uhrzeit) mit den typsichen Font-Eigenschaften (Größe, Farbe, Schriftart, etc.) die sich nach dem erstellen nicht mehr ändern, ausser dem Text selbst (Uhrzeit läuft weiter...).
Die komplette folgende Prozedur benötigt auf dem einen PC (Nvidia) 0 ms (in Worten: Null) und auf dem anderen (Ati Xpress 200) ~160 ms bei Schriftgröße 72. Beide GraKa sind OnBoard. Beide PCs ~ 2 GHz DualCore, je 1 GB Ram und mind. 256 MB GraKa Ram, wenn auch Shared. (Aber BEIDE - bei der einen geht's, bei der anderen nicht).
Habe auf dem ProblemPC auch schon verschiedene Treiber (Original, Omega, verschiedene Versionen) durchprobiert. Keine Änderung.
Code:
procedure TGLText.Render;
var
CurrentText:String;
cl: TColor;
a,b,c:Byte;
PosY:integer;
j, k:integer;
begin
CurrentText := Text;// Text gibt z.B. die aktuelle Uhrzeit zurück
glDisable(GL_TEXTURE_2D);// Text ohne eine Textur zeichnen
cl := FFont.Color;// Schriftfarbe einstellen wie bei FFont
TColor2RGB(cl, a, b, c);// in RGB umwandeln
glColor3ub(a, b, c);// und zuweisen
PosY := Top + Font_TextHeight(FFont, CurrentText);// hum... ich glaube die Textausgabe orientiert sich an links-unten, deshalb die Höhe dazurechnen
glRasterPos3f(Left, PosY,0);// Position für das Rendern festlegen
ifnotassigned(refFont)thenbegin
Assign_refFont;// Aus den bestehenden Displaylisten die passende für diese TFont raussuchen, ggf. neu generieren
// <--- bis hierher ist auf beiden PCs 0 ("Null") ms vergangen
glCallLists(Length(CurrentText), GL_UNSIGNED_BYTE,Pointer(CurrentText));// Text rendern
// so nun ist auf dem einen PC immernoch 0 ms, auf dem anderen ~160 ms. Warum?
end;
Habe ich nun einen Fehler und generiere die Listen bei jedem Renderdurchlauf neu, oder was ist das Problem? Soll ich besser für jede Schrift eine eigene Textur anlegen und dann immer (wie mit BitmapFonts) einfach Teilbereiche der Textur rendern?
Alternativen?
Achtung: Es handelt sich bei dieser "Aufgabe" um standard-stinknormale Windows-Schrift. Wie z.B. Arial, Weiß, Größe 72, weder Fett, noch Kursiv oder Unterstrichen, keine Textur etc. Ich will nur Text ausgeben. Mehr nicht.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Als erstes. Es gibt auf jeden Fall unterschiede zwischen den Grafikkarten. Aber die sollten nicht so gravierend sein. Wobei ich aber denke, dass bei OnBoard Chips da evtl etwas mehr Spielraum besteht. Aber der Unterschied ist trotzdem extrem. Um nicht zu sagen. Zu Extrem.
Aber jetzt zu deinem Problem. Mit deinem Code lässt es sich leider nicht so gut sagen ob da ein Problem besteht. Denn für mich sieht der glCallLists nicht schlimm aus. Wobei ich persönlich eher folgendes Empfehlen würde.
Dabei wird der Text nicht als Pointer gecastet sondern der Pointer des ersten Zeichens ermittelt. Das lässt weniger Spielraum für den Kompiler. Aber ich bin auch ein Kontrollfanatiker.
Bzw mir fällt gerade ein was es evtl sein könnte. Und zwar du benutzt ja Texturenfonts? Wie groß ist denn die Textur? Ist deren Größe eine Potenz von 2? Denn ATI Karten sind da ein bisschen empfindlicher. Die Xpress 200 kann zwar OpenGL 2.0 aber bei NPOT Texturen verfällt sie mitunter in den Softwaremodus. Da die Zeichen aber eher nur recht klein sind muss er nicht so viel machen weswegen die Geschwindigkeit zwar abfällt aber nicht so extrem.
Falls es das nicht sein sollte dann müsstest du uns mal zeigen was du alles in der Displayliste anstellst. Also wie diese generiert wird.
Ich habe eine Globale TComponentList mit lauter TMyGLFont Einträgen (siehe unten). TMyGLFont ist eine normale TFont, die sich lediglich zusätzlich eine Zahl merken kann, als Referenz auf die OpenGL Displaylist.
Code:
procedure TGLText.Assign_refFont;
var
i:integer;
Gefunden:Boolean;
temp_GOC: TGlobalObjectsCollection;
temp_Font: TMyGlFont;
pa:string;
begin
if DC =0thenexit;
temp_GOC := TGlobalObjectsCollection(GOC);
Gefunden := Funktion die Überprüft, ob es schon eine Liste für diese Font gibt; auskommentiert für das Forum
ifnot Gefunden thenbegin// Wenn diese Font nicht in der Liste ist
refFont := TMyGLFont.Create;// Font erstellen
ifnotassigned(refFont)thenexit;
with refFont dobegin// Werte wie Fett, Kursiv ... zuweisen
pa :='';
if fsBold in FFont.Stylethen pa := pa +'f';
if fsItalic in FFont.Stylethen pa := pa +'k';
if fsUnderline in FFont.Stylethen pa := pa +'u';
if fsStrikeOut in FFont.Stylethen pa := pa +'s';
Assign(FFont);
if DC > 0thenbegin// Wenn OpenGL schon initialisiert
FontList := glGenLists(256);
SelectObject(DC, refFont.Handle);// Font auf einen Device Context benutzen
wglUseFontBitmaps (DC,0,255, refFont.FontList);// Mit selektiertem Font Zeichen erstellen
end;
end;
ifassigned(temp_GOC)thenbegin
if temp_GOC.InheritsFrom(TGlobalObjectsCollection)thenbegin
temp_GOC.FontList.Add(refFont);// Diese Font mit in die Liste aufnehmen
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Eine kleine Bitte. Benutz bitte für Pascal die Pascaltags. Das lässt sich besser lesen. Danke
Also das was wglUseFontBitmaps erstellt ist normal Problemlos einsetzbar. Und da kann man auch nichts verkehrt machen. Habe selber mal einen Unit dafür gemacht und die sieht in etwa genau so aus.
Das einzige Problem was dabei bestehen könnte ist, dass es sich um echte Bitmaps handelt. Die Karten sind normal auf Dreiecke spezialisiert. Du hattest ja etwas von Schriftgröße 72 gesagt. Wirfst du das auch so in wglUseFontBitmaps rein? Also in der Größe. Wenn ja dann versuch mal bitte eine kleiner Größe. Also 14-20 oder so und schaue mal wie lange er dann braucht.
Wenn es dann immer noch so langsam ist, dann weiß ich auch nicht mehr was es noch sein könnte.
Also diese Prozedur wird für alle Texte und Schriften (Schriftgrößen) verwendet.
Bei Schriftgrößen unter 20 braucht er ca. 16ms, bei Schriftgröße 72 wie gesagt damals 160, mittlerweile (einen Fehler aufgedeckt, wonach der Southbridge-Treiber nicht installiert war) bei 46 ms.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Na ja. Dann scheint es so als ob deine ATI Karte das nicht wirklich auf der Hardware macht. Wobei mich da aber der Southbridge Treiber etwas verunsichert. Okay. Der ist für den Datentransfer da zuständig aber ist merkwürdig. Der Chip hat aber volle PCIe Anbindung, oder?
Wenn du die Möglichkeit hast dann würde ich das noch mal auf anderen ATI Karte ausprobieren. Deine 200er ist ja eigentlich auch etwas eingeschränkt. Evtl haben etwas größere Karten dieses Problem nicht. Was allerdings noch immer dazu führen würde, dass es bei dir entsprechend langsamer wäre.
Entweder du sagst, dass du damit leben kannst sofern es nur bei dir so wäre oder aber du müsstest so etwas wie Texturfonts benutzen. Die benutzen wiederrum normale Dreiecke und werden somit anständig von der Hardware unterstützt. Wenn du das zur Laufzeit haben möchtest, dann dürfte das derzeit aber noch etwas komplizierter werden. Schau dir dazu auch mal folgendes Thema an.
Leider kann ich ja die GraKa nicht tauschen, weil OnBoard und der PC hat kein AGP/PCIe, da es ein "super-flach" PC ist, der verbaut wird. Eine größere "Höhe" des PCs ist leider nicht möglich, da wir diesen dann nicht einbauen können.
Wir wollen demnächst auf das Nachfolgemodell mit Nvidia umsteigen, aber ich muss das halt jetzt mit den ATI-Karten zum laufen bekommen.
Ich habe das im Moment so gelöst, dass ich für jeden Text den ich ausgebe eine Textur erstelle (Canvas.Textout auf ein TBitmap, dann zuweisen an eine GL-Textur) und diese dann immer rendern lasse. Schein soweit generell zu klappen, die Framerate ist insgesamt aber trotzdem niedriger also auf dem System ohne Probleme... Naja, solange es läuft...
Werde mir mal sobald ich Zeit habe deinen Link in der Wiki angucken.
Soweit aber schonmal vielen Dank für die Antworten!
Mitglieder in diesem Forum: 0 Mitglieder und 7 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.