It is currently Sat Dec 16, 2017 7:47 pm

All times are UTC + 1 hour




Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: Problem with TransparentSpriteColor?
PostPosted: Fri Nov 11, 2016 6:57 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sun Jul 29, 2012 10:33 pm
Posts: 715
Location: United States
I may have found a bug with TransparentSpriteColor. It seems that if you draw directly onto a sprite more then once the transparency will still be linked to the original version.
In my example below I create a sprite and fill it completely green, and then I draw a red circle with a diameter of the box.
The green is set to transparent, and this all works fine. The sprite is displayed as it should be.
When I draw to the sprite a second time just like I did to the first except I make the red circle smaller. The result is a large green circle with a smaller red circle inside it.

The problem seems to be caused by TransparentSpriteColor. If I call TransparentSpriteColor only after the second draw the result is correct and I only see a small red circle. If I call it after each draw then I get the large green and small red circles.

I'm using PB 5.5 (x64) on Windows 7 and have tested it on both DirectX and OpenGL.
Code:
EnableExplicit

If InitSprite() = 0
  MessageRequester("Error!", "Failed to init the sprite system.", #PB_MessageRequester_Ok)
  End
EndIf

Define.i Event
Define.i WinW = 800
Define.i WinH = 600

If OpenWindow(0, 0, 0, WinW, WinH, "Transparent Sprite Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  If OpenWindowedScreen(WindowID(0), 0, 0, WinW, WinH) = 0
    MessageRequester("Error!", "Failed to open the screened window.", #PB_MessageRequester_Ok)
    End
  EndIf
 
  CreateSprite(1, 256, 256, #PB_Sprite_AlphaBlending)
  StartDrawing(SpriteOutput(1))
    DrawingMode(#PB_2DDrawing_Default)
    Box(0, 0, 256, 256, RGB(0,255,0)) ;Fill the entire sprite with a green background
    Circle(128, 128, 128, RGB(255,0,0)) ;Draw a large red circle
  StopDrawing()
 
  ;####
  ;Comment out the below TransparentSpriteColor() and everthing works correctly
  TransparentSpriteColor(1, RGB(0,255,0))
  ;####
 
  StartDrawing(SpriteOutput(1))
    DrawingMode(#PB_2DDrawing_Default)
    Box(0, 0, 256, 256, RGB(0,255,0)) ;Fill the entire sprite with a green background
    Circle(128, 128, 64, RGB(255,0,0)) ;Draw a small red circle
  StopDrawing()
 
  TransparentSpriteColor(1, RGB(0,255,0))
 
  Repeat
   
    DisplayTransparentSprite(1, 200, 200)
    FlipBuffers()

  Until WindowEvent() = #PB_Event_CloseWindow
 
EndIf
End


Top
 Profile  
Reply with quote  
 Post subject: Re: Problem with TransparentSpriteColor?
PostPosted: Fri Nov 11, 2016 7:11 pm 
Offline
Addict
Addict
User avatar

Joined: Fri Apr 12, 2013 1:55 pm
Posts: 1052
Location: just outside of Ferguson
Same behavior exists in PB 5.43 LTS x64 Linux.

_________________
Keep it BASIC.


Top
 Profile  
Reply with quote  
 Post subject: Re: Problem with TransparentSpriteColor?
PostPosted: Fri Nov 11, 2016 8:22 pm 
Offline
Enthusiast
Enthusiast

Joined: Thu Aug 30, 2007 11:54 pm
Posts: 658
Location: right here
i have some other code here i used to clarify for my self some time ago:

without modification (no TransparentSpriteColor() used) the code works as expected:
a black sprite and within is one transparent box 1, a black box 2 and a red box 4.
only box 1 is transparent, due to the alpha used.

when commenting in the first TransparentSpriteColor():
- the default BG color of $ff000000 is reported by Point() as $00000000, even with alpha in the drawing mode.
thought the alpha is reported correctly for box 2 and 3 after drawing.
..or the default BG color actually changed with using TransparentSpriteColor()?
- transparency is still only affected by the alpha channel (box 2 with $ff000000 is still not transparent)

Code:
InitSprite()
InitMouse()
InitKeyboard()

ww=800
wh=600
style | #PB_Window_ScreenCentered
style | #PB_Window_SystemMenu
style | #PB_Window_MinimizeGadget

If 01
  win=OpenWindow(#PB_Any, 50,100, ww,wh, "", style) :: AddKeyboardShortcut(win, #PB_Shortcut_Escape, 10)
  OpenWindowedScreen(WindowID(win), 0,0, ww/3,wh/3, 1,0,0)
Else
  OpenScreen(ww,wh,32,"", #PB_Screen_NoSynchronization)
  SetFrameRate(9999)
EndIf

Procedure debugColorP(text.s, x,y)
  Debug text + ": " + Red(Point(x,y)) + ","+Green(Point(x,y))+","+Blue(Point(x,y))+","+Alpha(Point(x,y))
EndProcedure

; only background sprite
w = ScreenWidth()
h = ScreenHeight()
sprBG = CreateSprite(#PB_Any, w, h, #PB_Sprite_AlphaBlending)
StartDrawing(SpriteOutput(sprBG))
  DrawingMode(#PB_2DDrawing_AllChannels)
  Box(0, 0, w, h, $ffaaaaaa)
  Box(50, 50, 50, 50, $ff00ff00)
  DrawingMode(#PB_2DDrawing_AllChannels | #PB_2DDrawing_Outlined)
  For i=0 To 200
    Circle(Random(w), Random(h), Random(50), RGBA(Random(255), Random(255), Random(255), Random(255)))
  Next
StopDrawing()

w = 100
h = 100
spr1 = CreateSprite(#PB_Any, w, h, #PB_Sprite_AlphaBlending)

; this would make the default BG of $ff000000 transparent, but not the Box(.., $ff000000) area!
; also the alpha will not be reported by Point() for the default color, but for the Box() with the same color.
;TransparentSpriteColor(spr1, RGB(0,0,0))

; this behaves exactly like the previous one
;TransparentSpriteColor(spr1, RGBA(0,0,0,255))

; ..so don't use TransparentSpriteColor() at all with alpha channels

StartDrawing(SpriteOutput(spr1))
  debugColorP("default (RGB) ", 0, 0)
  DrawingMode(#PB_2DDrawing_AllChannels)
  debugColorP("default (RGBA)", 0, 0)
 
  Box(10, 10, 20, 20, $00000000)
  debugColorP("in box 1      ", 10, 10)
 
  Box(40, 10, 20, 20, $ff000000)
  debugColorP("in box 2      ", 40, 10)
 
  Box(60, 10, 20, 20, $ff0000ff)
  debugColorP("in box 3      ", 60, 10)
 
  DrawingMode(#PB_2DDrawing_AllChannels | #PB_2DDrawing_Outlined)
  For i=0 To 50
    Circle(Random(w), Random(h), Random(50), RGBA(Random(255), Random(255), Random(255), Random(255)))
  Next
StopDrawing()

Repeat
  ExamineMouse()
  ExamineKeyboard()
 
  If IsWindow(win) ;{
    Repeat
      event = WindowEvent()
      em = EventMenu()
      Select event
        Case #PB_Event_CloseWindow
          quit = #True
        Case #PB_Event_Menu
          Select em
          Case 10
            quit = #True
          EndSelect
      EndSelect
    Until Not event
    ;}
  EndIf
 
  DisplayTransparentSprite(sprBG, 0, 0)
  DisplayTransparentSprite(spr1, MouseX(), MouseY())
 
  StartDrawing(ScreenOutput())
    DrawingMode(#PB_2DDrawing_Transparent)
    Circle(MouseX(), MouseY(), 1)
  StopDrawing()
 
  FlipBuffers()
  ClearScreen($333333)
  If IsWindow(win)
    Delay(10)
  EndIf
Until quit Or KeyboardPushed(#PB_Key_Escape)

so my guess is that alpha channel and TransparentSpriteColor() is not meant to be used together, especially since the command is older than the alpha channel support, and it does not accept and RGBA value, at least it doesn't use the the alpha component.
also it doesn't make a color transparent if the color does not have alpha 0 anyway.
..but it your case the green actually becomes transparent without alpha ..i'm still a bit confused.


Top
 Profile  
Reply with quote  
 Post subject: Re: Problem with TransparentSpriteColor?
PostPosted: Fri Nov 11, 2016 8:58 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sun Jul 29, 2012 10:33 pm
Posts: 715
Location: United States
I changed the box to blue instead of green in the second drawing block, and then updated TransparentSpriteColor() to blue also which makes everything work correctly.

This is just a guess, but I bet when TransparentSpriteColor() is called Purebasic tests to see if the current transparent sprite color is the same as the newly requested color. If they are the same it backs out and doesn't complete the process. Which results in incorrect transparent areas when the sprite has been redrawn.

Here's the working code with the two different TransparentSpriteColor()s.
Code:
EnableExplicit

If InitSprite() = 0
  MessageRequester("Error!", "Failed to init the sprite system.", #PB_MessageRequester_Ok)
  End
EndIf

Define.i Event
Define.i WinW = 800
Define.i WinH = 600

If OpenWindow(0, 0, 0, WinW, WinH, "Transparent Sprite Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  If OpenWindowedScreen(WindowID(0), 0, 0, WinW, WinH) = 0
    MessageRequester("Error!", "Failed to open the screened window.", #PB_MessageRequester_Ok)
    End
  EndIf
 
  CreateSprite(1, 256, 256, #PB_Sprite_AlphaBlending)
  StartDrawing(SpriteOutput(1))
    DrawingMode(#PB_2DDrawing_Default)
    Box(0, 0, 256, 256, RGB(0,255,0)) ;Fill the entire sprite with a green background
    Circle(128, 128, 128, RGB(255,0,0)) ;Draw a large red circle
  StopDrawing()
 
  TransparentSpriteColor(1, RGB(0,255,0))

 
  StartDrawing(SpriteOutput(1))
   DrawingMode(#PB_2DDrawing_Default)
   Box(0, 0, 256, 256, RGB(0,0,255)) ;Fill the entire sprite with a blue background
   Circle(128, 128, 64, RGB(255,0,0)) ;Draw a small red circle
  StopDrawing()
 
  TransparentSpriteColor(1, RGB(0,0,255))
 
  Repeat
   
    DisplayTransparentSprite(1, 200, 200)
    FlipBuffers()

  Until WindowEvent() = #PB_Event_CloseWindow
 
EndIf
End


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye