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

Aktuelle Zeit: Mi Jul 09, 2025 23:02

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: Alphamasking ?!
BeitragVerfasst: Di Nov 25, 2003 09:13 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 17, 2003 09:07
Beiträge: 24
Wohnort: Regensburg
Hi Leute,

es ist fast schon peinlich, weils für´s Maskieren und Blenden ein Tutorial gibt, und die Sache wirklich primitiv ist, aber ich kriegs leider wirklich nicht hin, und zwar folgendes:

(Im Orthomodus - spielt aber keine Rolle...)

Ich möchte ein QUAD mit einen Stern drauf (Textur), so über meinen Hintergrund (Ein bildschirmfüllender QUAD mit einer Galaxie-Textur) malen, daß der Stern sichtbar ist, aber die in der Stern-Textur vorkommenden schwarzen Stellen aber durchsichtig sind und der Hintergrund (die Galaxie) durchscheint.
Theoretisch (so dachte ich zumindest) brauche ich also 3 Texturen

- den Stern
- die Alphamaske des Sterns
- die Hintergrundtextur

Im Tutorial wird einfach Multitexturing benutzt, aber hier erscheint es etwas unpraktisch... vernünftiger scheint mir Colorkeying zu sein, aber ich hab (noch) keine Ahnung wie das unter OpenGL wirklich so funzt...

Wäre echt dankbar, wenn mir das (nochmal) einer erkärt (so für Doofe zum Mitschreiben :wink: )

PS: Ich benutze dglOpenGL.pas (also OpenGL1.5) und die textures.pas (aus Tutorial 7)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Nov 25, 2003 10:42 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Dein großer Fehler ist, dass du den Alphakanal als extra Textur gespeichert hast. Der muss sich normalerweise in deiner Sterntextur befinden. Also neben den Komponenten Rot, Grün und Blau käme noch der Alphawert hinzu. Das kannst du auf 2 weisen Lösen.
1. Du kannst deine Bilder mit Alphakanal (NUR als TGA) abspeichern. Leider sind nicht alle Programme dazu in der Lage.
2. Du benutzt einen Texturloader, der zwei Texturen miteinander verbinden kann. Objektorientierte Lader können aber auch einen Alphakanal anhand einer Farbe erstellen. Also ColorKey. Dadurch könntest du dir schon einmal die zweite Textur sparen.

Mit der Textures.pas kannst du allerdings nur die Möglichkeit 1 nehmen, da die Texturen gleich komplett fertig erstellt werden und keine Manipulation mehr möglich ist.

Danach stellst du den Alphatest ein bindest deine Textur und zeichnest dein Quad. Das wars dann auch schon.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Nov 25, 2003 11:57 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 17, 2003 09:07
Beiträge: 24
Wohnort: Regensburg
Hmm, dann werd ich mal die textures.pas umschreiben...

in der procedure LoadJPGTexture passiert ja folgendes


Code:
  1.  
  2. For H:=0 to Height-1 do
  3.   Begin
  4.     Line :=BMP.scanline[Height-H-1];   // flip JPEG
  5.     For W:=0 to Width-1 do
  6.     Begin
  7.       c:=Line^ and $FFFFFF; // Need to do a color swap
  8.       Data[W+(H*Width)] :=(((c and $FF) shl 16)+(c shr 16)+(c and $FF00)) or $FF000000;  // 4 channel.
  9.       inc(Line);
  10.     End;
  11.   End;
  12.  


(...)

Code:
  1.  
  2. Texture :=CreateTexture(Width, Height, GL_RGBA, addr(Data[0]));


da müßte dann doch wegen GL_RGBA auch ein ungenutzter Alphakanal mit drin sein, oder ? (Alpha ist dann einfach immer $FF)
Was ich nicht ganz gecheckt habe ist: Wieso macht man aus RGB ein BGR ? Wird in einem Windows-Bitmap die Farbe nicht als RGB sondern als BGR gespeichert - bin verwirrt :shock:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Nov 25, 2003 12:15 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 17, 2003 09:07
Beiträge: 24
Wohnort: Regensburg
Argh, hab´s genau andersrum gemeint...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Nov 25, 2003 12:23 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Du musst die Textures.pas nicht umschreiben. Du könntest ja einen bereits existierenden Texturenloader verwenden. Wie zum Bleistifft meinen (glBitmap.pas) ;-) oder den Jason Allen (GLBMP.pas). Beide findest du im aktuellen DGL-SDK.

