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

Aktuelle Zeit: Mo Jul 14, 2025 13:48

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



Ein neues Thema erstellen Auf das Thema antworten  [ 22 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: Fontmanager Problem
BeitragVerfasst: So Dez 10, 2006 16:50 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Hi Leute. Ich habe mein Programm jetzt um einen ScenenManager erweitert, allerdings geht nun komischerweise mein Fontmanager nich mehr richtig ^^

Bsp:
In meiner Renderfunktion wird am Ende ein FPSGraph gezeichnet:
Code:
  1.  
  2.   glEnable(GL_BLEND);
  3.   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  4.  
  5.   // BackGround
  6.   glColor4f(0.5,0.6,0.7,0.25);
  7.   glBegin(GL_QUADS);
  8.     glVertex3i(FPS_GRAPH_POSITION[0],FPS_GRAPH_POSITION[1],0);
  9.     glVertex3i(FPS_GRAPH_POSITION[2],FPS_GRAPH_POSITION[3],0);
  10.     glVertex3i(FPS_GRAPH_POSITION[4],FPS_GRAPH_POSITION[5],0);
  11.     glVertex3i(FPS_GRAPH_POSITION[6],FPS_GRAPH_POSITION[7],0);
  12.   glEnd();
  13.  
  14.   // Rahmen
  15.   glColor4f(0.5,0.6,0.7,1);
  16.   glBegin(GL_LINE_LOOP);
  17.     glVertex3i(FPS_GRAPH_POSITION[0],FPS_GRAPH_POSITION[1],0);
  18.     glVertex3i(FPS_GRAPH_POSITION[2],FPS_GRAPH_POSITION[3],0);
  19.     glVertex3i(FPS_GRAPH_POSITION[4],FPS_GRAPH_POSITION[5],0);
  20.     glVertex3i(FPS_GRAPH_POSITION[6],FPS_GRAPH_POSITION[7],0);
  21.   glEnd();
  22.  
  23.   glColor4f(0.5,0.6,0.7,0.25);
  24.   glBegin(GL_LINES);
  25.     // Vertikale Linien
  26.     for i:=0 to FPS_GRAPH_WIDTH DIV 10 do
  27.     begin
  28.       glVertex3i(FPS_GRAPH_POSITION[0]+i*10,FPS_GRAPH_POSITION[1],0);
  29.       glVertex3i(FPS_GRAPH_POSITION[6]+i*10,FPS_GRAPH_POSITION[7],0);
  30.     end;
  31.  
  32.     // Horizontale Linien
  33.     glVertex3i(FPS_GRAPH_POSITION[0],FPS_GRAPH_POSITION[1]+FPS_GRAPH_HEIGHT DIV 2,0);
  34.     glVertex3i(FPS_GRAPH_POSITION[2],FPS_GRAPH_POSITION[3]+FPS_GRAPH_HEIGHT DIV 2,0);
  35.  
  36.     // aktuelle FPS
  37.     glColor4f(0.5,0.6,0.7,0.5);
  38.     for i:=0 to Length(FPS60) do
  39.     begin
  40.       if FPS60[i]>0 then
  41.       begin
  42.         ActualFPSHeight := FPS_GRAPH_HEIGHT-round(FPS60[i]*FPS_GRAPH_HEIGHT/(HighestFPS+10));
  43.         //unten
  44.         glVertex3i(FPS_GRAPH_POSITION[0]+i*10,FPS_GRAPH_POSITION[1],0);
  45.         // oben
  46.         glVertex3i(FPS_GRAPH_POSITION[6]+i*10,FPS_GRAPH_POSITION[7]-ActualFPSHeight,0);
  47.       end;
  48.     end;
  49.   glEnd();
  50.   glDisable(GL_BLEND);
  51.  
  52.   DiffWidth := FontManager.GetTextWidth('FPS',inttostr(FPS60[59])+' FPS');
  53.  
  54.   glEnable(GL_TEXTURE_2D);
  55.     with FontManager do
  56.     begin
  57.       Draw('FPS',inttostr(HighestFPS)+' FPS',    FPS_GRAPH_POSITION[2]+5,           FPS_GRAPH_POSITION[5] - Fonts[GetFontId('FPS')].Height);
  58.       Draw('FPS',floattostr(HighestFPS/2)+' FPS',FPS_GRAPH_POSITION[2]+5,           FPS_GRAPH_POSITION[3] + FPS_GRAPH_HEIGHT DIV 2 - GetTextHeight('FPS','FPS') DIV 2);
  59.       Draw('FPS','0 FPS',                        FPS_GRAPH_POSITION[2]+5,           FPS_GRAPH_POSITION[3]);
  60.       Draw('FPS',inttostr(FPS60[59])+' FPS',     FPS_GRAPH_POSITION[0]+5,           FPS_GRAPH_POSITION[1]);
  61.       Draw('FPS',inttostr(Seconds)+' Seconds',   FPS_GRAPH_POSITION[0]+DiffWidth+25,FPS_GRAPH_POSITION[1]);
  62.     end;
  63.   glDisable(GL_TEXTURE_2D);


Es werden leider weder die aktuellen FPS noch die Texte dargestellt.
Ich gehe davon aus, dass die aktuellen FPS nicht gezeichnet werden, weil auch die Zaehlung der FPS durch die Umstellung etwas gelitten hat, daran mache ich mich später.
Aber warum die Texte nicht mehr gehn, weiss ich nicht.

Nun mal zu meinem Fontmanager:
Code:
  1.  
  2. TFontManager = class(TObject)
  3.   private
  4.     FontNames : THashedStringList;
  5.     NumFonts  : Integer;
  6.     FontSizes : Array[0..19] of TFontSizes;
  7.   public
  8.     Fonts     : Array[0..19] of TFont;
  9.  
  10.     constructor Create;
  11.  
  12.     procedure   AddFont       (const FontPath, FontName: string;  Height, R, G, B:Byte; Style: Integer);
  13.     function    GetFontID     (const Name: string): Integer;
  14.  
  15.     function    GetTextHeight (const FontName, Text: string): Integer;
  16.     function    GetTextWidth  (const FontName, Text: string): Integer;
  17.  
  18.     procedure   Draw          (const FontName, Text: string; X, Y: Integer);  overload;
  19.     procedure   Draw          (const FontName, Text: string; X, Y, Z: Single);overload;
  20.     destructor  Destroy;
  21. end;
  22.  
  23. constructor TFontManager.Create();
  24. begin
  25.   try
  26.     inherited Create;
  27.     FontNames := THashedStringList.Create;
  28.     FontNames.CaseSensitive:=FALSE;
  29.  
  30.     NumFonts := 0;
  31.  
  32.     BugTracker.AddBugReport('# TFontManager.Create: FontManager initialized successfully');
  33.   except
  34.     BugTracker.AddBugReport('> TFontManager.Create: Failed to initialize FontManager');
  35.   end;
  36. end;
  37.  
  38. procedure TFontManager.AddFont(const FontPath, FontName: string;  Height, R, G, B:Byte; Style: Integer);
  39. var Color: TSDL_Color;
  40. begin
  41.   if NumFonts <= 19 then
  42.   begin
  43.     if FontNames.IndexOf(FontName)=-1 then //Fontname existiert nicht
  44.     begin
  45.       try
  46.         Color.r := R;
  47.         Color.g := G;
  48.         Color.b := B;
  49.         Color.unused := 0;
  50.  
  51.         Fonts[NumFonts] := TFont.Create(FontPath, Height, Color, Style);
  52.         FontNames.Add(FontName);
  53.         FontSizes[NumFonts] := CalculateFontSizes(Fonts[NumFonts]);
  54.  
  55.         INC(NumFonts);
  56.         if BugTracker <> nil then
  57.           BugTracker.AddBugReport('# TFontManager.AddFont: ' + FontName + ' in ' + FontPath + ' loaded');
  58.       except
  59.         if BugTracker <> nil then
  60.           BugTracker.AddBugReport('> TFontManager.AddFont: Failed to load ' + FontName + ' in ' + FontPath);
  61.       end;
  62.     end
  63.     else
  64.       BugTracker.AddBugReport('> TFontManager.AddFont: ' + FontName + ' exists already');
  65.   end
  66.   else
  67.     if BugTracker <> nil then
  68.       BugTracker.AddBugReport('> TFontManager.AddFont: Exceeded Maximum FontNumber');
  69. end;
  70.  
  71. function TFontManager.GetFontID(const Name: string): Integer;
  72. var Id: Integer;
  73. begin
  74.   Id := FontNames.IndexOf(Name);
  75.   If id = -1 then
  76.   begin
  77.     BugTracker.AddBugReport('> TFontManager.GetFontId: No Font found (Id: '+inttostr(Id));
  78.     Halt;
  79.   end;
  80.   Result := Id;
  81. end;
  82.  
  83. function TFontManager.GetTextHeight(const FontName, Text: string): Integer;
  84. var nHeight, i: Integer;
  85. begin
  86.   nHeight:=0;
  87.   try
  88.     for i:=0 to Length(text)-1 do
  89.     begin
  90.       nHeight := nHeight+FontSizes[FontNames.IndexOf(FontName)][ORD(text[i])].CharHeight;
  91.     end;
  92.     Result:=nHeight;
  93.   except
  94.     Result:=-1;
  95.     BugTracker.AddBugReport('> TFontManager.GetTextHeight: Failed to load ' + FontName);
  96.   end;
  97. end;
  98.  
  99. function TFontManager.GetTextWidth(const FontName, Text: string): Integer;
  100. var nWidth, i: Integer;
  101. begin
  102.   nWidth:=0;
  103.   try
  104.     for i:=0 to Length(text)-1 do
  105.     begin
  106.       nWidth := nWidth+FontSizes[FontNames.IndexOf(FontName)][ORD(text[i])].CharWidth;
  107.     end;
  108.     Result:=nWidth;
  109.   except
  110.     Result:=-1;
  111.     BugTracker.AddBugReport('> TFontManager.GetTextWidth: Failed to load ' + FontName);
  112.   end;
  113. end;
  114.  
  115. procedure TFontManager.Draw(const FontName, Text: string; X, Y: Integer);
  116. begin
  117.   try
  118.     Fonts[FontNames.IndexOf(FontName)].Draw(Text,X,Y);
  119.   except
  120.     BugTracker.AddBugReport('> TFontManager.Draw: Failed to load ' + FontName);
  121.   end;
  122. end;
  123.  
  124. procedure TFontManager.Draw(const FontName, Text: string; X, Y, Z: Single);
  125. begin
  126.   try
  127.     Fonts[FontNames.IndexOf(FontName)].Draw3D(Text,X,Y,Z);
  128.   except
  129.     BugTracker.AddBugReport('> TFontManager.Draw: Failed to load ' + FontName);
  130.   end;
  131. end;
  132.  
  133. destructor TFontManager.Destroy();
  134. var i:Integer;
  135. begin
  136.   try
  137.     FontNames.Free;                
  138.     BugTracker.AddBugReport('# TFontManager.Destroy: FontNames destroyed successfully');
  139.   except
  140.     BugTracker.AddBugReport('> TFontManager.Destroy: Failed to destroy FontNames');
  141.   end;
  142.   try
  143.     for i:=0 to Length(Fonts)-1 do
  144.       Fonts[i].Free;
  145.     BugTracker.AddBugReport('# TFontManager.Destroy: Font destroyed successfully');
  146.   except
  147.     BugTracker.AddBugReport('> TFontManager.Destroy: Failed to destroy Font');
  148.   end;
  149.   BugTracker.AddBugReport('> TEngine.Destroy: FontManager destroyed');
  150.   inherited Destroy;
  151. end;


Initalisierung:
Code:
  1.   FontManager := TFontManager.Create();
  2.   FontManager.AddFont('Fonts/Arial.ttf','FPS',15,$7F,$99,$B2,0);
  3.  


Tja dann sollte der Manager funken und die Schriftart FPS (Arial) sollte verfügbar sein. Das ging bisher immer super so.
Mit den Draws aus meiner Renderfunktion zeichne ich dann die Worte.

Allerdings geht es nichtmehr. Ich habe mal nachgesehen. Wenn ich GetFontId aufrufe, bricht er ab (Halt) also findet er den gesuchten Eintrag in der Stringlist nicht, obwohl das sonst immer ging. Ich habe keine Ahnung, was da schief laeuft.

Danke schonmal im Voraus.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Dez 10, 2006 20:16 
Offline
DGL Member

Registriert: Di Jun 06, 2006 09:59
Beiträge: 474
Mir fallen 2 Schwächen auf, die aber mit deinem Problem nichts zu tun haben:
1. gibt es in Delphi schon eine Klasse TFont, und Namensgleichheiten machen oft Ärger (z.B. TBitmap in Graphics.pas und Windows.pas)
2. Sind deine Fontgrößenfunktionen an der falschen Stelle(Fontmanager und nicht Font) und zusätzlich extrem ineffizient


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Dez 10, 2006 21:38 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Ehm nein die Klassen TFont kommt aus der SDL_Font und deswegen wollte ich sie nicht aendern. Deshalb stehen die groessen auch im Fontmanager.
Wie sollte man ihn denn effizienter machen


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Dez 11, 2006 10:03 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Shaddow hat geschrieben:
Wie sollte man ihn denn effizienter machen

Code:
  1. for i:=0 to Length(text)-1 do
  2. begin
  3.   nHeight := nHeight+FontSizes[FontNames.IndexOf(FontName)][ORD(text[i])].CharHeight;
  4. end;
  5.  

Zum Beispiel den Index des Fonts cachen. Der ändert sich doch nicht bei jedem Zeichen?

Dann wird die Höhe auch falsch berechnet. Die Zeichen stehen doch nicht untereinander, oder? Also Muss man auch nicht Height := Height + Rechnen. Bei der Breite ist das was anderes.

Wie sieht das TFont eigentlich aus? Also was macht CalculateFontSizes. Meine Frage hat folgenden Hintergrund. Wenn du Schrift mit SDL zeichnen lässt. Also einen ganzen Text und nicht jedes einzelne Zeichen dann kann es sein, dass er Kerning auf einige Zeichen anwendet. Wenn du aber alle Zeichen einzeln abprpüfst und zusammenrechnest dann haut das aber nicht, da der Text mitunter wesentlich kleiner sein kann.

Ein Halt in einer Bibliothek ist im übrigen richtig ÜBEL! Auch wenn diese nur bei dir verwendet wird. Sollte GetFontID nicht funktionieren gibt es -1 als Rückgabe und das wars. Damit müssen alle anderen Teile klarkommen. Evtl auch eine Exception aber auf gar keinem Fall darf dort ein Halt vorkommen. Das wurde/wird(?) bei Corba einer Netzwerkbibliothek auch so gemacht. Also falls die etwas finden womit die nicht rechnen machen ein C/C++ close und schawusch. Weg ist die Delphianwendung ohne auch nur ein Wort von sich geben zu können oder dagegen etwas tun zu können. Solche Sachen am Besten gar nicht erst angewöhnen.

Und zum Fehler. So weit ich das beurteilen kann sieht das ganz gut aus. Evtl solltest du dir das was er macht einmal im Debugger ganz genau anschauen. Wobei ich das aber auch schon ein bisschen Komisch finde, dass du 3 Unterschiedliche Listen hast in denen du Daten sammelst die eigentlich alle zusammen gehören. Also würde ich versuchen diese auch zusammen zu halten. Also Record gemacht und Pointer davon in eine TList. Und ich denke nicht, dass der verzicht auf die HashedStringList da so groß ins Gewicht fallen dürfte.

PS: Nur etwas am Rande. Wenn BugTracker auch einmal nicht Assigned sein darf dann solltest du es auch Konsequent immer überprüfen. Teilweise hast du es überprüft dann wieder nicht und dann doch wieder. Und das alles in einer einzelnen Methode. ;-)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Dez 11, 2006 16:29 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Also das hier ist die Calculatesizes:

