Seite 1 von 2

PNG Sprite zerstückeln

Verfasst: 04.01.2010 20:40
von Josef Sniatecki
Hallo an alle,

ich habe folgendes Problem: Ich besitze ein Tileset das im PNG-Format vorliegt, weil diese Teile später auch den Alpha-Kanal unterstützen sollen. Das Problem ist nun, dass ich keine 3D-Sprites aus den Tiles erstellen kann, da ClipSprite leider keinen Einfluss hat. Außerdem kann ich auch kein PNG-Sprite anzeigen lassen und dieses dann durch GrabSprite zerstückeln, da der Alpha-Kanal verloren gehen würde.

Gibt es irgendeine Möglichkeit, in PureBasic PNG-Sprites zu zerteilen?

Hier mein fehlgeschlagener Versuch:

Code: Alles auswählen

LoadSprite(0, "Tileset.png", #PB_Sprite_Texture)
ClipSprite(0, #FieldSize*X, #FieldSize*Y, #FieldSize, #FieldSize)
Tile_X_Y = CreateSprite3D(#PB_Any, 0)
Gruß Josef

Re: PNG Sprite zerstückeln

Verfasst: 04.01.2010 20:52
von STARGÅTE
lade das TitleSet erst mal als IMAGE, dies kannst du zerstückeln, auch mit Alpha und dann im temp-Ordner speichern, von dort aus lädst du das neue Bild als Sprite...

das mag nicht perfekt sein, sollte aber gehen

Re: PNG Sprite zerstückeln

Verfasst: 04.01.2010 21:02
von Josef Sniatecki
Danke für deinen Tipp. Darauf wäre ich garnicht gekommen.

Hab schon mal gecodet:

Code: Alles auswählen

Procedure.i GetTile(Set.i, X.i, Y.i)
  Protected Tile.i, Sprite.i
  
  Tile = GrabImage(Set, #PB_Any, #FieldSize*X, #FieldSize*Y, #FieldSize, #FieldSize)
  SaveImage(Tile, "Temp.png", #PB_ImagePlugin_PNG)
  
  Sprite = LoadSprite(#PB_Any, "Temp.png", #PB_Sprite_Texture|#PB_Sprite_AlphaBlending)
  ProcedureReturn CreateSprite3D(#PB_Any, Sprite)
EndProcedure
Entsteht zwar ne Windows-Ladezeit, aber dafür geht's :allright:.

Re: PNG Sprite zerstückeln

Verfasst: 05.01.2010 11:37
von kswb73
Oder wie wäre es damit:
Du lädst das das Bild als Image. Anstelle es dann im Temp Order zu speichern, malst du es einfach mittel DrawAlphaImage() in dein Sprite.

Re: PNG Sprite zerstückeln

Verfasst: 05.01.2010 12:59
von STARGÅTE
das prolem ist aber das DrawAlphaImage() den AlphaChannel nicht selbst mit in das Sprite kopiert.
soll heißen das Image wird mit AlphaBlending auf das leere (schwarze, aber nicht transparente) Sprite gemalt.
und die ganzen Alpha-Sachen aus der 2D-Drawing-Lib sind nur für ImageOutput().
Man kann also ein Sprite selbst wenn es mit #PB_Sprite_AlphaBlending erstellt ist nicht durchschtig machen in bezug auf den Alphachannel

Re: PNG Sprite zerstückeln

Verfasst: 05.01.2010 14:05
von Thorium
Kann man schon durchsichtig machen. Du musst die Images nur zu fuß auf die Sprites malen. Dann klappt das. Einfach den Pointer zu den Buffern holen und dann den Kram mit den Memory befehlen rüberkopieren. Darauf achten das pitch und pixelformat berücksichtigt werden müssen.

Re: PNG Sprite zerstückeln

Verfasst: 05.01.2010 14:46
von STARGÅTE
danke Thorium für den Tip :

Code: Alles auswählen

InitSprite()
InitSprite3D()
InitKeyboard() 

OpenWindow(0, 0, 0, 800, 600, "SCREEN", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, 800, 600, 0, 0, 0)

CreateSprite(0, 256, 256, #PB_Sprite_Texture|#PB_Sprite_AlphaBlending)
StartDrawing(SpriteOutput(0))
 Debug DrawingBufferPixelFormat()
 For y = 0 To 255
  For x = 0 To 255
   *Buffer = DrawingBuffer() + y*4*256 + x*4
   PokeL(*Buffer, RGBA(y,255,255,x))
  Next
 Next
StopDrawing()
CreateSprite3D(0, 0) 

Repeat

 WaitWindowEvent(10)
 
 ClearScreen($FF8000)
 
 Start3D()
  DisplaySprite3D(0,0,0)
 Stop3D()
 
 FlipBuffers()

 ExamineKeyboard()
 If KeyboardPushed(#PB_Key_Escape) : End : EndIf

ForEver
wusste garnicht das es "so einfach" ist.
Ich hoffe trotzdem das die "richtigen"-alpha-Sachen die zur Zeit nur bei Image gehen auch bei Sprites gehen, damit man sich diese "umweg" sparen kann.

Re: PNG Sprite zerstückeln

Verfasst: 03.03.2010 17:35
von dllfreak2001
Weil es gerade zum Thread-Verlauf passt... warum wird hier das Image nicht
nicht mit einem Transparenzverlauf dargestellt.

Code: Alles auswählen

UsePNGImageDecoder()

CreateImage(0, 256, 256, 32)

StartDrawing(ImageOutput(0))
  For y = 0 To 255
    For x = 0 To 255
      Plot(x,y, RGBA(y, 100, 0, x))
    Next
  Next
StopDrawing()

OpenWindow(0, 0, 0, 500, 500, "Alpha-Test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  ImageGadget(0, 100, 120, 400, 400, ImageID(0))

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow

Re: PNG Sprite zerstückeln

Verfasst: 03.03.2010 17:41
von STARGÅTE
weil du im falschen DrawingMode arbeitest:

Das Image ist beim erstellen gefüllt mit RGBA(0,0,0,255)
Das muss erst mal mit AlphaChannel auf 0 gesetzt werden

Code: Alles auswählen

DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0,0,ImageWidth(0),ImageHeight(0),$00000000)
danach musst du mit AlphaBlend arbeiten damit die fArbe richtig draufgesetzt wird:

Code: Alles auswählen

UsePNGImageDecoder()

CreateImage(0, 256, 256, 32)

StartDrawing(ImageOutput(0))
  DrawingMode(#PB_2DDrawing_AlphaChannel)
  Box(0,0,ImageWidth(0),ImageHeight(0),$00000000)
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  For y = 0 To 255
    For x = 0 To 255
      Plot(x,y, RGBA(y, 100, 0, x))
    Next
  Next
StopDrawing()

OpenWindow(0, 0, 0, 500, 500, "Alpha-Test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  ImageGadget(0, 100, 120, 400, 400, ImageID(0))

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Für sowas habe ich schon mal n Procedure geschrieben:

Code: Alles auswählen

 Procedure CreateTransparentImage(Image, Width, Height)
  Protected Result = CreateImage(Image, Width, Height, 32)
  If Image = #PB_Any : Image = Result : EndIf
  If IsImage(Image)
   If StartDrawing(ImageOutput(Image))
    DrawingMode(#PB_2DDrawing_AlphaChannel)
    Box(0,0,ImageWidth(Image),ImageHeight(Image),$00000000)
    StopDrawing()
    ProcedureReturn Result
   EndIf
  EndIf
 EndProcedure
sie erstellt sofort ein komplett echt transparentes Image (geht mit Index und #PB_any)

Re: PNG Sprite zerstückeln

Verfasst: 03.03.2010 18:21
von dllfreak2001
Achso, ich habe gedacht, der Plot-Befehl könnte den Alpha-Wert des entsprechenden Pixels direkt manipulieren.
<) Danke für den Code!