Aber zu deiner Frage. Japp. Da wird wohl ein Alphakanal mitgesendet auch wenn er gar nicht benutzt wird. Wie er initialisiert wurde kann ich so nicht sagen. Hängt von den Quellen ab. Aber ich schätze mal mit $FF. Bei 16Bit Texturen ist das reine Platzverschwendung und sorgt nur dafür, dass die Texturen schlechter aussehen als sie eigentlich müssten. (wegen ungenutzten Alpha) Der Loader von Jason Allen macht das im übrigen genau so. :-(

Die Zweite Frage. Ja im Windowsbitmap sind die Farben im BGR format abgelegt. Grafikkarten ab OpenGL1.2 kommen aber auch damit ohne Probleme klar. Also wenn gewisse Extensions unterstützt werden kann man das einfach so an die Karte senden.

PS: Ein Bitmap hat auch Platzhalterzeichen mit eingebaut. Diese können pro Zeile 0-3 Bytes betragen. Je nachdem wie breit das Bild. Das wird in vielen Loadern (Textures.pas, GLBmp.pas) NICHT mit berücksichtigt. Momentan ist das zwar egal. Aber es könnte für einiges an Verwunderung sorgen, wenn NonPowerOfTwo Texturen (OpenGL1.5) "legal" werden. Denn danm sehen die Texturen verschoben aus.

PPS: Auch auf die Gefahr, dass ich wieder ein "bisschchen" Werbung mache. In dem Texturenloader, den ich geastelt habe, habe ich versucht alle diese Sachen mit einfließen zu lassen. Also es wird kein Alpahkanal mit übertragen, wenn keiner existiert. Wenn BGR als Format zulässig ist wird das verwendet. Weil weniger Kopieraufwand. ;-) Zum Laden verwendet ich TBitmap was keine Probleme mit diesen Spacerbytes hat.
Und eine Colorkey funktion existiert auch. Die hat sogar nen Ungenauigkeitsfaktor.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Nov 26, 2003 08:54 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 17, 2003 09:07
Beiträge: 24
Wohnort: Regensburg
Bäh, habs nicht bleiben lassen können - ich bin leider :evil: (LEIDER !) einer der Leute die immer noch ein antikes 56K Modem besitzen. In der Zeit wo diese kleine grüne Schachtel die DGL-SDK runtergeladen hat, hab ich mir eine komplette Unit geschrieben... naja.

Ich schaufel jetzt einfach Byte für Byte (Geschwindigkeitsrausch :roll: )
vom TBitmap in die Textur rein (Ich werd´s mal mit Assembler überarbeiten - das dauert mir einfach zu lange :x )...
Naja, zumindest hab ich jetzt auch´nen Alphakanal.
(Und krieg meine Sterne ohne schwarzes Kästchen rum. :mrgreen: Danke für den Hinweis !)

Deine Unit hab ich mir aber auch mal angeschaut und ausprobiert - wow, da hat sich jemand wirklich Mühe gemacht :D, ich bin jetzt wirklich am überlegen, was ich nehmen soll...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Nov 26, 2003 09:52 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Vergiss das Assembler mal gleich wieder. ;-) Wenn du das gut programmiert hast, dann ist es egal, ob du das Assembler oder Delphi ist.

Wenn du bei einem TBitmap dir einen Pointer mittels Scanline holst und aus diesem Pointer Daten kopierst oder schreibst, dann ist das schon super schnell. Da kannst du mit Assembler auch nicht mehr viel herraus holen.