Code:
  1. function  CalculateFontSizes (Font: TFont): TFontSizes;
  2. var minX, maxX, minY, maxY, advance, nWidth, i: Integer;
  3.     pFont : PTTF_Font;
  4.     FontSize: TFontSizes;
  5. begin
  6.   pFont := TTF_OpenFont(PChar(Font.Name), Font.Height);
  7.   TTF_SetFontStyle(pFont, Font.Style);
  8.  
  9.   for i:=0 to 255 do
  10.   begin
  11.     TTF_GlyphMetrics(pFont, i, minX, maxX, minY, maxY, advance);
  12.     FontSize[i].CharWidth  := maxX-minX;
  13.     FontSize[i].CharHeight := maxY-minY;
  14.   end;
  15.   Result:=FontSize;
  16.   TTF_CloseFont(pFont);
  17. end;


Sie geben ein Array of TFontSizes (record of Charwidth, Charheight: Integer) zurueck. Das Array hat 256 felder, eins fuer jeden Char. Ich habe es deshalb alles einzeln gemacht, weil ich die TFont ja aus der SDL_Font kommt. Da aber ionos das jetz schon in die SDL_Font reingepackt hat, denke ich, kann ich das auch rausmachen, die funktion sollte es ja jetzt geben. Darum mache ich mir ja jetzt grad keine Gedanken, aber mein Prob ist noch nicht behoben und ich habe keine Ahnung, warum.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Dez 11, 2006 17:06 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Okay. Ein Array zurückgeben halte ich für nicht ganz so gut. Besser ist so etwas wenn du für das Array einen Typen definierst und dieses dann als Var Parameter übergibst. Das ist für Delphi untendrunter auch wesentlich einfacher und schneller.

