It is currently Thu Nov 14, 2019 8:39 pm

All times are UTC + 1 hour




Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: how to Tint a translucent sprite?
PostPosted: Wed Mar 16, 2016 10:44 pm 
Offline
User
User

Joined: Tue Mar 18, 2014 4:25 pm
Posts: 62
Location: Bogotá, Colombia
Hi all,

I am working on a particles engine, and I need to tint the particles (sprites) with a specific color (may be random or pre-set). The default behaviour of DisplayTransparentSprite when you pass a color does not work as expected as it changes avery pixel of the image that is non transparent to that specific color instead of "tinging" it.

So Looking at the forums for a solution, the suggested method to do so is to display twice the same sprite, one with the original color, and one with a translucent color as shown in the code bellow:

Code:
DisplayTransparentSprite(spriteId, x, y)
DisplayTransparentSprite(spriteId, x, y, alphaValue, desiredColor)


This however has a problem when you need to display the colored sprite with a specific translucency and at the same time tinted with a color.

What I thought on doing was
Code:
alphaValue = 150/2
DisplayTransparentSprite(spriteId, x, y, alphaValue)
DisplayTransparentSprite(spriteId, x, y, alphaValue, desiredColor)


But this solution makes the colored sprite almost invisible so not sure if that should be the right way to do it.

Do you guys have ideas?


Top
 Profile  
Reply with quote  
 Post subject: Re: how to Tint a translucent sprite?
PostPosted: Thu Mar 17, 2016 12:14 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Thu Mar 24, 2011 12:40 am
Posts: 534
Location: Iowa, USA
Hi,
I think you must apply the tint to the sprite before you display it.

Here is a procedure that I have used to tint an image, grayscale or full color.
I have modified the procedure to work with sprites and hopefully the alpha channel will work properly.
This procedure assumes the transparent color is black.
I must caution you that I have not tested it in this modified form.
I hope it works for you.
Code:
Procedure TINT_SPRITE(sprite.i, color.i)
   Protected c, i, x, y, xMax, yMax
   Protected.d r, g, b

   r = Red(color)   / 1785
   g = Green(color) / 1785
   b = Blue(color)  / 1785
   
   If IsSprite(sprite)
     
      StartDrawing(SpriteOutput(sprite))
         xMax = OutputWidth()  - 1
         yMax = OutputHeight() - 1
         
         For y = 0 To yMax
            For x = 0 To xMax
               c = Point(x, y)
               
               i = (c & $FF) << 1 : c >> 8
               i + (C & $FF) << 2 : c >> 8
               i + (c & $FF)      : c >> 8
               
               Plot(x, y, RGBA(r*i, g*i, b*i, c))
            Next x
         Next y
      StopDrawing()
     
   EndIf
EndProcedure

_________________
BasicallyPure
Until you know everything you know nothing, all you have is what you believe.


Top
 Profile  
Reply with quote  
 Post subject: Re: how to Tint a translucent sprite?
PostPosted: Thu Mar 17, 2016 3:07 pm 
Offline
User
User

Joined: Tue Mar 18, 2014 4:25 pm
Posts: 62
Location: Bogotá, Colombia
Will try that out, thanks.

My only concern is the use of the StartDrawing()/StopDrawing(). It is not that fast and efficient for it to be run during a game loop (at least not in my test but please feel free to share your experience). For my use case I would be generating particles all the time each with a random color, so this procedure would be called hundreds of times in a single game update.

I havent tested it yet as right now I dont have access to my PB compiler and source code, but will give it a try as soon as possible. In the mean time are there any other options?


Top
 Profile  
Reply with quote  
 Post subject: Re: how to Tint a translucent sprite?
PostPosted: Thu Mar 17, 2016 5:57 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Thu Mar 24, 2011 12:40 am
Posts: 534
Location: Iowa, USA
juankprada wrote:
My only concern is the use of the StartDrawing()/StopDrawing(). It is not that fast and efficient for it to be run during a game loop

Correct. It would not be good to use inside of your game loop.
I don't know how big your sprites are.
If they are small maybe you could create many sprites, each with a different tint.
Choose from them randomly inside your loop.

_________________
BasicallyPure
Until you know everything you know nothing, all you have is what you believe.


Top
 Profile  
Reply with quote  
 Post subject: Re: how to Tint a translucent sprite?
PostPosted: Mon Apr 25, 2016 1:07 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Thu Apr 30, 2009 5:23 pm
Posts: 306
Location: Côtes d'Azur, France
Display your 2 sprites and use blendingmodes on your sprites. SpriteBlendingMode(ModeSource, ModeDestination).

_________________
There are 2 methods to program bugless.
But only the third works fine.

Win10, Pb x64 5.70 LTS


Top
 Profile  
Reply with quote  
 Post subject: Re: how to Tint a translucent sprite?
PostPosted: Tue Apr 26, 2016 10:02 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Thu Apr 07, 2011 1:14 pm
Posts: 243
Location: 3 arks
@Basicallypure : thanks for your procedure ;).

I have added some lines, to not tint with a white color, which change the sprite in grey level ^^. And I think it's interesting to draw again the originale image to not tint over the last color, but with a new color each time :

Code:
 If IsSprite(SpriteId)
     
       StartDrawing(SpriteOutput(Sprite))
       
       ; erase first the sprite
       DrawingMode(#PB_2DDrawing_AllChannels)
       Box(0,0,OutputWidth(),OutputHeight(),RGBA(0,0,0,0))
       ; draw the original image, you need to know what is the sprite image
       DrawingMode(#PB_2DDrawing_AlphaBlend)
       DrawAlphaImage(ImageID(SpriteImg),0,0)
       
       ; then tint the sprite, only if color isn't white.
       If color <> RGB(255,255,255)
           xMax = OutputWidth()  - 1
           yMax = OutputHeight() - 1
           
           For y = 0 To yMax
               For x = 0 To xMax
                   c = Point(x, y)
                   
                   i = (c & $FF) << 1 : c >> 8
                   i + (c & $FF) << 2 : c >> 8
                   i + (c & $FF)      : c >> 8
                   
                   Plot(x, y, RGBA(r*i, g*i, b*i, c))
               Next x
           Next y
       EndIf
       
      StopDrawing()
     
   EndIf


I guess for faster transformation, we could use DrawingBuffer() ;)

Edit :

Other ways, faster :D !

Code:
If IsSprite(SpriteId)
     
       StartDrawing(SpriteOutput(Sprite))
       
       ; erase first the sprite
       DrawingMode(#PB_2DDrawing_AllChannels)
       Box(0,0,OutputWidth(),OutputHeight(),RGBA(0,0,0,0))
       ; draw the original image, you need to know what is the sprite image
       DrawingMode(#PB_2DDrawing_AlphaBlend)
       DrawAlphaImage(ImageID(SpriteImg),0,0)
       
       ; then tint the sprite, only if color isn't white.
       If color <> RGB(255,255,255)
           DrawingMode(#PB_2DDrawing_AlphaClip)
           ; you can change the alpha of the rgba color, to get the effect you want.
           Box(0,0,OutputWidth(),OutputHeight(),RGBA(Red(color),Green(color),Blue(color),120))
       EndIf
       
       StopDrawing()
     
EndIf




With a custom filter (you can use a multiply, add, screen, overlay... custom filter for interesting effect ;)):

The custom filter multiply :
Code:
Procedure bm_multiply(x, y, SourceColor, TargetColor)
  ProcedureReturn RGBA((Red(SourceColor)*Red(TargetColor))/255,(Green(SourceColor)*Green(TargetColor))/255,(Blue(SourceColor)*Blue(TargetColor))/255, Alpha(TargetColor)*Alpha(TargetColor)/255)
EndProcedure


Code:
If IsSprite(SpriteId)
     
       StartDrawing(SpriteOutput(Sprite))
       
       ; erase first the sprite
       DrawingMode(#PB_2DDrawing_AllChannels)
       Box(0,0,OutputWidth(),OutputHeight(),RGBA(0,0,0,0))
       ; draw the original image, you need to know what is the sprite image
       DrawingMode(#PB_2DDrawing_AlphaBlend)
       DrawAlphaImage(ImageID(SpriteImg),0,0)
       
       ; then tint the sprite, only if color isn't white.
       If color <> RGB(255,255,255)
           DrawingMode(#PB_2DDrawing_CustomFilter)     
           CustomFilterCallback(@bm_multiply())
           Box(0,0,OutputWidth(),OutputHeight(),Color)
       EndIf
       
       StopDrawing()
     
EndIf


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

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 6 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