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

Aktuelle Zeit: Di Jul 08, 2025 16:18

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 7 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Fr Mai 04, 2007 10:53 
Offline
DGL Member

Registriert: Mo Jul 17, 2006 13:16
Beiträge: 69
Hi!

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:
  1.  
  2. procedure TGLText.Render;
  3. var
  4.   CurrentText: String;
  5.   cl: TColor;
  6.   a,b,c: Byte;
  7.   PosY: integer;
  8.   j, k: integer;
  9. begin
  10.   CurrentText := Text; // Text gibt z.B. die aktuelle Uhrzeit zurück
  11.   glDisable(GL_TEXTURE_2D); // Text ohne eine Textur zeichnen
  12.   cl := FFont.Color; // Schriftfarbe einstellen wie bei FFont
  13.   TColor2RGB(cl, a, b, c); // in RGB umwandeln
  14.   glColor3ub(a, b, c); // und zuweisen
  15.  
  16.   PosY := Top + Font_TextHeight(FFont, CurrentText); // hum... ich glaube die Textausgabe orientiert sich an links-unten, deshalb die Höhe dazurechnen
  17.   glRasterPos3f(Left, PosY, 0); // Position für das Rendern festlegen
  18.  
  19.   if not assigned(refFont) then begin
  20.     Assign_refFont; // Aus den bestehenden Displaylisten die passende für diese TFont raussuchen, ggf. neu generieren
  21.   end;
  22.  
  23.   glListBase(refFont.FontList); // Displaylist auswählen
  24.   // <--- bis hierher ist auf beiden PCs 0 ("Null") ms vergangen
  25.  
  26.   glCallLists(Length(CurrentText), GL_UNSIGNED_BYTE, Pointer(CurrentText)); // Text rendern
  27.   // so nun ist auf dem einen PC immernoch 0 ms, auf dem anderen ~160 ms. Warum?
  28. end;
  29.  


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.

Danke für schnelle Hilfe!


// Edit Lossy: Code durch Pascaltags ersetzt.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Mai 04, 2007 12:03 
Offline
DGL Member
Benutzeravatar

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.
Code:
  1. glCallLists(length(CurrentText), GL_UNSIGNED_BYTE, @CurrentText[1]);

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.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Mai 04, 2007 12:11 
Offline
DGL Member

Registriert: Mo Jul 17, 2006 13:16
Beiträge: 69
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:
  1.  
  2. procedure TGLText.Assign_refFont;
  3. var
  4.   i: integer;
  5.   Gefunden: Boolean;
  6.   temp_GOC: TGlobalObjectsCollection;
  7.   temp_Font: TMyGlFont;
  8.   pa: string;
  9. begin
  10.   if DC = 0 then exit;
  11.  
  12.   temp_GOC := TGlobalObjectsCollection(GOC);
  13.  
  14.   Gefunden := Funktion die Überprüft, ob es schon eine Liste für diese Font gibt; auskommentiert für das Forum
  15.  
  16.   if not Gefunden then begin // Wenn diese Font nicht in der Liste ist
  17.     refFont := TMyGLFont.Create; // Font erstellen
  18.     if not assigned(refFont) then exit;
  19.     with refFont do begin // Werte wie Fett, Kursiv ... zuweisen
  20.       pa := '';
  21.       if fsBold in FFont.Style then pa := pa + 'f';
  22.       if fsItalic in FFont.Style then pa := pa + 'k';
  23.       if fsUnderline in FFont.Style then pa := pa + 'u';
  24.       if fsStrikeOut in FFont.Style then pa := pa + 's';
  25.       Assign(FFont);
  26.  
  27.       if DC > 0 then begin // Wenn OpenGL schon initialisiert
  28.         FontList := glGenLists(256);
  29.         SelectObject(DC, refFont.Handle);              // Font auf einen Device Context benutzen
  30.         wglUseFontBitmaps (DC, 0, 255, refFont.FontList);  // Mit selektiertem Font Zeichen erstellen
  31.       end;  
  32.     end;
  33.     if assigned(temp_GOC) then begin
  34.       if temp_GOC.InheritsFrom(TGlobalObjectsCollection) then begin
  35.         temp_GOC.FontList.Add(refFont); // Diese Font mit in die Liste aufnehmen
  36.       end;
  37.     end;
  38.   end;
  39. end;
  40.  
  41.  
  42.   TMyGLFont = class(TFont)
  43.   public
  44.     FontList: Cardinal;
  45.     constructor Create; reintroduce;
  46.   end;
  47.  
  48. constructor TMyGLFont.Create;
  49. begin
  50.   inherited Create;
  51.   FontList := 0;
  52. end;
  53.  
  54.  



// Edit Lossy: Code durch Pascaltags ersetzt.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Mai 04, 2007 12:33 
Offline
DGL Member
Benutzeravatar

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.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Mai 04, 2007 12:38 
Offline
DGL Member

Registriert: Mo Jul 17, 2006 13:16
Beiträge: 69
Sry für die falschen Tags.

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.

Ich brauche halt so große Schriftarten :/


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Mai 04, 2007 13:12 
Offline
DGL Member
Benutzeravatar

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.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Mai 04, 2007 13:43 
Offline
DGL Member

Registriert: Mo Jul 17, 2006 13:16
Beiträge: 69
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!


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 7 Beiträge ] 
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder 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.017s | 17 Queries | GZIP : On ]