Aber ich dachte mir schon, dass du die Zeichen einzeln betrachtest. Da kann es gut passieren, dass die Schrift auf dem Bildschirm kleiner ist als die die du ausrechnest. Dadurch, dass SDL_ttf nun auch mal Kerning anwendet und dies aber nicht mit rausreichen kann/will.


Zu deinem Fehler. Hast du dir mal angeschaut was ob du da im Debugger evtl etwas findest? Kannst du den Fehler sinnvoll reproduzieren? Das Problem ist, dass es kein offensichtlicher Quellcodefehler ist. Da musst du auch schon selber mal ein bisschen rumprobieren und suchen.

Wir können dir da nur sagen was für Stellen evtl etwas kritisch sind. Und die Verteilung der Daten etc. halte ich persönlich auch für Kritisch. Da würde ich wohl eher etwas anders überlegen. Eben um nicht 3 Stellen haben zu müssen um die Daten zu verwalten. Evtl würde ich da die HashedStringList auch mal gegen eine normale austauschen. Halt Fehler ausschließen. Mehr können wir so für dich nicht tun.

PS: Solltest du es gar nicht hinbekommen können wir uns auch gerne mal den Code anschauen. Aber dazu bräuchten wir den kompletten Code. Du solltest es aber auf jeden Fall selber erst einmal ernsthaft versucht haben.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Dez 11, 2006 21:42 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Hab mir das jetz nochma genau angesehen und bin zu folgendem gekommen:

Der Fehler löst eindeutig in diesem Abschnitt aus:
Code:
  1.   glEnable(GL_TEXTURE_2D);
  2.     with FontManager do
  3.     begin
  4.       Draw('FPS',inttostr(HighestFPS)+' FPS',    FPS_GRAPH_POSITION[2]+5,           FPS_GRAPH_POSITION[5] - Fonts[GetFontId('FPS')].Height);
  5.       Draw('FPS',floattostr(HighestFPS/2)+' FPS',FPS_GRAPH_POSITION[2]+5,           FPS_GRAPH_POSITION[3] + FPS_GRAPH_HEIGHT DIV 2 - GetTextHeight('FPS','FPS') DIV 2);
  6.       Draw('FPS','0 FPS',                        FPS_GRAPH_POSITION[2]+5,           FPS_GRAPH_POSITION[3]);
  7.       Draw('FPS',inttostr(FPS60[59])+' FPS',     FPS_GRAPH_POSITION[0]+5,           FPS_GRAPH_POSITION[1]);
  8.       Draw('FPS',inttostr(Seconds)+' Seconds',   FPS_GRAPH_POSITION[0]+DiffWidth+25,FPS_GRAPH_POSITION[1]);
  9.     end;
  10.   glDisable(GL_TEXTURE_2D);


