Seite 2 von 3
Verfasst: 14.08.2009 09:25
von dllfreak2001
Dann Beispiel her....
Ich könnte wie viele ander hier die Echtzeitmanipulation der Alphakanäle von Sprites durchaus gebrauchen.

Verfasst: 15.08.2009 00:10
von Thorium
dllfreak2001 hat geschrieben:Dann Beispiel her....
Ich könnte wie viele ander hier die Echtzeitmanipulation der Alphakanäle von Sprites durchaus gebrauchen.

OK, nach einigen Stunden rummprobieren muss ich leider sagen das es so aussieht als würde PB den Alphakanal zerstören.
Läd man ein Sprite aus einem Bild mit Alphakanal ist dieser im Sprite vorhanden, er wird beim Zeichnen des Sprites berücksichtigt. Möchte man nun mit DrawingBuffer() direkt auf die Bilddaten zugreifen zerstört PB den Alphakanal. Innerhalb des StartDrawing-StopDrawing Blocks, in dem man das Sprite mittels DrawingBuffer() manipuliert ist noch alles in Ordnung. Der Alphakanal lässt sich dort auch auslesen. Nach dem Block jedoch ist der Alphakanal FF auf jedem Pixel.
Nun wirds noch kurioser. Läd man das Sprite nicht aus einer Datei, sondern erstellt es mit CreateSprite kann man genau ein mal per DrawingBuffer() auf die Bilddaten zugreifen und ein Bild _mit_ Alphakanal erstellen. Der Alphakanal funktioniert dann. Greift man ein zweites mal darauf zu zerstört PB den Kanal wieder.
Ich glaube das is ein Bug.
Ich bastel mal nen Code der das demonstiert.
In meinem Projekt hab ich den Alphakanal ja nur einmal beim Catchen meiner Sprites erstellt. Und das funktioniert, später nochmal manipuliert habe ich ihn nicht. Ich raffe nur nicht warum es später nicht mehr funktioniert.
Verfasst: 15.08.2009 00:45
von Thorium
Hab grad nochwas rausgefunden: Und zwar scheint das ein Bug zu sein, der im DirectX9 Subsystem steckt. Mit Standart-Subsystem (DirectX7) bleibt der Alphakanal intakt!
Nur leider wird der nur bei 3DSprites bei der Zeichnung des Sprites berücksichtigt und InitSprite3D schlägt bei mir unter Vista mit DX7 fehl und XP hab ich grad nicht zur Hand.
Verfasst: 15.08.2009 10:42
von dllfreak2001
Das kann sein...
Aber stell doch dein Beispiel hier herein (wenn du es willst) dann können es andere auch mal austesten.
Würde schon gern sehen wie du den Alphakanal innerhalb des DrawingBuffer-Blocks manipulierst.
Verfasst: 15.08.2009 13:21
von Thorium
Öhm, also das glaub ich jetzt nicht. Heute Rechner wieder angemacht den Source unverändert nochmal gestartet um zu schauen das er auch keinen Fehler auswirft bevor ich ihn poste und nun funzt der Alphachannel.

