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.
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.
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
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
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.
TTF_GlyphMetrics(pFont, i, minX, maxX, minY, maxY, advance);
FontSize[i].CharWidth:= maxX-minX;
FontSize[i].CharHeight:= maxY-minY;
end;
Result:=FontSize;
TTF_CloseFont(pFont);
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.
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.
function TFontManager.GetFontID(const Name:string):Integer;
var Id:Integer;
begin
Id := FontNames.IndexOf(Name); ShowMessage(inttostr(ID));
If Id =-1then
BugTracker.AddBugReport('> TFontManager.GetFontId: No Font found (Id: '+inttostr(Id));
Result := Id;
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:
BugTracker.AddBugReport('> TFontManager.Draw: Failed to load '+ FontName);
end;
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:
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.
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:
function TFontManager.GetFontID(const FontName:string):Integer;
var Id:Integer;
begin
Id := FontNames.IndexOf(FontName);//ShowMessage(inttostr(ID));// ShowMessage(Fontnames.Names[1]); // ShowMessage(inttostr(ID));
If Id =-1then
BugTracker.AddBugReport('> TFontManager.GetFontId: No Font found (Id: '+inttostr(Id));
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.
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
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.
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:
BugTracker.AddBugReport('> TFontManager.Draw: Failed to load '+ NFontName);
end;
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:
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?
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.
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}
Camera.Update;{auch nur relevant wenn ein Move- oder Lookpath der Camera angegeben wurde.}
SceneManager.UpdateScene(Renderer.CurDrawTime);{In diesem Fall wird hier die StartScene.Update aufgerufen}
{SceneManager.RenderScene ruft nun die StartScene.Render auf mit dem Folgenden Inhalt:}
renderer.OrthoStart;
glEnable(GL_TEXTURE_2D);
font1.Draw('hregfrger',100,100);
glDisable(GL_TEXTURE_2D);
renderer.OrthoStop;
{danach kommt die Renderer.Swapbuffers und damit der Schluss}
if KoordSysDraw then
DrawKoordSys;
if FPSGraphDraw then
begin
OrthoStart;
DrawFPSGraph;
OrthoStop;
end;
SDL_GL_SwapBuffers;
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.
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.