Der genaue Fehlerpunkt:

Code:
  1. function TFontManager.GetFontID(const Name: string): Integer;
  2. var Id: Integer;
  3. begin
  4.   Id := FontNames.IndexOf(Name);    ShowMessage(inttostr(ID));
  5.   If Id = -1 then
  6.     BugTracker.AddBugReport('> TFontManager.GetFontId: No Font found (Id: '+inttostr(Id));
  7.   Result := Id;
  8. end; // -> An dieser Stelle bricht mein Debugger ab


Wenn ich jetzt Fonts[GetFontId('FPS')].Height rauslasse, dann laeuft er Fehlerfrei durch, allerdings zeigt er dennoch keine Schriften an. Komisch ist auch, dass im GetFontId und im Draw die Fontsid gleich herausgefunden werden, aber beim Draw funkt es, bei der anderen nicht.
Hier mal die Draw:
Code:
  1. procedure TFontManager.Draw(const FontName, Text: string; X, Y: Integer);
  2. begin
  3.   try
  4.     Fonts[FontNames.IndexOf(FontName)].Draw(Text,X,Y);
  5.   except
  6.     BugTracker.AddBugReport('> TFontManager.Draw: Failed to load ' + FontName);
  7.   end;
  8. end;


Wie gesagt löst die Fonts[..].Draw() dann die 2d Funktion Draw aus der EasySDLFonts aus.
Ich verstehe wirklich nicht, warums nun nimmer geht. Habe wie gesagt nur den jetzt funktionierenden Scenenmanager eingefügt.

Ich weiss im grunde auch nicht, was ich euch noch an Quellcode geben soll, denn der gesamte Fontmanager ist ja schon gepostet.
Wie gesagt, so wird er initalisiert und die erste Font reingehaun:
Code:
  1.   FontManager := TFontManager.Create();
  2.   FontManager.AddFont('Fonts/Arial.ttf','FPS',15,$7F,$99,$B2,0);
  3.  


Hoffe mal ihr findet was :) Wenn ich noch irgendwas posten soll, dann sagts ma bitte ^^


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Dez 12, 2006 11:32 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Um mich noch mal zu wiederholen. Der Code sieht optisch so weit okay aus. Ich konnte nichts entdecken was irgendwie nach grobem Fehler schreit. Da der Code eigentlich auch nicht komplex ist denke ich auch mal, dass die Anderen auch nichts finden werden. Das Einzige was ich so jetzt tun kann ist dir mögliche Schwachstellen aufzuzeigen. Was ich teilweise auch schon getan habe. Bzw habe ich dir auch Alternativen vorgeschlagen wie man es sicherer und stabiler gestalten kann.

Schwachstellen:
- Ich halte es für Gefährlich, dass du auf der einen Seite die Methode GetFontID hast aber sonst im Code immer direkt IndexOf aufrufst. Und das dann auch ohne dessen Ergebniss abzuprüfen. Das wird dann direkt als ArrayIndex benutzt. Wenn dann solltest du überall GetFontID benutzen.
- Getrennte Datenhaltung. So etwas sollte immer alles an einer zentralen Stelle gehalten werden. Ich persönlich würde da wohl eine Liste oder Hash benutzen in denen ich Pointer auf Records ablege. Diese Records würden aber alles notwendige enthalten.

