Author Topic: More integer blending.  (Read 2601 times)

0 Members and 1 Guest are viewing this topic.

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
More integer blending.
« on: October 31, 2007 »
After a bit of testing I found a few problems with overflows of the colour values in the blending stuff I've been trying but I think I've fixed the problems although there is still a little loss most of the time. This does some more stuff now too:

Code: [Select]
'argb0-3=4 (32 bit) colour of source pixels for bi linear filtering
'dest=32 bit colour of destination
'alpha=8 bit interpolated vertex alpha value
'shade=8 bit interpolated shade value
'u_frac,v_frac=8 bit weights for bi linear filtering
function blend(byval argb0 as unsigned integer,byval argb1 as unsigned integer,_
                byval argb2 as unsigned integer,byval argb3 as unsigned integer,_
                byval dest as unsigned integer,byval alpha as unsigned integer,byval shade as unsigned integer,_
                byval u_frac as unsigned integer,byval v_frac as unsigned integer)as unsigned integer
   
'using both values in the 1-256 range fucks things up
'calculate weights for 4 pixels
    u_frac+=1
    dim as unsigned integer bl=(257-u_frac)*v_frac
    dim as unsigned integer br=u_frac*v_frac
    v_frac=255-v_frac
    dim as unsigned integer tl=(257-u_frac)*v_frac
    dim as unsigned integer tr=u_frac*v_frac
   

'calculate alpha value using supplied alpha and weighted alpha combined
    dim as unsigned integer pa=(((((argb0 shr 24)*tl)+((argb1 shr 24)*tr)+((argb2 shr 24)*bl)+((argb3 shr 24)*br) )*(alpha+1))shr 24)+1
    dim as unsigned integer pma=(257-pa)*(shade+1)
   
'calculate new weights using alpha and shade values
    tr=(tr*pma)shr 24
    tl=(tl*pma)shr 24
    br=(br*pma)shr 24
    bl=(bl*pma)shr 24
   
'do the blending, can remove some of the shr=8 if alpha channel not returned
    dim as unsigned integer _r_b,a_g_
    _r_b=(((argb0 and &hff00ff)*tl)+((argb1 and &hff00ff)*tr)+((argb2 and &hff00ff)*bl)+((argb3 and &hff00ff)*br)  +((dest and &hff00ff)*pa))
    argb0 shr=8
    argb1 shr=8
    argb2 shr=8
    argb3 shr=8
    dest shr=8
    a_g_=(((argb0 and &hff00ff)*tl)+((argb1 and &hff00ff)*tr)+((argb2 and &hff00ff)*bl)+((argb3 and &hff00ff)*br)  +((dest and &hff00ff)*pa))

    return ((_r_b shr 8)and &hff00ff)or(a_g_ and &hff00ff00)
end function

I'm not sure if the alpha value is used the right way round, whether high or low alpha should be transparent but is easy enough to switch it round.

Cheers, Fryer.
« Last Edit: November 01, 2007 by Stonemonkey »

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17409
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: More integer blending.
« Reply #1 on: November 01, 2007 »
I'll have to try this out :) I've used a version of your fast alpha definition for quite some time now from time to time so have some good Karma :)
Shockwave ^ Codigos
Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: More integer blending.
« Reply #2 on: November 01, 2007 »
Thanks, something I'm not sure about is what alpha value should be returned. In opengl what is written to the buffer when alpha write is enabled?

(I'm pretty sure mine is wrong atm, it modulates the supplied (interpolated)alpha with the alpha from the texture then modulates the result with the alpha from the texture again)

Other than that I think it should be fine and if you don't need alpha returned then some of the ops can be removed.

Cheers, Fryer.