Wird nicht zerstört.
Beispielsource kommt gleich, ich will nur noch kurz bissel testen. ^^
Vieleicht ist das sogar ein DX9 Bug, der garnix mit PB zutun hat.
Verfasst: 15.08.2009 13:35
von Thorium
So hier der Code:
Es hat zwar noch den Schönheitsfehler das die Alphawerte der Datei ignoriert werden. Aber das ist ja erstmal für ein Beispiel wurscht.
Der Code zeichnet ein Hintergrundbild und darauf ein kleines 32x32 Sprite, welches per direkter Manipulation des Alphakanals ein wenig gefaded wird.
Läuft bei mir mit ca. 500 FPS. Ist natürlich auch ein sehr kleines Sprite. Bei großen Sprites geht die Performance in die Knie.
Die beiden Bilddateien können natürlich auch runtergeladen werden:
http://www.gametreasure.de/downloads/bgtest.png
http://www.gametreasure.de/downloads/test.png
Nicht vergessen die Pfade im Code anzupassen.
Code: Alles auswählen
EnableExplicit
Structure Pixel_BGRA
Blue.b
Green.b
Red.b
Alpha.b
EndStructure
Define.i BgSprite, Sprite, BgSprite3D, Sprite3D, Exit, Time, Frames, FpsStartTime, FpsTime, Buffer, Pitch, PixelFormat, Width, Height, X, Y, Alpha, Direction
Define.f Fps
Define *Pixel.Pixel_BGRA
InitKeyboard()
InitSprite()
InitSprite3D()
UsePNGImageDecoder()
OpenScreen(1024, 768, 32, "Test")
BgSprite = LoadSprite(#PB_Any, "d:\Bgtest.png", #PB_Sprite_Texture | #PB_Sprite_AlphaBlending)
BgSprite3D = CreateSprite3D(#PB_Any, BgSprite)
Sprite = LoadSprite(#PB_Any, "d:\test.png", #PB_Sprite_Texture | #PB_Sprite_AlphaBlending)
Sprite3D = CreateSprite3D(#PB_Any, Sprite)
Alpha = 1
Direction = 1
Repeat
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Escape) <> 0
Exit = #True
EndIf
;-----------------------------
;manipulation of alpha channel
;-----------------------------
StartDrawing(SpriteOutput(Sprite))
Buffer = DrawingBuffer()
Pitch = DrawingBufferPitch()
PixelFormat = DrawingBufferPixelFormat()
Width = SpriteWidth(Sprite) - 1
Height = SpriteHeight(Sprite) - 1
If PixelFormat <> #PB_PixelFormat_32Bits_BGR
Debug "wrong pixel format"
End
EndIf
Alpha + Direction
If Alpha = 127
Direction = -1
ElseIf Alpha = 1
Direction = 1
EndIf
For Y = 0 To Height
*Pixel = Buffer + (Pitch * Y)
For X = 0 To Width
*Pixel\Alpha = Alpha
*Pixel + 4
Next
Next
StopDrawing()
;-----------------------------
Frames + 1
Time = ElapsedMilliseconds()
FpsTime = Time - FpsStartTime
If FpsTime > 100
Fps = Frames / FpsTime * 1000
FpsStartTime = Time
Frames = 0
EndIf
ClearScreen($00000000)
Start3D()
DisplaySprite3D(BgSprite3D, 1, 1)
DisplaySprite3D(Sprite3D, 100, 100)
Stop3D()
StartDrawing(ScreenOutput())
DrawText(1,1,"FPS : " + StrF(Fps, 2), $00FF0000)
StopDrawing()
FlipBuffers(#PB_Screen_NoSynchronization)
Until Exit = #True
Verfasst: 15.08.2009 19:29
von Thorium
Und hier DarkDragons schicke Prozedur umgebaut für die Verwendung mit Sprites und Alphakanal. Hier wird nicht die Farbe direkt verändert, sondern nur der Alphakanal. Man könnte damit also auch ein Muster nehmen zum aufdecken.
Läuft bei mir mit ca. 500 FPS.
Downloads der Bilder:
http://www.gametreasure.de/downloads/test.png
http://www.gametreasure.de/downloads/test2.png
Code: Alles auswählen
EnableExplicit
Structure Pixel_BGRA
Blue.b
Green.b
Red.b
Alpha.b
EndStructure
Procedure.i doEffect(Sprite.i, Angle.d, Transparency.i)
Define.i Width, Height, HalfWidth, HalfHeight, X, Y, Buffer, Pitch, PixelFormat, Line, XPos, YPos
Define.d PixelAngle
Define *Pixel.Pixel_BGRA
If IsSprite(Sprite) = 0
ProcedureReturn 0
EndIf
Angle = (Angle * #PI) / 180.0
StartDrawing(SpriteOutput(Sprite))
Width = SpriteWidth(Sprite)
Height = SpriteHeight(Sprite)
HalfWidth = Width >> 1
HalfHeight = Height >> 1
Buffer = DrawingBuffer()
Pitch = DrawingBufferPitch()
PixelFormat = DrawingBufferPixelFormat()
If PixelFormat = #PB_PixelFormat_32Bits_BGR Or PixelFormat = #PB_PixelFormat_32Bits_RGB
For X = -HalfWidth To HalfWidth - 1
For Y = -HalfHeight To HalfHeight - 1
PixelAngle = ACos(Y / Sqr(X * X + Y * Y))
If Angle < #PI And X > 0
If PixelAngle < Angle
XPos = X + HalfWidth
YPos = Height - (Y + HalfHeight) - 1
*Pixel = Buffer + Pitch * YPos + 4 * XPos
*Pixel\Alpha = Transparency
Else
XPos = X + HalfWidth
YPos = Height - (Y + HalfHeight) - 1
*Pixel = Buffer + Pitch * YPos + 4 * XPos
*Pixel\Alpha = 0
EndIf
Else
If X > 0
XPos = X + HalfWidth
YPos = Height - (Y + HalfHeight) - 1
*Pixel = Buffer + Pitch * YPos + 4 * XPos
*Pixel\Alpha = Transparency
ElseIf PixelAngle < Angle - #PI
XPos = X + HalfWidth
YPos = Y + HalfHeight
*Pixel = Buffer + Pitch * YPos + 4 * XPos
*Pixel\Alpha = Transparency
Else
XPos = X + HalfWidth
YPos = Y + HalfHeight
*Pixel = Buffer + Pitch * YPos + 4 * XPos
*Pixel\Alpha = 0
EndIf
EndIf
Next Y
Next X
Else
StopDrawing()
ProcedureReturn 0
EndIf
StopDrawing()
ProcedureReturn 1
EndProcedure
Define.i Sprite, EffectSprite, Sprite3D, EffectSprite3D, Exit, Time, Frames, FpsStartTime, FpsTime, LastTime, CurrentTime
Define.f Fps
Define.d Angle
Define *Pixel.Pixel_BGRA
InitKeyboard()
InitSprite()
InitSprite3D()
UsePNGImageDecoder()
OpenScreen(1024, 768, 32, "Test")
Sprite = LoadSprite(#PB_Any, "d:\test.png", #PB_Sprite_Texture | #PB_Sprite_AlphaBlending)
Sprite3D = CreateSprite3D(#PB_Any, Sprite)
EffectSprite = LoadSprite(#PB_Any, "d:\test2.png", #PB_Sprite_Texture | #PB_Sprite_AlphaBlending)
EffectSprite3D = CreateSprite3D(#PB_Any, EffectSprite)
Angle = 0.0
LastTime = ElapsedMilliseconds()
Repeat
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Escape) <> 0
Exit = #True
EndIf
CurrentTime = ElapsedMilliseconds()
Angle + (CurrentTime - LastTime) * 0.1
LastTime = CurrentTime
While Angle > 360.0
Angle - 360.0
Wend
doEffect(EffectSprite, Angle, 100)
Frames + 1
Time = ElapsedMilliseconds()
FpsTime = Time - FpsStartTime
If FpsTime > 100
Fps = Frames / FpsTime * 1000
FpsStartTime = Time
Frames = 0
EndIf
ClearScreen($00000000)
Start3D()
DisplaySprite3D(Sprite3D, 100, 100)
DisplaySprite3D(EffectSprite3D, 100, 100)
Stop3D()
StartDrawing(ScreenOutput())
DrawText(1,1,"FPS : " + StrF(Fps, 2), $00FF0000)
StopDrawing()
FlipBuffers(#PB_Screen_NoSynchronization)
Until Exit = #True
Verfasst: 15.08.2009 19:31
von DarkDragon
Ich würde gerne mal was von Rubiko zu dem Thema hören, ob nun etwas richtig war?!
Verfasst: 15.08.2009 19:41
von dllfreak2001

Super, muss die Codes heute gleich mal testen wenn ich heute nach Hause komme.

Verfasst: 15.08.2009 19:50
von Fluid Byte