Lösungsvorschläge:
- Setz mal an wichtigen Punkten Breakpoints und schaue dir an was wie wo gemacht wird. Und was wie wo zurückgegeben wird. Vor allem in GetFontID. Der Name des Parameters "Name" kann durchaus auch ungünstig gewählt sein. Überprüfe mal genau was zu welchem Zeitpunkt in den Variablen steht.
- Evtl solltest du auch mal zu Begin irgendwo einen Breakpoint hinsetzen und dann mal Zeile für Zeile durchgehen und genau schauen was er macht und wo er als nächstes hinspringt. Der Debugger ist sehr mächtig. Man muss ihn nur benutzen.


Und damit wir uns das mal anschauen können bräuchten wir schon das ganze Projekt. Also mit allen benötigten Dateien. Bilder, Fonts und Bibliotheken die zum Kompilieren notwending sind. Ich habe keine Lust mich hinzusetzen und da erst mal was draus basteln zu müssen. Aber um das auch noch mal loszuwerden. Das Problem sieht in meinen Augen noch nicht wirklich kompliziert aus. Also es gibt durchaus noch schlimmere Probleme.

PS: Habe das mal ins Allgemeine verschoben, da das Problem nichts mit OpenGL zu tun hat.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Dez 12, 2006 20:13 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Ich habe nochma ne weile davor gesessen und deine Vorschlaege umgesetzt. Und dennoch.. es geht nicht

Ich habe jetzt die EasySDLFonts bei mir angepasst (liegt im Ordner bei). Es gibt eine Variable fWidth vom Typ Array[0..255] of Byte.
Auf die kann man nun zugreifen, allerdings hatte ich ja das selbe auch schonmal in den Fontsizes, es ist also im Grunde kein unterschied.

Immernoch bricht er bei mir an dieser Stelle ab:
Code:
  1. function TFontManager.GetFontID(const FontName: string): Integer;
  2. var Id: Integer;
  3. begin
  4.   Id := FontNames.IndexOf(FontName);//ShowMessage(inttostr(ID));// ShowMessage(Fontnames.Names[1]); //  ShowMessage(inttostr(ID));
  5.   If Id = -1 then
  6.     BugTracker.AddBugReport('> TFontManager.GetFontId: No Font found (Id: '+inttostr(Id));
  7.   Result := Id;
  8. end;<------ HIER WIEDER MAL....



Naja hier alle Dateien, die man bruachen kann. http://shaddow89.sh.funpic.de/prob.rar


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Dez 12, 2006 20:41 
Offline
DGL Member

Registriert: Di Jun 06, 2006 09:59
Beiträge: 474
In dieser Funktion kann einzig und allein ein nicht initalisierter Bugtracker oder eine nicht initalisierte Stringlist eine exception auslösen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Dez 13, 2006 09:20 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
So ich habe jetzt nicht mal 5 Minuten an dem Problem gesessen und sofort eine andere nicht funktionierende Stelle gefunden.

Direkt beim Starten der Anwendung erhalte ich eine Exception an Adresse 0. Das liegt daran, dass im TEngine.Create ein TFont erzeugt wird welches einen OpenGL Befehl aufruft, OpenGL aber zu dem Zeitpunkt noch gar nicht erstellt wurde. Nachdem ich die Fonts nach dem Initialisieren erstelle hatte es bei mir funktioniert.

Sollte das nicht der Fehler sein dann wäre es schön, wenn du mir mal sagst was ich dort genau tun muss um diesen fehler zu bekommen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Dez 13, 2006 23:24 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Es darf nich wahr sein ^^ Lossy du bist mein Held. Als ich alle Manager ausgelagert habe, habe ich sie an den Anfang gesetzt, ohne zu bedenken, dass die Teilweise ja OpenGL brauchen. Nu habe ich OpenGL vorher initalisiert und alles funkt vabene


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Dez 14, 2006 09:24 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Und weißt du wie ich das gefunden habe? Ich habe auf das gehört was mir Delphi sagt und habe dann mit dem Debugger Anweisung für Anweisung ausgeführt um zu sehen wo es kracht. Immer wenn es in einer Untermethode gekracht hatte habe ich einen Breakpoint gesetzt und neu gestartet. So lange bis ich in der easySDL angelangt war. Danach gegenmaßnahmen zu finden sollte kein Thema sein, wenn man weiß woran es liegt.

