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

Aktuelle Zeit: Sa Jul 05, 2025 19:39

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



Ein neues Thema erstellen Auf das Thema antworten  [ 12 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Laden der Textur funktioniert nicht.
BeitragVerfasst: Do Okt 09, 2008 08:11 
Offline
DGL Member

Registriert: Mi Okt 08, 2008 14:00
Beiträge: 8
Hallo!

Ich möchte eine Primitive texturieren, allerdings bekomme ich es einfach nicht hin. Ich verwende die glBitmap-Library und möchte eine TGA-Datei laden, nur leider wird sie nicht korrekt geladen bzw. die Textur-ID bleibt 0. An den Einstellungen der glBitmap habe ich nichts verändert außer der Aktivierung der TBitmap-Unterstützung, allerdings funktioniert es so oder so nicht.

Hier mein Code zum Laden der Textur:
Code:
  1. var
  2.   texture: TglBitmap2D;
  3.  
  4. begin
  5.   // Die Textur wurde mit GIMP erzeugt, keine RLE Kompression
  6.   // und auch kein Ursprung links unten.
  7.   texture := TglBitmap2D.Create('C:\test.tga');
  8.   texture.GenTexture;
  9.  
  10.   MessageBox(0, PChar('Texture generated! ID: ' + IntToStr(texture.ID)),
  11.     'Information', MB_OK or MB_ICONINFORMATION);
  12. end;


Die Textur wird kurz vor dem Aufruf von SwapBuffers durchgeführt, ich hoffe, das beeinflusst das Laden nicht. Müssen irgendwelche OpenGL-Parameter eingestellt werden, sodass Texturen geladen werden können?

Was noch interessant ist: Um zu testen, ob die Textur richtig erkannt bzw. geladen wird, habe ich in die Prozedur TglBitmap2D.GenTexture einen MessageBox-Aufruf hinzugefügt, um die aktuelle Texturgröße und die maximale Texturgröße anzeigen zu lassen. Auf diese Weise kommt nur eine Textur-ID mit 0. Lasse ich diesen Aufruf allerdings weg, so wird eine Exception geworfen.

Könnt ihr mir helfen?

mfg oli


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Okt 09, 2008 09:19 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Hallo Oli und willkommen im Forum.

Für TGA Dateien brauchst du in der glBitmap gar keine Einstellungen vornehmen. Diese werden hoffentlich vollständig unterstützt. Sowohl RLE als auch ein Ursprung der sich unten links befindet. Wenn es da also beim Laden der Textur nicht zu einem Fehler kommt sollte die Textur zu mindest anständig geladen worden sein. Bei OpenGL brauchst du in der Regel auch nichts weiter einstellen.

Eine MessageBox wärend dem Laden anzuzeigen kann mitunter andere Seiteneffekt auslösen. Zum Beispiel könnte es sein, dass du im OnPaint des Formulars zeichnest etc. Dann führt unter anderem das Anzeigen einer Meldung zu fehlern. Da solltest du in Zukunft lieber einen Haltepunkt an die Codestelle setzten und mit dem Debugger dir die Werte anschauen.

Das Laden und Erstellen der Textur solltest du nicht wärend dem Rendern erledigen sondern nach dem Erstellen und Aktivieren des Renderkontextes (Initialisierung von OpenGL). Wärend dem Rendern kann so etwas schon ziemlich extrem an der Geschwindigkeit nagen.

Warum die Textur ID 0 ist kann ich nicht mit Bestimmtheit sagen. Habe aber eine Theorie. Denn normal sollte alleine das Erstellen der ID (leeres Texturobject seitens OpenGL) keine Probleme verursachen. Üblicherweise ist erst das Hochladen der Daten problematisch. Es kommt auch noch hinzu, dass ich nicht abschätzen kann an welcher Stelle du die MessageBox in die Methode GenTexture eingefügt hast. Wenn das zu früh war, dann kann es natürlich sein, dass noch gar keine Textur ID erstellt wurde.

Mich würde auch mal interessieren was für einen Fehler du bei GenTextures bekommen hast. Bei Fehlern ist es immer gut mit anzugeben was das für einer war. Erleichtert das Suchen. Wenn das so etwas wie "AccessViolation an Adresse 0x00000000" war, dann hast du vermutlich die Aktivierung der dglOpenGL.pas in der glBitmap aktiviert und die Reihenfolge nicht ganz beachtet. Da wäre es dann wichtig wie du OpenGL initialisiert hast und wo du die Textur geladen hast. Wichtig. Erst nach der Initialisierung von OpenGL darf GenTexture aufgerufen werden.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Okt 09, 2008 10:23 
Offline
DGL Member

Registriert: Mi Okt 08, 2008 14:00
Beiträge: 8
Lossy eX hat geschrieben:
Hallo Oli und willkommen im Forum.

Danke für die nette Begrüßung ;)