Zum Bleistiift das Laden aus meinem Loader.
Code:
  1.     for Row := 0 to Height -1 do begin
  2.       pSource := Bitmap.Scanline[Row];
  3.       if (Assigned(pSource)) then begin
  4.         MoveMemory(pData, pSource, Width * Size);
  5.         Inc(PChar(pData), Width * Size);
  6.       end;
  7.     end;

Ich mache dort nichts anderes also mir EINMAL (mehrmals aufrufen tut auch weh) den Pointer der aktuellen Row zu holen und kopiere dann den kompletten Block auf einmal. Intern arbeitet MoveMemory auch Byteweise.

Hier noch eine andere Möglichkeit es Pixel bzw. Byteweise zu kopieren.
Code:
  1.     for Row := 0 to Height -1 do begin
  2.       pSource := Bitmap.Scanline[Row];
  3.       if (Assigned(pSource)) then begin
  4.         for Col := 0 to Width -1 do begin
  5.           // Entweder als BGR laden
  6.           MoveMemory(pData, pSource, Size);
  7.  
  8.           // oder die Bytes rumdrehen und als RGB laden
  9.           PChar(pData)^              := PChar(Integer(pSource) + 2)^;
  10.           PChar(Integer(pData) + 1)^ := PChar(Integer(pSource) + 1)^;
  11.           PChar(Integer(pData) + 2)^ := PChar(pSource)^;
  12.           // Für Alpha noch das
  13.           PChar(Integer(pData) + 3)^ := PChar(Integer(pSource) + 3)^;
  14.  
  15.            // Pointer erhöhe
  16.           Inc(PChar(pData), Size);
  17.           Inc(PChar(pSource), Size);
  18.         end
  19.       end;
  20.     end;

Size ist entweder 3 oder 4. Je nachdem ob Alpha existiert oder nicht.
Wenn man die Möglichkeit hat sollte man das Bild am Besten am Stück laden. Spart Funktionsaufrufe (MoveMemory) und Rechenoperationen (Pointer + Offset). Die werden nämlich von Delphi zu 95% auch direkt in Assembler so umgewandelt. Da ist Delphi schon Sau gut optimiert. :D
Und eigentlich sollte ein Hochsprache ja dafür sorgen, dass man nicht mehr auf Assembler zurückgreifen muss. Was aber nicht bedeuten soll, dass man sich in der Prozesorarchitektur nicht auskennen sollte.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Nov 26, 2003 10:34 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Jul 12, 2002 07:15
Beiträge: 916
Wohnort: Dietzhölztal / Hessen
Programmiersprache: C/C++, Obj-C
Lossy eX hat geschrieben:
Intern arbeitet MoveMemory auch Byteweise.

Stimmt nicht ganz!

Erstens ruft MoveMemory nur die Delphi-Funktion Move auf (solltest Dir also überlegen, ob Du nicht gleich direkt Move verwenden willst. Sparst Dir somit jedesmal einen unnötigen Procedure-Aufruf).

Zweitens zerlegt Move die zu kopierenden Bytes in 4er Blöcke (32 Bit = 4 Byte) und kopiert solange 4-Byte weise (mit dem 32-Bit Befehl movsd, welcher die 4 Byte in einem Rutsch kopiert) bis ein Rest von weniger als 4 Byte übrigbleibt (wird am Anfang ausgerechnet). Lediglich dieser Rest wird dann noch einzeln verschoben. Also ist Move mächtig gut Optimiert und nutz die volle Leistung der 32-Bit Prozessoren! Ich schätze mal, schneller bekommt man das von Hand nicht hin.

Übrigens, was Optimierung angeht: wenn ich es richtig mitbekommen habe, compiliert Delphi ab der Version 5 nur noch in einen zwischen code. Dies ist der gleiche, den auch der C++-Builder von Borland erstellt. Dieser zwischencode wird dann durch einen Optimizer (der von vorland C/C++) durchgejagt, welcher dann den finalen Native-Code erstellt. Das nur als ergänzung zum Thema Delphi und Optimierung!