Mit anderen Worten. Das war keineswegs wirklich schwer und du solltest dich definitiv mehr mit dem Debugger beschäftigen. ;-)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jan 02, 2007 20:23 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Und wieder mal ein Problem, das an Kuriositaet seines gleichen sucht...
Ich initalisiere eine Font mit folgendem Aufruf:
Code:
  1. (***** Fonts initilasieren ****************************************************)
  2.   FontManager := TSE_FontManager.Create();
  3.   WriteLn('    -> Init FontManager');
  4.   FontManager.AddFont('Fonts/Arial.ttf','FPS',4,$7F,$99,$B2,0);
  5.   WriteLn('    -> Font added');


Dabei wird der Construktor:
Code:
  1. constructor TSE_FontManager.Create();
  2. begin
  3.   try
  4.     inherited Create;
  5.     FontNames := THashedStringList.Create;
  6.     FontNames.CaseSensitive:=FALSE;
  7.  
  8.     NumFonts := 0;
  9.  
  10.     BugTracker.AddBugReport('# TFontManager.Create: FontManager initialized successfully');
  11.   except
  12.     BugTracker.AddBugReport('> TFontManager.Create: Failed to initialize FontManager');
  13.   end;
  14. end;


und die Methode:
Code:
  1. procedure TSE_FontManager.AddFont(const NFontPath, NFontName: string;  NHeight, NR, NG, NB: UInt8; NStyle: Integer);
  2. var Color: TSDL_Color;
  3. begin
  4.     if FontNames.IndexOf(NFontName)=-1 then //Fontname existiert nicht
  5.     begin
  6.       try
  7.         Color.r := NR;
  8.         Color.g := NG;
  9.         Color.b := NB;
  10.         Color.unused := 0;                      
  11.         FontNames.Add(NFontName);
  12.  
  13.         NumFonts := NumFonts+1;
  14.         SetLength(Fonts,NumFonts);
  15.         Fonts[NumFonts-1] := TFont.Create(NFontPath, NHeight, Color, NStyle);
  16.         WriteLn('Font Erstellt: ('+inttostr(NumFonts-1)+') '+fonts[NumFonts-1].Name);
  17.         if BugTracker <> nil then
  18.           BugTracker.AddBugReport('# TFontManager.AddFont: ' + NFontName + ' in ' + NFontPath + ' loaded');
  19.       except
  20.         if BugTracker <> nil then
  21.           BugTracker.AddBugReport('> TFontManager.AddFont: Failed to load ' + NFontName + ' in ' + NFontPath);
  22.       end;
  23.     end
  24.     else
  25.       BugTracker.AddBugReport('> TFontManager.AddFont: ' + NFontName + ' already exists');
  26. end;

aufgerufen.
Jedwede Überprüfung, ob Fonts[0] danach existiert (zb mit Assigned) führt zu einem positiven Ergebnis. Auch WriteLn innerhalb des AddFonts gibt ordnungsgemaess alle Angaben aus. Der BugTracker meldet ebenfalls keine Fehler. Exceptions gibt es auch keine.

Wenn ich dann folgenden Aufruf starte: FontManager.Draw('FPS','FPS',200,200); wird die Methode:
Code:
  1. procedure TSE_FontManager.Draw(const NFontName, NText: string; NX, NY: Integer);
  2. begin
  3.   try        fonts[0].Draw('hallo',100,200);
  4.     Fonts[GetFontID(NFontName)].Draw(NText,NX,NY);
  5.   except
  6.     BugTracker.AddBugReport('> TFontManager.Draw: Failed to load ' + NFontName);
  7.   end;
  8. end;

aufgerufen. Dieses Fonts[0].Draw ist lediglich ein weiterer Test, doch es wird nichts, wirklich gar nichts gezeichnet.
Das Verwirrendste allerding ist, dass alle Fonts dargestellt werden, sobald ich einen manuellen aufruf im Hauptprogramm starte:
Code:
  1.  
  2. type color: TSDL_Color;
  3.  
  4. color.r := $ff;
  5.   color.g := $ff;
  6.   color.b := $ff;
  7.   color.unused := 0;
  8.   Font1 := tfont.Create('Fonts/Arial.ttf',20,color,0);


Danach benutze ich nicht etwa Font1 sondern weiterhin den oben dargestellten Aufruf FontManager.Draw('FPS','FPS',200,200); und dennoch werden alle Fonts dargestellt. Mir lag der Verdacht nahe, dass das Laden der Font in irgendeiner weise schief laeuft und es beim manuellen Laden dann funktioniert, allerdings laesst ja keine Exception auf etwas derartiges Schliessen...

Ich weiss wirklich nicht, was da schief laeuft, aber gehen tut es einfach nicht...