Lossy eX hat geschrieben:
Für TGA Dateien brauchst du in der glBitmap gar keine Einstellungen vornehmen. Diese werden hoffentlich vollständig unterstützt. Sowohl RLE als auch ein Ursprung der sich unten links befindet. Wenn es da also beim Laden der Textur nicht zu einem Fehler kommt sollte die Textur zu mindest anständig geladen worden sein. Bei OpenGL brauchst du in der Regel auch nichts weiter einstellen.

Das sehe ich genauso, denn die richtige Größe kann ich mir anzeigen lassen.

Lossy eX hat geschrieben:
Eine MessageBox wärend dem Laden anzuzeigen kann mitunter andere Seiteneffekt auslösen. Zum Beispiel könnte es sein, dass du im OnPaint des Formulars zeichnest etc. Dann führt unter anderem das Anzeigen einer Meldung zu fehlern. Da solltest du in Zukunft lieber einen Haltepunkt an die Codestelle setzten und mit dem Debugger dir die Werte anschauen.

Das ist leider ein wenig komplizierter: Ob das Zeichnen im OnPaint eines Formulars oder woanders ausgeführt wird, weiß ich nicht. Mit Debugging kenne ich mich bestens aus, aber einen Haltepunkt kann ich leider nicht setzen.
Der Grund hierfür ist, dass meine Anwendung eigentlich eine injizierte DLL (auf einen anderem Rechner, auf dem ich nichts installieren darf) ist und ich daher den Debugger nicht verwenden kann.

Lossy eX hat geschrieben:
Das Laden und Erstellen der Textur solltest du nicht wärend dem Rendern erledigen sondern nach dem Erstellen und Aktivieren des Renderkontextes (Initialisierung von OpenGL). Wärend dem Rendern kann so etwas schon ziemlich extrem an der Geschwindigkeit nagen.

Da meine DLL auf einem API-Hook der SwapBuffers-Funktion aufbaut und sie nicht unbedingt zur Ladezeit der Anwendung selbst injiziert wird, bleibt mir nichts anders als eben diese SwapBuffers-Funktion übrig, um meinen Quellcode ausführen zu lassen. Allerdings kann ich dich beruhigen, ich lade die Textur nur einmal ;)

Lossy eX hat geschrieben:
Warum die Textur ID 0 ist kann ich nicht mit Bestimmtheit sagen. Habe aber eine Theorie. Denn normal sollte alleine das Erstellen der ID (leeres Texturobject seitens OpenGL) keine Probleme verursachen. Üblicherweise ist erst das Hochladen der Daten problematisch. Es kommt auch noch hinzu, dass ich nicht abschätzen kann an welcher Stelle du die MessageBox in die Methode GenTexture eingefügt hast. Wenn das zu früh war, dann kann es natürlich sein, dass noch gar keine Textur ID erstellt wurde.

Die MessageBox wird erst nach dem Aufruf der TglBitmap2D.GenTexture-Methode angezeigt (siehe Quellcode weiter oben).

Lossy eX hat geschrieben:
Mich würde auch mal interessieren was für einen Fehler du bei GenTextures bekommen hast. Bei Fehlern ist es immer gut mit anzugeben was das für einer war. Erleichtert das Suchen. Wenn das so etwas wie "AccessViolation an Adresse 0x00000000" war, dann hast du vermutlich die Aktivierung der dglOpenGL.pas in der glBitmap aktiviert und die Reihenfolge nicht ganz beachtet. Da wäre es dann wichtig wie du OpenGL initialisiert hast und wo du die Textur geladen hast. Wichtig. Erst nach der Initialisierung von OpenGL darf GenTexture aufgerufen werden.

Ich arbeite mit der normalen OpenGL.pas, ich kann aber mal versuchen, die dglOpenGl.pas zu verwenden. Inzwischen weißt du, dass OpenGL schon längst initialisiert wurde, also erübrigt sich das.
Der Fehler der ausgelöst wird, ist von dir selbst, nämlich, dass die Textur zu groß wäre und eventuell nicht unterstützt wird. Wenn ich mir die Werte der drei relevanten Variablen (Height, Width, TexSize) allerdings vorher über eine MessageBox anzeigen lasse, so ist TexSize weit größer als die Größe der Textur (> 100.000).

