Bilder als Ressourcen: Unterschied zwischen den Versionen
Flash (Diskussion | Beiträge) K (→Nachwort) |
K (Resource -> Ressource (Außer im Englischen Quelltext)) |
||
(4 dazwischenliegende Versionen von 4 Benutzern werden nicht angezeigt) | |||
Zeile 17: | Zeile 17: | ||
===einfach und schnell=== | ===einfach und schnell=== | ||
− | Man benutzt das Programm "PE | + | Man benutzt das Programm "PE Ressource Explorer", mit welchem man sich recht bequem seine Ressourcen zusammen klicken kann. (Download: http://www.wilsonc.demon.co.uk/d10ressourceeditor.htm) |
===selber tippen=== | ===selber tippen=== | ||
Die andere Möglichkeit ist etwas mehr Arbeit: Also schnappst du dir Notepad oder sonst irgendeinen Editor und erstellst eine Datei mit folgendem Format:<br> | Die andere Möglichkeit ist etwas mehr Arbeit: Also schnappst du dir Notepad oder sonst irgendeinen Editor und erstellst eine Datei mit folgendem Format:<br> | ||
− | <Ressourcenbezeichner> < | + | <Ressourcenbezeichner> <Ressourcentyp> <Pfad zur Datei><br> |
beispielsweise:<br> | beispielsweise:<br> | ||
myCharTex BITMAP char.tga<br> | myCharTex BITMAP char.tga<br> | ||
Zeile 46: | Zeile 46: | ||
==...und einbinden== | ==...und einbinden== | ||
− | Soweit so gut, wir haben die | + | Soweit so gut, wir haben die Ressourcen alle in einer .res Datei und binden diese mit {$R lemon.RES} in unser Programm ein...<br> |
− | HA! Wenn man die .res Datei in das Hauptprojekt eingebunden hätte, wäre sie beim compilieren mit in die .exe hineinkompiliert | + | HA! Wenn man die .res Datei in das Hauptprojekt eingebunden hätte, wäre sie beim compilieren mit in die .exe hineinkompiliert worden.<br> |
Weil wir das aber nicht wollen, gehen wir her und erstellen in Delphi ein neues DLL Projekt.<br> | Weil wir das aber nicht wollen, gehen wir her und erstellen in Delphi ein neues DLL Projekt.<br> | ||
Den vorgeschriebenen Quelltext ersetzen wir mit:<br> | Den vorgeschriebenen Quelltext ersetzen wir mit:<br> | ||
− | <pascal> | + | <source lang="pascal"> |
library lemon; | library lemon; | ||
Zeile 57: | Zeile 57: | ||
begin | begin | ||
end. | end. | ||
− | </ | + | </source> |
wobei der Name der Library und "lemon.RES" natürlich auf eure Bedürfnisse angepasst werden sollte.<br> | wobei der Name der Library und "lemon.RES" natürlich auf eure Bedürfnisse angepasst werden sollte.<br> | ||
− | Wunderbar, jetzt speichern wir das Projekt, compilieren es und der ein oder andere kann auch "Hosianna" rufen, denn jetzt haben wir eine wunderschöne .dll Datei, die all unsere | + | Wunderbar, jetzt speichern wir das Projekt, compilieren es und der ein oder andere kann auch "Hosianna" rufen, denn jetzt haben wir eine wunderschöne .dll Datei, die all unsere Ressourcen enthält. Und ich denke, jeder gewöhnliche Wald und Wiesen Depp, wird sich denken "Möh? DLL - Wasn datt da? Kann man das essen?? Lass ich mal lieber in Ruhe"<br> |
Hehe, aber wir sind noch nicht am Ziel... wir müssen die Daten ja auch wieder aus der DLL rausbekommen. | Hehe, aber wir sind noch nicht am Ziel... wir müssen die Daten ja auch wieder aus der DLL rausbekommen. | ||
− | |||
==Ressourcen laden== | ==Ressourcen laden== | ||
Zeile 67: | Zeile 66: | ||
Erstmal brauchen wir eine Variable vom Typen Papst ääh, Cardinal.<br> | Erstmal brauchen wir eine Variable vom Typen Papst ääh, Cardinal.<br> | ||
Der weisen wir mittels<br> | Der weisen wir mittels<br> | ||
− | <pascal> | + | <source lang="pascal"> |
var h: cardinal; | var h: cardinal; | ||
h := LoadLibrary('lemon.dll'); | h := LoadLibrary('lemon.dll'); | ||
− | </ | + | </source> |
die eben erstelle DLL Datei zu.<br> | die eben erstelle DLL Datei zu.<br> | ||
Wenn man jetzt in LoadFromRessource oder ähnlichen Funktionen als Parameter eine Instance angeben sollst, ist das unsere Cardinal Variable, die ja auf die DLL zeigt.<br> | Wenn man jetzt in LoadFromRessource oder ähnlichen Funktionen als Parameter eine Instance angeben sollst, ist das unsere Cardinal Variable, die ja auf die DLL zeigt.<br> | ||
Bei der glBitmap.pas laden wir allerdings immer aus Streams - und zwar so:<br> | Bei der glBitmap.pas laden wir allerdings immer aus Streams - und zwar so:<br> | ||
− | <pascal> | + | <source lang="pascal"> |
var myStream: TResourceStream | var myStream: TResourceStream | ||
var h: Cardinal; | var h: Cardinal; | ||
var foo: TglBitmap2D; | var foo: TglBitmap2D; | ||
+ | // DLL Laden | ||
h := LoadLibrary('lemon.dll'); | h := LoadLibrary('lemon.dll'); | ||
+ | |||
+ | // Texturklasse erstellen | ||
+ | foo := TglBitmap2D.Create; | ||
+ | |||
+ | // Stream auf eine Ressource erstellen | ||
myStream := TResourceStream.CreateFromID(h, 10, RT_RCDATA); | myStream := TResourceStream.CreateFromID(h, 10, RT_RCDATA); | ||
− | foo.LoadFromStream(myStream); | + | try |
+ | // Bild aus Stream laden | ||
+ | foo.LoadFromStream(myStream); | ||
+ | finally | ||
+ | // Stream in jedem Falle wieder frei geben | ||
+ | myStream.Free; | ||
+ | end; | ||
+ | |||
+ | // OpenGL Textur erstellen | ||
foo.GenTexture; | foo.GenTexture; | ||
− | </ | + | |
− | damit würden wir aus der Datei lemon.dll eine RCDATA | + | // DLL Wieder entladen wenn sie nicht mehr gebraucht wird |
+ | FreeLibrary(h); | ||
+ | </source> | ||
+ | damit würden wir aus der Datei lemon.dll eine RCDATA Ressource mit dem Bezeichner 10 laden.<br> | ||
Wenn man den Ressourcen String-Namen gegeben hat, benutzt man "Create" statt "CreateFromId" und gibt den String an. | Wenn man den Ressourcen String-Namen gegeben hat, benutzt man "Create" statt "CreateFromId" und gibt den String an. | ||
Zeile 91: | Zeile 107: | ||
Abgesehen davon hoffe ich, dass ich an dieser Stelle Lossy eX für Geduld und Wissen danken darf :)<br> | Abgesehen davon hoffe ich, dass ich an dieser Stelle Lossy eX für Geduld und Wissen danken darf :)<br> | ||
Ciao | Ciao | ||
+ | |||
+ | [[Benutzer:Doppelreim|Doppelreim]] | ||
[[Kategorie:Anleitung|Bilder in Ressourcen]] | [[Kategorie:Anleitung|Bilder in Ressourcen]] |
Aktuelle Version vom 21. März 2012, 15:25 Uhr
Inhaltsverzeichnis
Vorwort
Eins vorneweg: Da ich noch OpenGL-Frischling bin, sollten die in diesem Artikel beschriebenen Methoden zwar funktionieren, jedoch bin ich fast der Überzeugung, dass sie Speicher- sowie Performancetechnisch eher miserabel sind...
Einleitung
Man kann Bilder (und auch jeglichen anderen Daten) beispielsweise in Ressourcen-Dateien packen,
um die .exe möglichst klein zu halten.
Oder aber man freut sich, wenn man immer alle Grafiken in einer Datei zusammen hat.
Oder man verwendet Ressourcen-Dateien, damit "net jeder Wald und Wiesendepp mit Paint die Grafiken verunstalten kann" (Zitat Flash)
Warum auch immer man sich für Ressourcen-Dateien entscheiden sollte, die Herangehensweise ist die selbe - nämlich folgende:
.RES Datei Erstellen...
Als erstes nehmen wir alle Grafiken, die wir brauchen, und packen sie in eine .res Datei.
"packen" weckt hier möglicherweise falsche Hoffnungen, denn die Daten werden dadurch nicht komprimiert, sie kommen bloß alle zusammen in eine Datei.
Um eine solche .res Datei zu erschaffen gibt es mehrere Wege - hier sind zwei:
einfach und schnell
Man benutzt das Programm "PE Ressource Explorer", mit welchem man sich recht bequem seine Ressourcen zusammen klicken kann. (Download: http://www.wilsonc.demon.co.uk/d10ressourceeditor.htm)
selber tippen
Die andere Möglichkeit ist etwas mehr Arbeit: Also schnappst du dir Notepad oder sonst irgendeinen Editor und erstellst eine Datei mit folgendem Format:
<Ressourcenbezeichner> <Ressourcentyp> <Pfad zur Datei>
beispielsweise:
myCharTex BITMAP char.tga
- Ressourcenbezeichner: ist der Name, den du der Ressource gibst. Statt einem String kannst du auch ne Zahl hinschreiben, also:
- 10 BITMAP holla.bmp
- Muss man selber wissen, ob man lieber mit Strings oder Integers als Bezeichner arbeitet, hat bestimmt beides Vorzüge...
- Ressourcentyp: Es gibt einige vordefinierte Typen (für Bitmaps, Jpgs, Cursor, Icon, usw)
- Für alle Sachen, die nicht explizit nen eigenen Typ haben gibt es RCDATA
- Das wär dann wohl allgemeine Datenvielfalt, oder so...
- Pfad zur Datei: ist selbsterklärend denke ich.
- Kann sein, dass man Gänsefüsschen setzen muss, keine Ahnung - testen!
Jetzt hast du im Editor zeilenweise deine Ressourcen angegeben und speicherst das Werk erstmal als Datei mit der Endung ".rc" ab.
Dann gibt es in deinem Delphi Verzeichnis einen Ordner "bin" und in selbigem eine Datei brcc32.exe - die brauchen wir jetzt.
Die .rc Datei enthält ja nur die Dateinamen zu den Ressourcen die du haben willst. brcc32.exe nimmt sich diese Datei und packt die darin angegebenen Ressourcen in eine .res Datei.
Dazu ruft man die brcc32 in der Kommandozeile auf und übergibt als Parameter den Pfad zur .rc Datei
Ipp Zipp Zapp, fertig ist die .res Datei
Dieser zweite Weg ist zwar unter Umständen mehr Arbeit, aber dafür hat man dann auch n bisschen Hintergrundwissen abbekommen - kann ja nicht schaden.
...und einbinden
Soweit so gut, wir haben die Ressourcen alle in einer .res Datei und binden diese mit {$R lemon.RES} in unser Programm ein...
HA! Wenn man die .res Datei in das Hauptprojekt eingebunden hätte, wäre sie beim compilieren mit in die .exe hineinkompiliert worden.
Weil wir das aber nicht wollen, gehen wir her und erstellen in Delphi ein neues DLL Projekt.
Den vorgeschriebenen Quelltext ersetzen wir mit:
library lemon;
{$R lemon.RES}
begin
end.
wobei der Name der Library und "lemon.RES" natürlich auf eure Bedürfnisse angepasst werden sollte.
Wunderbar, jetzt speichern wir das Projekt, compilieren es und der ein oder andere kann auch "Hosianna" rufen, denn jetzt haben wir eine wunderschöne .dll Datei, die all unsere Ressourcen enthält. Und ich denke, jeder gewöhnliche Wald und Wiesen Depp, wird sich denken "Möh? DLL - Wasn datt da? Kann man das essen?? Lass ich mal lieber in Ruhe"
Hehe, aber wir sind noch nicht am Ziel... wir müssen die Daten ja auch wieder aus der DLL rausbekommen.
Ressourcen laden
Zurück in der Hauptanwendung gehen wir folgendermaßen vor:
Erstmal brauchen wir eine Variable vom Typen Papst ääh, Cardinal.
Der weisen wir mittels
var h: cardinal;
h := LoadLibrary('lemon.dll');
die eben erstelle DLL Datei zu.
Wenn man jetzt in LoadFromRessource oder ähnlichen Funktionen als Parameter eine Instance angeben sollst, ist das unsere Cardinal Variable, die ja auf die DLL zeigt.
Bei der glBitmap.pas laden wir allerdings immer aus Streams - und zwar so:
var myStream: TResourceStream
var h: Cardinal;
var foo: TglBitmap2D;
// DLL Laden
h := LoadLibrary('lemon.dll');
// Texturklasse erstellen
foo := TglBitmap2D.Create;
// Stream auf eine Ressource erstellen
myStream := TResourceStream.CreateFromID(h, 10, RT_RCDATA);
try
// Bild aus Stream laden
foo.LoadFromStream(myStream);
finally
// Stream in jedem Falle wieder frei geben
myStream.Free;
end;
// OpenGL Textur erstellen
foo.GenTexture;
// DLL Wieder entladen wenn sie nicht mehr gebraucht wird
FreeLibrary(h);
damit würden wir aus der Datei lemon.dll eine RCDATA Ressource mit dem Bezeichner 10 laden.
Wenn man den Ressourcen String-Namen gegeben hat, benutzt man "Create" statt "CreateFromId" und gibt den String an.
Nachwort
Sohohohoho, ich hoffe, ich habe alles Erwähneswerte erwähnt und wenn es jemandem hilft, dann bin ich mächtig stolz, auch mal ne Antwort gegeben zu haben, statt immer nur zu Fragen.
Abgesehen davon hoffe ich, dass ich an dieser Stelle Lossy eX für Geduld und Wissen danken darf :)
Ciao