Von Hand eingefügter Assembler kann also einen Geschwindigkeitsvorteil bringen, jedoch ist fraglich ob das in Relation zum notwendigen Aufwand steht. Was jetzt nicht heissen soll, dass man keinen internen Assembler verwenden darf. Man muss sich eben fragen, ob der notwendige Aufwand wirklich merkbar Geschwindigkeit bringt (was durchaus sein kann), oder ob die von Delphi erbrachte Arbeit genau sogut ist. Delphi zu optimieren ist nicht unbedingt leicht. Machbar, sicher. Je nach afugabe. Aber eben nicht leicht! (Was teilweise auch daran liegt, dass viele RTL-Funktionen bereits mit von Hand optimierten Assembler implementiert wurden. Ein Blick in die Sources der RTL wirkt recht lehrreich.)

Aber nu iss genug mit Off-Topic. ;)

_________________
Und was würdest Du tun, wenn Du wüsstest, dass morgen Dein letzter Tag auf dieser Erde ist?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Nov 26, 2003 11:14 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Ups. Ich erzähle mal wieder Dünnes. :roll:
Man möge mir verzeihen.

SchodMC: Danke für den Tipp. War mir neu, dass er das nicht so tut. Werde das mal umbauen. Habe da auch noch die eine oder andere optimierwürdie Stelle gefunden. :-)

OffTopic: Auch wieder wahr. ;-) Aber eine Sache hätte ich da noch. Bevor man so etwas Zeit und Nervenintensives wie Assembler verwendet sollte man sich einmal ausmalen was es einem überhaupt bringt. Den Ladevorgang eines Bildes von 20 auf 18 ms zu beschleunigen hat bei 20 Bildern so gut wie keine Auswirkung. Vor allem wenn man dedenkt, dass das Laden nur Einmal aufgerufen wird! Und zwar beim Initialisieren. Dann sollte man viel mehr darauf achten, dass man die Renderschleife gut optimiert. Die wird ja 30 - 500 Mal in der Sekunde aufgerufen. Und da würde es sich schon eher lohnen viel Zeit in die Optimierungen zu stecken.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Nov 26, 2003 11:28 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Jul 12, 2002 07:15
Beiträge: 916
Wohnort: Dietzhölztal / Hessen
Programmiersprache: C/C++, Obj-C
@Richtig Optimieren (Render-Schleife): Jau! Aber mal ehrlich: solche Überlegungen setze ich mittlerweile bei den Cummunity-Mitgliedern vorraus! Hab da großes Vertrauen. ;)

_________________
Und was würdest Du tun, wenn Du wüsstest, dass morgen Dein letzter Tag auf dieser Erde ist?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Nov 26, 2003 11:40 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Dez 13, 2002 12:18
Beiträge: 1063
Die Codeoptimierung von movsb zu movsd mit DWORD-Alignment vorn und hinten, die von vielen Compilern immer noch durchgeführt wird, ist übrigens suboptimal, da diese Optimierung auf jedem halbwegs modernen Prozesser (meines Wissens ab Pentium Pro, und sogar schon bei einigen Cyrix 486ern) intern durchgeführt wird.
Im Endeffekt kann man sich aber für "normale" Sachen ohnehin auf den Postoptimizer von modernen Programmiersprachen verlassen - Assemblerprogrammierung bringt nur was, wenn's um wirklich zeit- oder Speicherplatzkritische Anwendungen geht (dann allerdings ist man froh, wenn man's kann).

_________________
Viel Spaß beim Programmieren,
Mars
http://www.basegraph.com/


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Nov 26, 2003 11:56 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 17, 2003 09:07
Beiträge: 24
Wohnort: Regensburg
Ihr braucht euch bei mir nix dabei denken, ich arbeite viel und gern mit Assembler, da kommt´s auf den Texturloader jetzt auch nicht mehr drauf an. :wink: Hab vermutlich eine masochistische Ader :mrgreen:

Mich hat´s eben genervt, daß Window so ewig mit den TBitmap rummacht... (In Vergleich zu anderen Operationen)

Danke jedenfalls für eure Hilfe !


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 12 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.017s | 17 Queries | GZIP : On ]