So, jetzt noch zu meinen "Errungenschaften" bis jetzt: Es scheint ein Problem mit den von dir nachgeladenen OpenGL-Funktionen zu geben. Ich habe die glGenTextures (die durch die OpenGL.pas anscheinend nicht geladen wird) getestet und dabei gemerkt, dass sie den Wert der Variablen, die man ihr übergibt, nicht verändert! Wodurch sich dann auch sehr einfach die ID von 0 erklären lässt, das Problem allerdings noch schwerwiegender macht ;-)
Ähnlich scheint es mit der Funktion glGetIntegerv zu sein, die eher eine Speicheradresse oder so anstatt des gefragten Werts (GL_MAX_TEXTURE_SIZE) zurückliefert.

Vermutlich ergibt sich dieses Problem durch den Umstand, dass ich eine injizierte DLL verwende, nur mir bleibt leider nichts anderes übrig. Interessant ist, dass die normalen Funktionen, die in der OpenGL.pas definiert sind, problemlos zu arbeiten scheinen (mit ihnen habe ich bis jetzt farbige Polygone sowie Text unter Verwendung der Methode wglUseFontBitmaps rendern lassen).

Hoffentlich kannst du mit den Infos, die ich dir jetzt gegeben habe, etwas anfangen ;)

mfg oli

PS: Um das gleich im Vorhinein zu klären: Ich schreibe mir kein verbessertes HUD für ein Spiel oder so. Ich arbeite in einem Institut, dass einen Fahrsimulator besitzt. Da dieser allerdings softwaremäßig relativ schlecht ist, programmiere ich gerade ein Programm, das es erlaubt, 2D Elemente wie Text und sowohl farbige als auch texturierte Polygone dazuzuzeichnen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Okt 09, 2008 15:36 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Aha. Da kommen wir der Sache doch ein bisschen näher. ;) Als erstes einmal. Hooks sind wirklich extrem empfindlich. Ich hatte vor einer Weile selber mal einen OpenGL Hook gebastelt (ich benutze überwiegend anderen Code). Dort war es mir allerdings selber auch nicht möglich irgendwelche Eigenschaften von OpenGL zu erfragen. Ich hatte das aber auch nicht weiter ausprobiert. Ich meine aber ich hätte das vor einigen Monaten noch mal in der Hand gehabt und dann hätte es dann geklappt. Obwohl ich so am Code glaube ich nichts oder nur unwichtige Sachen geändert hatte.

Ich kann ja heute abend zu Hause noch mal schauen ob ich in meinen Gedanken da richtig liege. Das Sample finde unter folgendem Link.
http://files.opengl24.de/projects/ApiHook.zip 260KB


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Okt 10, 2008 12:25 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Bin gestern leider nicht dazu gekommen das zu Hause mal zu testen. Allerdings hier läuft es. Ich konnte auch eine Textur laden und anzeigen. Der Code ist bis auf eine Kleinigkeit auch gleich zu dem was sich auf meiner Webseite befindet.

Das Eingige was ich da noch mache ist das Sender der Message WM_NULL an alle Fenster (HWND_BROADCAST), nachdem ich den Hook installiert bzw deinstalliert habe. Das scheint das Installieren und Deinstallieren des Hooks zu verbessern. Sonst könnte es passieren, dass die Fenster erst nach einer Benutzeraktion eine Reaktion auf den Hook zeigen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Okt 10, 2008 18:39 
Offline
DGL Member

Registriert: Mi Okt 08, 2008 14:00
Beiträge: 8
Hallo!

Auf diesen Code bin ich auch schon mal gestoßen, habe mich dann allerdings für die uallCollection entschieden. Da mein API Hook auch funktioniert, sollte das im Grunde ja nichts ändern, allerdings werde ich mir den Code nochmal genau anschauen ;) Kannst du mir vielleicht deinen Test schicken, in dem es dir möglich war, eine Textur zu erzeugen und anzeigen zu lassen? Bin gespannt, ob es auch mit meiner Anwendung zusammen funktioniert oder sie vielleicht an dem Ganzen Schuld ist und ich eh nichts machen kann.

Jedenfalls vielen vielen Dank schon mal für die großartige Hilfe bis jetzt!
mfg oli


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Okt 11, 2008 21:22 
Offline
DGL Member

