Dark Bit Factory & Gravity

PROGRAMMING => Freebasic => Topic started by: Hezad on June 29, 2009

Title: A little snippet : Reflections
Post by: Hezad on June 29, 2009
Heya everyone :D Very long time no see !

Sorry for not being present all that time, I already explained the situation to shockwave so I won't tell all the story here but I just don't code as much as I would.

Anyway, here is a little snippet I coded yesterday, I thought it could interest some of you :) Thanks to duke4e from freebasic forums,  hellfire and Jim from well.. here ;) for the optimisation :)

A screenshot :
(http://narky00.free.fr/Capture-waves.png)


The code :
Code: [Select]
Screenres 320,240,32

Const ZOOM_FACTOR = .003

Type WaveT
    As Single x,y
    As Single Freq
End Type

#include "fbgfx.bi"

Const _reduct = 1/(255*255)
Const _255 = 1/255

Dim Shared As Single t
Dim Shared As WaveT Wave(2)
Dim Shared As Uinteger Pal(255)
Dim Shared As Any Ptr Back
Dim Shared As Uinteger Ptr buffer
Dim Shared As Integer Ptr pixel

buffer = Screenptr()

Wave(0).Freq = .052
Wave(1).Freq = .08
Wave(2).Freq = .086

Back = Imagecreate(320,240)

'From vdecampo post
pixel = back+SizeOf(FB.IMAGE) 'Skip over image header

Bload "blue_sunset.bmp",Back


Sub HandleWaves()
  
    Static As Integer cR,cG,cB,ii,ii2,ii3,jj,rr,gg,bb
    Static As Uinteger col,p
  
    For i As Integer = 0 To 319
     ii = (Wave(0).x-i)*(Wave(0).x-i)
     ii2 = (Wave(1).x-i)*(Wave(1).x-i)
     ii3 = (Wave(2).x-i)*(Wave(2).x-i)
    
        For j As Integer = 0 To 239
            jj = Wave(0).y-j
            cR = 128+127*Cos(ZOOM_FACTOR*(ii + jj*jj)*Wave(0).Freq+t)
            jj = Wave(1).y-j
            cG = 128+127*Cos(ZOOM_FACTOR*(ii2 + jj*jj)*Wave(1).Freq+t)
            jj = Wave(2).y-j
            cB = 128+127*Cos(ZOOM_FACTOR*(ii3 + jj*jj)*Wave(2).Freq+t)
          
            Cr = (Cr+Cg+Cb+(255-Cr)*.5)/3
          
            'p = Point(Abs(i-Cr*.5),Abs(j-Cr*.5),Back)

            'vdecampo
           p = pixel[Cint(Abs(j-Cr*.5f)) * 320 + Cint(Abs(i-Cr*.5f))]
          
            bb = Cr * (p And 255) * _255
            gg = Cr * ((p Shr 8) And 255) * _255
            rr = Cr * ((p Shr 16) And 255) * _255
          
            buffer[i + 320 * j] = Rgb(rr,gg,bb)
          
        Next
    Next
  
End Sub


Do
    Screenlock : Cls
  
    Wave(0).x = 100-80*Cos(t*.1)
    Wave(0).y = 180-120*Sin(t*.5)
    Wave(1).x = 300+50*Cos(t*.4)
    Wave(1).y = 200+40*Sin(t*.2)
    Wave(2).x = 50+10*Cos(t*.3)
    Wave(2).y = 60+130*Sin(t*.2)
  
  
    HandleWaves()
  
    t+=.1
    Screenunlock : Sleep 1,1
Loop Until Multikey(&h01)

Imagedestroy(Back)

 

The background image :
(http://freefile.kristopherw.us/uploads/hezad/blue_sunset.bmp)
(save as "blue_sunset.bmp" in the same folder as the source file. You can use any 320x240 bmp file :) )

Title: Re: A little snippet : Reflections
Post by: Shockwave on June 29, 2009
Thats pretty excellent actually Hezad, if I hadn't seen the bitmap then I would never have guessed what the source picture looked like :)

Oh, and it's totally great to see you again!

Exe attached.. (it still needs the image).
Title: Re: A little snippet : Reflections
Post by: rdc on June 29, 2009
I saw this on the FB forum. Cool stuff.
Title: Re: A little snippet : Reflections
Post by: Hezad on June 29, 2009
Thanks a lot :)