PS:
Noch eine kurze Nachfrage: Wenn ich im Orthomode die Parameter so aendere, dass OGL auch links oben mit den Pixel bei 0,0 zu zaehlen beginnt, so wie windows es tut, dann werden die Fonts automatisch horizontal gespiegelt. Um das zu umgehen, dachte ich zuerst an ein einfaches glScale(1,-1,1), was leidergottes nicht funktionierte :) Andere Ideen?

Danke schonmal fuer Eure Muehen


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Jun 04, 2007 14:29 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Nachdem ich mich nun nach einiger Abwesenheit, die ich Lineage2 in die Schuhe schieben muss, wieder einmal mit meinem Programm beschäftigt habe, stehe ich nach wie vor vor oben beschriebenem Problem.

Um alle Eventualitaeten auszuräumen, habe ich meinen Fontmanager komplett rausgeschmissen und mich komplett auf die TFont aus der EasySDLfont verlassen.

In meiner SE_Globals wird eine globale Font (zum Testen) erzeugt. Diese Font ist danach in jeder Datei verfügbar, so auch in Startscene.pas, in der ich im Orthomode ein paar Buchstaben ausgebe. Diese Buchstaben werden nur nicht ausgegeben, es sei denn, ich initialisiere die selbe Font direkt in meinem Hauptprogramm nochmal unter der selben Variable.

Im Anhang schicke ich mal alle relevanten Dateien mit. So wie es gerade eingestellt ist, sollte es gehen, tut es aber nicht. Die Font wird in Globals erzeugt und in Scenemanager genutzt. Wenn ihr die Neubelegung in der Unit1.pas wieder reinnehmt (ist derzeit ausgeklammert) dann sieht man sie font.



Ich glaube inzwischen nichtmehr, dass es an meinem Fontmanager gelegen hat, da es ja mit EasySDLFonts auch nicht geht. Wahrscheinlicher ist, dass irgendwo davor oder dahinter im Renderer ein Bug ist.

Hier nochmal meine Erstellung der Font:

Code:
  1.   Color.r:=$FF;
  2.   Color.g:=$8D;
  3.   Color.b:=$1D;
  4.   Color.unused:=0;
  5.  
  6.   Font1 := TFont.Create('Fonts/Arial.ttf', 10, Color, 0);


Der Code im Loop ist zusammengefasst der Folgende:
Code:
  1.   fTimeAtLastUpdate := SDL_GetTicks();
  2.   glMatrixMode(GL_PROJECTION);
  3.   glLoadIdentity;
  4.   gluPerspective(45.0, Camera.Width/Camera.Height, Camera.NearClipping, Camera.FarClipping);
  5.  
  6.   glMatrixMode(GL_MODELVIEW);
  7.   glLoadIdentity;
  8.  
  9.   glClearColor(0,0,0,0);
  10.   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  11.  
  12.   glLoadIdentity;
  13.   glRotatef(Rotation[0],1,0,0);
  14.   glRotatef(Rotation[1],0,1,0);
  15.   glTranslatef(Translation[0],Translation[1],Translation[2]);
  16.  
  17.     EventManager.Loop; {in diesem Fall ja völlig ohne bedeutung, deswegen schreib ich den Code nicht direkt rein, könnt ihr aber nachlesen im Anhang}
  18.  
  19.    Camera.Update; {auch nur relevant wenn ein Move- oder Lookpath der Camera angegeben wurde.}
  20.  
  21.     SceneManager.UpdateScene(Renderer.CurDrawTime);  {In diesem Fall wird hier die StartScene.Update aufgerufen}
  22.     {SceneManager.RenderScene ruft nun die StartScene.Render auf mit dem Folgenden Inhalt:}
  23.  
  24. renderer.OrthoStart;
  25. glEnable(GL_TEXTURE_2D);
  26. font1.Draw('hregfrger',100,100);
  27. glDisable(GL_TEXTURE_2D);
  28. renderer.OrthoStop;
  29.  
  30. {danach kommt die Renderer.Swapbuffers und damit der Schluss}
  31.  
  32.   if KoordSysDraw then
  33.     DrawKoordSys;
  34.  
  35.   if FPSGraphDraw then
  36.   begin
  37.     OrthoStart;
  38.     DrawFPSGraph;
  39.     OrthoStop;
  40.   end;
  41.  
  42.   SDL_GL_SwapBuffers;
  43.  
  44.  


Als Anmerkung zum Anhang: Ich habe die EasySDLFont verändert. Bei mir werden in der TFont noch die Weite jedes Buchstaben gespeichert und alle Fonts werden von vornherein horizontal gespiegelt. Ihr könnt es auch mit euren eigenen EasySDLFonts testen, da sollte bis auf eine Drehung nichts anderes passieren.

Hier nun der Download

Danke schonmal fuer Eure Muehen


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 22 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

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.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.015s | 16 Queries | GZIP : On ]