Registriert: Di Jun 06, 2006 09:59
Beiträge: 474
Zum laden der dll gibt es mehrere Methoden. Unter NT ist CreateRemoteThread IMO to günstigste.
Zum hooken selbst gibt es ebenfalls eine reihe an Möglichkeiten.
1. Die "import address table" (IAT) patchen
2. Die "export address table" (EAT) patchen
3. Die api funktion selbst überschreiben
Bei IAT patches musst du zusätzlich noch GetProcAddress falls funktionen dynamisch geladen werden hooken.
Falls im projekt anwendbar sind IAT patches meist das günstigste.
Die hooks sind dann recht stabil und es ist sehr einfach die ursprüngliche funktion im rahmen der eigenen funktion aufzurufen. Ich würde dir außerdem raten deine gesamte hook funktion in einen try except block zu packen und die exception zu loggen da exceptions die das modul verlassen ungünstig sind.

_________________
Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Okt 11, 2008 22:39 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Um eines vor weg zu sagen. Ich benutze dort lediglich einen Code (von toms. glaube aus der DP) und weiß ehrlich nicht genau was dort gemacht wird. Das war nur als Test/kleine Spielerei gedacht. Ich meine aber, dass dort die Import Table verändert wird. Denn dynamisch geladene Funktionen werden ignoriert.

Ich habe auf meiner Webseite das Beispiel mit meinen Änderungen noch mal aktualisiert (ApiHook.zip). Zusätzlich dazu gibt es ein Zweites (ApiHook_texture.zip). Da ist aber nur in der Zeichenroutine etwas anders. Das dort enthaltene Bild muss sich in dem obersten Verzeichniss befinden wo sich auch die Anwenung befindet. Also auf dem gleichen Laufwerk.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Okt 13, 2008 11:39 
Offline
DGL Member

Registriert: Mi Okt 08, 2008 14:00
Beiträge: 8
Hi!

Also der Fehler liegt auf jeden Fall beim Injizieren der DLL.

Bis jetzt mache ich bzw. die uallCollection das durch CreateRemoteThread. Die Funktion glGenTextures liefert in dieser Variante keine Textur-IDs zurück, sondern belässt die Werte, so wie sie sind. Dies ist glaube ich auch dann der Fall, wenn OpenGL nicht initialisiert worden ist.

Verwende ich einen globalen Windows-Hook, so kommt das einer DLL-Injizierung sehr nahe, doch interessanterweise funktioniert es auf einmal, sprich die selbe DLL macht plötzlich das, was sie soll.

Und wo ist nun mein Problem? Tja, die Anwendung, für die ich die DLL schreibe, besitzt offensichtlich keine Message-Queue und der Windows-Hook greift nicht (selbiges gilt für andere Hooks).

Also, was mache ich? :?

Lg oli


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Okt 13, 2008 12:48 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Der Grund, warum das ganze mit CreateRemoteThread nicht funktioniert dürfte darin liegen, dass der OpenGL-Kontext Threadbezogen ist. Das bedeutet, dass du nur auf den Kontext zugreifen kannst, wenn er im gleichen Thread erstellt wurde.

Ich habe mich auch mal mit Hooking befasst (genaugenommen in den letzten paar tagen) und bin im zusammenhang mit Threads auch immer auf probleme gestoßen. Dazu kommt, dass dynamisch geladene Funktionspointer auch nicht ersetzt werden können. Wenn deine Anwendung also die Funktion, die du hookst dynamisch, also zur Laufzeit, nachlädt, kannst du da nicht viel machen.

Gruß Lord Horazont

_________________
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:
BeitragVerfasst: Mo Okt 13, 2008 16:10 
Offline
DGL Member

Registriert: Mi Okt 08, 2008 14:00
Beiträge: 8
Wenn das so ist, dann muss ich eigentlich in der gehookten SwapBuffers Funktion die Texturen erzeugen oder sehe ich das falsch? Bisher wird das nämlich in einem anderen Thread meiner DLL erledigt. Werde ich morgen gleich ausprobieren und ich hoffe sehr, dass das auch klappt! Und natürlich berichte ich euch davon dann ;) (und erbitte vielleicht noch mehr Hilfe :P)

Schon mal vielen Dank,
Lg oli


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Okt 14, 2008 08:48 
Offline
DGL Member

Registriert: Mi Okt 08, 2008 14:00
Beiträge: 8
Hallo!

Ich danke euch vielmals für eure Hilfe und speziell bedanke ich mich bei Lord Horazont, der mir den entscheidenden Hinweis gegeben hat, dass der OpenGL-Kontext threadbezogen ist. Wenn ich nun die glGenTextures-Methode in der gehookten SwapBuffers-Funktion aufrufe, so funktioniert es wunderbar und ich kann die Texturen anzeigen lassen!

Außerdem vielen Dank an Lossy eX, du hast diesen Thread so lange verfolgt ;)

Lg oli


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 13 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:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.008s | 14 Queries | GZIP : On ]