Shockwave >and  thanks for the exe ;)
Title: Re: A little snippet : Reflections
Post by: Jim on June 29, 2009
Very pretty!  Glad to see you back on the scene too. :)

Jim
Title: Re: A little snippet : Reflections
Post by: Clyde on June 29, 2009
welldone Hezad :)
Title: Re: A little snippet : Reflections
Post by: Hezad on June 30, 2009
thanks :buddies:
Title: Re: A little snippet : Reflections
Post by: benny! on June 30, 2009
Nice to see you again, mate!

Very good work. Keep it up!
Title: Re: A little snippet : Reflections
Post by: hellfire on June 30, 2009
Nice one, Hezad!

For each pixel you're calculating the distances to some center-points.
Using multiple square-roots per pixel is quite costly, though.
If you really need floating-point precision you can take advantage of the fact that the change in distance is very small when traversing from one pixel to the next.
So instead of calculating the "complete" square-root, you could use the previous pixel's distance as an estimation and use eg the newton-method (http://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Iterative_methods_for_reciprocal_square_roots) to approximate the current pixel's distance.

Instead of this...
Code: [Select]
For y = 0 To 239
  For x = 0 To 319
    val = x1*x1 + y1*y1
    dist = sqr(val)

...you could try this:
Code: [Select]
For y = 0 To 239
  ' calculate a correct value for the first pixel
  val= x1*x1 + y1*y1
  approx= 1.0 / sqr(val)
  For x = 0 To 319
      val = x1*x1 + y1*y1
      ' estimate the next pixel from the previous approximation
      approx= approx*0.5 * (3.0 - val*approx*approx)
      ' this is required to make it stable
      if approx < 0.0 then approx= 0.0
      val*= approx
Title: Re: A little snippet : Reflections
Post by: Jim on July 01, 2009
Cool idea!

I'd be surprised if the fx looked substantially different if the sqrt(x) were removed completely and replaced with a scale factor, eg. x * 0.007 (guess x in range 0-160, y in range 0-120, so x^2+y^2 approx= 22500 and sqrt(x^2+y^2) approx = 150 implies scale factor of 150/22500=1/150=0.00666.

Jim
Title: Re: A little snippet : Reflections
Post by: Hezad on July 01, 2009
thanks again mates :)

hellfire > One more excellent advice, thanks :) Since Jim's idea (I'll speak about it :) ) suppress the sqrt, I won't use it anymore but it'll be definitely useful for next programs !

Jim > excellent ! the result is almost (if not exactly) the same and no square root to calculate :) Thanks !

(updated code on first post)
Title: Re: A little snippet : Reflections
Post by: spitfire on July 09, 2009
This looks cool, but I cant figure out how it works. Would someone care to explain?
Title: Re: A little snippet : Reflections
Post by: Hezad on July 12, 2009
thanks spitfire :)

Well, it's a combination of a black and white plasma and a background image. The image is drawn on screen but for each point, the program checks the plasma color. It uses the color value to choose a point on the background image : the whiter the plasma is, the farther the program will look for a pixel color on the background image.

Sorry for the poor vocabulary :S
Title: Re: A little snippet : Reflections
Post by: Shockwave on July 12, 2009
Thats a really nice explanation :)
Title: Re: A little snippet : Reflections
Post by: spitfire on July 13, 2009
Yes thats a good explanation thanks. But what about the darker areas at the bottom, since theres no black in the image. Or do you just mix black with the texture colour when the plasma is below a certain threshold?
Title: Re: A little snippet : Reflections
Post by: Hezad on July 13, 2009
In fact, the plasma is not only used to calculate the "displacement" but there's also kind of an alpha blending between the plasma and the background image. White => totally transparent (and max displacement) / Black => no transparency (and min displacement) :)
Title: Re: A little snippet : Reflections
Post by: Hotshot on July 13, 2009
very good and I like that.....You could have rainbow colours  8)

Welldone ;D
Title: Re: A little snippet : Reflections
Post by: Hezad on July 13, 2009
thanks :cheers: