peaceful travel among the stars

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Post Reply
dafhi
Posts: 1741
Joined: Jun 04, 2005 9:51

peaceful travel among the stars

Post by dafhi »

Code: Select all

/' -- peaceful stars - 2025 March 24 - by dafhi

    inspired by a video background

        my compiler option
    -gen gcc -arch native -Wc -Ofast,-mfpmath=sse,-funroll-loops
  
      updates:
      
    simplified imvars
    aadot rather than metaball2d
    background stars more visible over time via iris diameter

'/

'#include "aadot z.bas"
  /' - variably sharp anti-aliased dot - 2024 Dec 29 - by dafhi

  ' usage
screenres 800,600, 32
aa_dot.render_target 0
aa_dot.draw x,y,rgb,rad,edge
'/

'#include "imvars.bas"
' -- imvars.bas - 2025 March 23 - by dafhi

function min( a as double, b as double ) as double
  return iif( a < b, a, b)
end function

function max( a as double, b as double ) as double
  return iif( a > b, a, b)
end function

function clamp( in As double, hi As double = 1, lo As double = 0) As double
  return min( max(in, lo), hi ) '' 2023 June 12
End Function
  
    sub _gfx_release( byref im as any ptr )
      if imageinfo(im) = 0 then imagedestroy im
      im = 0
    end sub


type imvars
    as long       w,h, bypp, pitch,rate
    as any ptr    pixels, im
    as string     driver_name
    
    as long       wm, hm, pitchBy ' custom
    as single     r
end type

    sub fill_imvars( byref i as imvars, im as any ptr = 0)
        if im = 0 then
          _gfx_release i.im
          ScreenInfo i.w, i.h, , i.bypp, i.pitch, i.rate, i.driver_name
          i.pixels = screenptr
        else
          _gfx_release i.im
          ImageInfo im, i.w, i.h, i.bypp, i.pitch, i.pixels
          i.im = im
        end if
        i.r = sqr(i.w^2 + i.h^2) / 2
        i.wm = i.w - 1
        i.hm = i.h - 1
        i.pitchBy = i.pitch \ i.bypp
    end sub


    function triwave( i as single ) as single
      return abs( i - int(i) - .5 ) - .25 ' by Stonemonkey
    end function

    function _cchsv(h as single, s as single, v as single) as ubyte ' 2024 July 24
      var wave_hgt = s * v
      return 255.499 * (wave_hgt * (clamp(triwave(h)*6+.5)-1) + v)
    end function

function hsv( h as single=0, s as single=1, v as single=1, a as ubyte = 255 ) as ulong ' 2024 May 21
      return rgba( _
    _cchsv( h + 0/3, s,v ), _
    _cchsv( h + 2/3, s,v ), _
    _cchsv( h + 1/3, s,v ), a )
end function
' ------------ imvars.bas

' ----- support
'
function sqr_safe( d as double ) as double
    return sgn(d) * sqr( abs(d))
end function

    type t_draw_area field = 2 ' 2 byte elems
      dim as short    x0, y0
      dim as short    x1, y1
      declare operator  cast as string
    end type

operator t_draw_area.cast as string
    return str(x0)+" "+str(y0)+" "+str(x1)+" "+str(y1)
end operator


#Macro Alpha256(ret,back, fore, a256) '2017 Mar 26
  ret=((_
  (fore And &Hff00ff) * a256 + _
  (back And &Hff00ff) * (256-a256) + &H800080) And &Hff00ff00 Or (_
  (fore And &H00ff00) * a256 + _
  (back And &H00ff00) * (256-a256) + &H008000) And &H00ff0000) Shr 8
#EndMacro
'
' ------------ support


    namespace aa_dot
    
dim as imvars _im

    '' 1 of 2 main subs.  other is draw()
    ''
sub render_target( im as any ptr = 0 ) 
    fill_imvars _im, im
end sub
  
  dim as long         scan_x0, scan_x1, final_a
  dim as single       xm5, ym5, xp5, rp5_sq, invert, alpha_sa, edge_iRSq
  dim as single       dySq, dx, dy, rSq
  
  dim as t_draw_area  rc
  
  sub _cliprect( byref rc as t_draw_area, x0 as single, y0 as single, x1 as single, y1 as single )
    rc.x0 = max( 0, int( x0+.0 )) '' +.5 used previously
    rc.y0 = max( 0, int( y0+.0 ))
    rc.x1 = min( _im.wm, int( x1+.0 ))
    rc.y1 = min( _im.hm, int( y1+.0 ))
  end sub

  sub _precalcs( x as single, y as single, c as ulong, r as single, edge as single )
      _cliprect rc,  x - r, y - r, x + r, y + r
      alpha_sa = min(1, edge*r) * 256.499 * (c shr 24) / 255
      rSq = r^2
      edge_irSq = edge * alpha_sa / rSq
      xm5 = x - .5 : xp5 = x + .5 : ym5 = y - .5 : rp5_sq = (r + .5)^2
  end sub
  
  sub _dy_and_scanline_ends( y as single, iy as long, rad as single )
    dy = iy-ym5
    dx = sqr_safe( rp5_sq - dy^2 )
    scan_x0 = max( int(xp5 - dx), rc.x0 ) ' scan segment hugs circle
    scan_x1 = min( int(xm5 + dx), rc.x1 )
    dySq = dy * dy
  end sub
  
  sub _draw( x as single = 0, y as single = 0, c as ulong = -1, rad as single = 5, edge as single = 1 )
        
        for iy as long = rc.y0 to rc.y1
    _dy_and_scanline_ends y, iy, rad
    var pixel = cast( ulong ptr, _im.pixels + iy * _im.pitch ) '' pitch = bytes per scanline
        for ix as long = scan_x0 to scan_x1
    dx = ix - xm5
    invert = rSq - (dx*dx + dySq)
    final_a = min( alpha_sa, edge_irSq * max(0,invert) )
    alpha256( pixel[ix], pixel[ix], c, final_a )
    next
    next
    
  end sub

sub draw( x as single = 0, y as single = 0, c as ulong = -1, rad as single = 5, edge as single = 1 )
    _precalcs x, y, c, rad, edge
    _draw x,y,c,rad,edge
end sub

end namespace ' ---- aadot


'#include "defocus_dot.bas"
    namespace defocus_dot  /' --  2024 Dec 27 - by dafhi '/

dim as single     iris_diam = .09 '' i recommend values close to 1.0 .. (can set elsewhere)
dim as single     focus_z   = 1.5

    dim as single _m, _a

function new_alpha( rad as single, z as single ) as single
  var r_expan = rad + iris_diam * abs(z - focus_z)
  _m = r_expan / rad
  _a = rad^2 / r_expan^2
  return _a
End function
  
function rad_mul( alpha_thresh as single = 1 / 5 ) as single
  
  '' alpha below threshold -> reduced radius (faster draw)
  
  return iif( _a < alpha_thresh, _m * _a / alpha_thresh, _m )
end function

end namespace
  '
    ' --------- defocus_dot


#include "fbgfx.bi" '' for alpha

using FB

type v3
    as single x, y, z
End Type


type t_star
     as v3        pos
     as single    rad, sharpness = 1.75 + rnd * 1.5
     as ulong     color
end type


    namespace demo

const w = 1024, wh = w/2
const h = 768, hh = h/2

var               seconds = 100
var               report_next = 1.5

const             u_stars = 11999

dim as t_star     star(u_stars)

dim as single     general_scale_2d

  sub _initialize_star_common( t as t_star )
      t.pos.x = general_scale_2d*(rnd-.5) * 2.5
      t.pos.y = general_scale_2d*(rnd-.5) * 2.5
      t.color = hsv( rnd, rnd^1, 1 )
      t.rad = general_scale_2d * .08 * (.3 + rnd)
  end sub

  const rand_depth = 16

  sub _dots_z_reset( dt as double )
      for i as long = 0 to u_stars
        if star(i).pos.z <= .03 then
          star(i).pos.z += (defocus_dot.focus_z) * (rand_depth+rnd)
          _initialize_star_common star(i)
        else
          star(i).pos.z -= dt * 0.07
        endif
      next
  end sub
    dim as double     t0, t, tp, dt, dt2 '' fps average helper dt2
    dim as double     info_t1
    dim e as EVENT

sub init
    screenres w,h,32,, fb.gfx_alpha_primitives
    aa_dot.render_target 0
    
    defocus_dot.focus_z       = 1
    
    general_scale_2d          = (wh+hh)*.07
    for i as long = 0 to u_stars
      star(i).pos.z = (0 + rnd * rand_depth)
      _initialize_star_common star(i)
    next
    _dots_z_reset 0
    t0 = Timer :     info_t1 = t0 + 1.5
end sub

    sub _draw_star( t as t_star )
      var z_m = t.pos.z

      if z_m > .04 then
        var a   = defocus_dot.new_alpha( t.rad, z_m )
        var r   = t.rad * defocus_dot.rad_mul / z_m
        
        var z_s = general_scale_2d / z_m
        
        var x = t.pos.x * z_s + wh
        var y = t.pos.y * z_s + hh
        aa_dot.draw x,y, ((255.5*a)shl 24) or (t.color and &HFFFFFF),r, t.sharpness
      endif
    end sub

sub DrawStars
  for i as long = 0 to u_stars
  _draw_star star(i):  next
end sub

end namespace ' --------- demo

    function round(in as double, places as ubyte = 2) as string
      dim as integer mul = 10 ^ places
      return str(csng( int(in * mul + .5) / mul) )
    End Function


randomize

using demo
init

    do

tp = t
t = timer - t0
dt = t - tp

    var fade_in = csng(1.9)*t
defocus_dot.iris_diam = (fade_in + 10) / (fade_in + 1) '' approaches 1.0 as t increases.

    screenlock
cls
DrawStars
screenunlock

if t > report_next then
  var m = str(report_next)
  windowtitle "FPS: " + round( 2 / (dt + dt2) ) + "  TIme left: " + round( seconds - t )
  dt2 = dt
  report_next += 1
endif

if inkey <> "" then end

_dots_z_reset dt

sleep 1

loop while t < seconds

sleep

Last edited by dafhi on Mar 25, 2025 21:56, edited 3 times in total.
dodicat
Posts: 8267
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: peaceful travel among the stars

Post by dodicat »

Thanks Dafhi
Very therapeutic.
Either that, or little bits of plankton down in the abyssal section of the Gulf stream as it progresses towards us, or would it be the American stream now?
deltarho[1859]
Posts: 4702
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: peaceful travel among the stars

Post by deltarho[1859] »

As is often the case with two monitors, the output screen straddles both monitors.

If we insert these three lines immediately following 'ScreenRes' the output screen gets centred on the primary monitor.

Code: Select all

Dim As Long ScreenWidth, ScreenHeight
ScreenControl FB.GET_DESKTOP_SIZE, ScreenWidth, ScreenHeight
ScreenControl FB.SET_WINDOW_POS, (ScreenWidth - w)\2, (ScreenHeight - h)\2

UEZ has added the code to his template for future releases.

With only one monitor, the addition is surplus to requirements.
UEZ
Posts: 1079
Joined: May 05, 2017 19:59
Location: Germany

Re: peaceful travel among the stars

Post by UEZ »

Added:

Code: Select all

/' -- peaceful travel among the stars - 2025 March 7 - by dafhi

inspired by a background in a video i enjoyed

my compiler option
-gen gcc -arch native -Wc -Ofast,-mfpmath=sse,-funroll-loops

'/

'#include "metaball2d.bas"
'#include "imvars.bas"
' -- imvars.bas - 2025 Feb 8 - by dafhi

#include "fbgfx.bi"
Using FB

Sub CenterFBWin(iW As Long, iH As Long, iTBw As Long = 0, iTBh As Long = 0) 'centers the FB-GUI on the primary screen
	Dim As Long iScreenWidth, iScreenHeight
	ScreenControl GET_DESKTOP_SIZE, iScreenWidth, iScreenHeight
	ScreenControl SET_WINDOW_POS, (iScreenWidth - iW) \ 2 - iTBw, (iScreenHeight - iH) \ 2 - iTBh
End Sub


Sub _gfx_release( ByRef im As Any Ptr )
	If ImageInfo(im) = 0 Then ImageDestroy im
	im = 0
End Sub


Type t_image_info
	Declare Destructor
	Dim As Long     w,h, bypp, pitch,rate
	Dim As Any Ptr  pixels, im
	Dim As String   driver_name
End Type

Destructor t_image_info
	_gfx_release im
End Destructor

Sub _get_screen( ByRef i As t_image_info )
	_gfx_release i.im
	ScreenInfo i.w, i.h, , i.bypp, i.pitch, i.rate, i.driver_name
	i.pixels = ScreenPtr
End Sub

Sub _get_image( ByRef i As t_image_info, im As Any Ptr )
	_gfx_release i.im
	ImageInfo im, i.w, i.h, i.bypp, i.pitch, i.pixels
	i.im = im
End Sub

Type imvars Extends t_image_info
	As Long       wm, hm, pitchBy
	As Single     r
End Type

Sub fill_imvars( ByRef imv As imvars, im As Any Ptr = 0)
	If im = 0 Then:  _get_screen imv
	Else:            _get_image imv, im:  End If
	imv.r = Sqr(imv.w^2 + imv.h^2)
	imv.wm = imv.w - 1
	imv.hm = imv.h - 1
	imv.pitchBy = imv.pitch \ imv.bypp
End Sub

#ifndef min
	Function min( a As Double, b As Double ) As Double
		Return IIf( a < b, a, b)
	End Function
	
	Function max( a As Double, b As Double ) As Double
		Return IIf( a > b, a, b)
	End Function
	
	Function clamp( in As Double, hi As Double = 1, lo As Double = 0) As Double
		Return min( max(in, lo), hi ) '' 2023 June 12
	End Function
#endif


Function triwave( i As Single ) As Single
	Return Abs( i - Int(i) - .5 ) - .25 ' by Stonemonkey
End Function

Function _cchsv(h As Single, s As Single, v As Single) As UByte ' 2024 July 24
	Var wave_hgt = s * v
	Return 255.499 * (wave_hgt * (clamp(triwave(h)*6+.5)-1) + v)
End Function

Function hsv( h As Single=0, s As Single=1, v As Single=1, a As UByte = 255 ) As ULong ' 2024 May 21
	Return RGBA( _
	_cchsv( h + 0/3, s,v ), _
	_cchsv( h + 2/3, s,v ), _
	_cchsv( h + 1/3, s,v ), a )
End Function

#macro Alpha256( ret, back, fore, a256) 'blend colors. alpha max = 256  (2024 July 16)
	Scope
		Static As Long _a: _a = (a256)
		ret=((_
		(fore And &Hff00ff) * _a + _
		(back And &Hff00ff) * (256-_a) + &H800080) And &Hff00ff00 Or (_
		(fore And &H00ff00) * _a + _
		(back And &H00ff00) * (256-_a) + &H008000) And &H00ff0000) Shr 8
	End Scope
#endmacro

Union uARGB
	As ULong        col
	Type: As UByte  B,G,R,A
	End Type
End Union
'
' -- imvars.bas

'  metaball2d.bas continued ..

Function sqr_safe( d As Double ) As Double
	Return Sgn(d) * Sqr( Abs(d))
End Function


Type t_draw_area Field = 2 ' 2 byte elems
	Dim As Short    x0, y0
	Dim As Short    x1, y1
	Declare Operator  Cast As String
End Type

Operator t_draw_area.cast As String
	Return Str(x0)+" "+Str(y0)+" "+Str(x1)+" "+Str(y1)
End Operator

Const As Double epsilon = 1e-11


Namespace metaball2d  ' 2024 July 23 - by dafhi
	
	Dim As imvars       im_hsf
	
	Sub render_target( im As Any Ptr = 0 )
		fill_imvars im_hsf, im
	End Sub
	
	Dim As Single         _slope_by_rad, _metaball_alpha, _metaball_alpha_256, _salpha_max
	
	Dim As Long           plot_x, plot_Y
	Dim As Single         dx, dy, dx0, dy0, dySQ, xx, edge_Sq, _rad
	
	Dim As t_draw_area  rc
	Dim As uARGB        col
	
	Sub _metaball_scanLine
		dy = dy0 + _slope_by_rad * (plot_Y - rc.y0)
		dySQ = dy * dy
		Dim As Single f = _rad * sqr_safe( edge_Sq - dySQ )
		Dim As Long   x0 = max( Int(xx - f), rc.x0 )
		Dim As Long   x1 = min( Int(xx + f), rc.x1 )
		dx = dx0 + _slope_by_rad * (x0 - rc.x0)
		Dim As uARGB Ptr p = im_hsf.pixels + plot_Y * im_hsf.pitch
		
		For x As Long = x0 To x1
			Dim As Single       alpha =  _metaball_alpha / ((dx * dx + dySQ)^2 + epsilon)
			
			Dim As Single       lerp = min(_metaball_alpha_256, alpha)
			Alpha256( p[x].col, p[x].col, col.col, lerp )
			dx += _slope_by_rad
		Next
	End Sub
	
	Sub _cliprect_calc( ByRef rc As t_draw_area, x As Single, y As Single, rad As Single )
		rc.x0 = max( Int( x - rad ), 0)
		rc.x1 = min( Int( x + rad ), im_hsf.wm)
		rc.y0 = max( Int( y - rad ), 0)
		rc.y1 = min( Int( y + rad ), im_hsf.hm)
	End Sub
	
	Type metaball_vars
		As Single   x, y, rad, edge ' edge = metaball draw distance.  small value gives hard edge
		As uARGB    uar
	End Type
	
	Sub _draw_metaball( ByRef v As metaball_vars )
		If v.rad * v.edge < .001 Then Exit Sub
		For plot_Y = rc.y0 To rc.y1
			_metaball_scanLine
		Next
	End Sub
	
	
	Sub _rendering_precalcs( ByRef mbv As metaball_vars )
		_cliprect_calc rc, mbv.x, mbv.y, mbv.rad * mbv.edge ' edge = metaball draw distance.  small value gives hard edge
		_slope_by_rad = 1 / mbv.rad
		: edge_Sq = mbv.edge ^ 2
		dx0 = (rc.x0 - mbv.x) * _slope_by_rad
		dy0 = (rc.y0 - mbv.y) * _slope_by_rad
		_metaball_alpha = (mbv.uar.A) * .017
		_metaball_alpha_256 = (mbv.uar.A / 255) * 256.499 ' c++ et al 256.999
		col = mbv.uar : xx = mbv.x : _rad = mbv.rad
	End Sub
	
	Sub Draw( x As Single, y As Single, c As ULong, rad As Single = 10, edge As Single = 1 )
		Static As metaball_vars v : v = Type( x, y, Abs(rad), Abs(edge) * 1.2, c )
		_rendering_precalcs v
		_draw_metaball v
	End Sub
	
End Namespace
'
' ---- metaball2D

'#include "defocus_dot.bas"
Namespace defocus_dot  ' --  2024 Dec 27 - by dafhi
	
	
	Dim As Single     iris_diam = .09 '' i recommend values close to 1.0 .. (can set elsewhere)
	Dim As Single     focus_z   = 1.5
	
	Dim As Single _m, _a
	
	Function new_alpha( rad As Single, z As Single ) As Single
		Var r_expan = rad + iris_diam * Abs(z - focus_z)
		_m = r_expan / rad
		_a = rad^2 / r_expan^2
		Return _a
	End Function
	
	Function rad_mul( alpha_thresh As Single = 1 / 5 ) As Single
		
		'' alpha below threshold -> reduced radius (faster draw)
		
		Return IIf( _a < alpha_thresh, _m * _a / alpha_thresh, _m )
	End Function
	
End Namespace
'
' ---- defocus_dot


#include "fbgfx.bi" '' for alpha

Type v3
	As Single x, y, z
End Type


Namespace demo
	
	Const w = 800, wh = w / 2
	Const h = 600, hh = h / 2
	
	Var               seconds = 100
	Var               report_next = 1.5
	
	Const             u = 29999
	
	Type t_star
		As v3        pos
		As Single    rad
		As ULong     color
	End Type
	
	Dim As t_star     star(u)
	
	Dim As Single     general_scale_2d
	
	Sub _initialize_star_common( t As t_star )
		t.pos.x = general_scale_2d*(Rnd-.5) * 2.5
		t.pos.y = general_scale_2d*(Rnd-.5) * 2.5
		t.color = hsv( Rnd, Rnd^1, 1 )
		t.rad = general_scale_2d * .15 * (.2 + Rnd)
	End Sub
	
	Const rand_depth = 16
	
	Sub _dots_z_reset( dt As Double )
		For i As Long = 0 To u
			If star(i).pos.z <= .03 Then
				star(i).pos.z += (defocus_dot.focus_z) * (rand_depth+Rnd)
				_initialize_star_common star(i)
			Else
				star(i).pos.z -= dt *.4
			End If
		Next
	End Sub
	
	Sub init
		ScreenRes w, h, 32, , FB.gfx_alpha_primitives
		CenterFBWin(w, h, 0, 40)
		metaball2d.render_target 0
		
		defocus_dot.focus_z       = 1
		defocus_dot.iris_diam     = 3
		
		general_scale_2d          = (wh+hh)*.07
		For i As Long = 0 To u
			star(i).pos.z = (0 + Rnd * rand_depth)
			_initialize_star_common star(i)
		Next
		_dots_z_reset 0
	End Sub
	
End Namespace

Function round(in As Double, places As UByte = 2) As String
	Dim As Integer mul = 10 ^ places
	Return Str(CSng( Int(in * mul + .5) / mul) )
End Function


Randomize

Using demo
init

Dim As Double     t0 = Timer, t, tp, dt, dt2 '' fps average helper dt2


Do
	
	tp = t
	t = Timer - t0
	dt = t - tp
	
	ScreenLock
	Cls
	
	For i As Long = 0 To u
		Var z_m = star(i).pos.z
		
		If z_m > .04 Then
			Var a   = defocus_dot.new_alpha( star(i).rad, z_m )
			Var r   = star(i).rad * defocus_dot.rad_mul / z_m
			
			Var z_s = general_scale_2d / z_m
			
			Var x = star(i).pos.x * z_s + wh
			Var y = star(i).pos.y * z_s + hh
			Var edge = 1.
			metaball2d.Draw x,y, ((255.5*a)Shl 24) Or (star(i).color And &HFFFFFF),r, edge
			'    circle (x, y), r, ((255.5*a)shl 24) or (star(i).color and &HFFFFFF),,,, f
		End If
	Next
	ScreenUnlock
	
	If t < .75 Then
		Locate 2,2
	ElseIf t > report_next Then
		Var m = Str(report_next)
		WindowTitle "FPS: " + round( 2 / (dt + dt2) ) + "  TIme left: " + round( seconds - t )
		dt2 = dt
		report_next += 1
	End If
	
	If Inkey <> "" Then End
	
	_dots_z_reset dt
	
	Sleep 1
	
Loop While t < seconds

Sleep
@dafhi: looks nice.
Last edited by UEZ on Mar 07, 2025 22:12, edited 1 time in total.
deltarho[1859]
Posts: 4702
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: peaceful travel among the stars

Post by deltarho[1859] »

Want some complementary sound?

Get a meditation video; preferably low frequency. Run that and minimize. Now run dafhi's code.

Now that is therapeutic.

:)
badidea
Posts: 2636
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: peaceful travel among the stars

Post by badidea »

Cool, I think it needs a spaceship in the center and an options to fire engage the warp drive.
deltarho[1859]
Posts: 4702
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: peaceful travel among the stars

Post by deltarho[1859] »

A departure for me. I looked at meditation flute music. Worked a treat. :)
dafhi
Posts: 1741
Joined: Jun 04, 2005 9:51

Re: peaceful travel among the stars

Post by dafhi »

thanks a bunch, guys!

dodicat .. plankton, um, reminds me of a separate project where i run mutations within limits set by epochs, but my 'creatures' were too simplistic and imo didn't get the vision across. i think i need more traits per entity.

thanks deltarho for the compliment! i discovered new age music in 1987. It was home until i eventually migrated to video game / chiptune. On the subject of graphics, you might also enjoy video of real-time executable Empires, on youtube

badidea .. yep one day it'd be cool to build procedurally-oriented stars and throw in some pewpew. i have decent particle skills too
Lothar Schirm
Posts: 492
Joined: Sep 28, 2013 15:08
Location: Germany

Re: peaceful travel among the stars

Post by Lothar Schirm »

Thank you! Very impressive, peaceful and relaxing :P
deltarho[1859]
Posts: 4702
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: peaceful travel among the stars

Post by deltarho[1859] »

In dafhi's code replace

Code: Select all

var               seconds = 100
with
var               seconds = 20*60
dafhi's code will now run for 20 minutes.

Click on the link and unzip. That will give you a MP4.
Relaxing Flute Music

Execute the MP4 and minimize.

Now run dafhi's edited code.

The MP4 will inject a little more calmness.

Added: The MP4, running in a separate thread of execution, will introduce some extra CPU usage, but not much.
dodicat
Posts: 8267
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: peaceful travel among the stars

Post by dodicat »

Hi dafhi.
Didn't have time to do plankton, so I did PLANKton

Code: Select all


Type v3
    As Double x,y,z
End Type

'standard opengl type cube faces used as the base cube
Dim Shared As V3 basecube(1 To 6,1 To 4)= _
{{(-1,-1,-1),(1,-1,-1),(1,1,-1),(-1,1,-1)},_'front
{(1,-1,-1),(1,-1,1),(1,1,1),(1,1,-1)},_ 'right
{(-1,-1,1),(1,-1,1),(1,1,1),(-1,1,1)},_'back
{(-1,-1,-1),(-1,-1,1),(-1,1,1),(-1,1,-1)},_'left
{(1,1,-1),(1,1,1),(-1,1,1),(-1,1,-1)},_'top
{(1,-1,-1),(1,-1,1),(-1,-1,1),(-1,-1,-1)}}'base

Type cube
    As v3 p(1 To 6,0 To 4)
    As v3 v1,v2 'ends of cube diagonals
    As v3 centre 
    As Long painter(1 To 6)
    Declare Constructor
    Declare Constructor(() As v3)
    As Ulong col(1 To 6)'colour each of six faces
End Type


Constructor cube
End Constructor

Constructor cube(a() As v3)
For r As Long=1 To 6
    For c As Long=1 To 4
        p(r,c)=a(r,c)
    Next
Next
'two corner diagonals
v1=p(1,1)
v2=p(2,3)
centre=Type<v3>((v1.x+v2.x)/2,(v1.y+v2.y)/2,(v1.z+v2.z)/2)
End Constructor

Sub CubeSort(c() As cube)
    For n As Long=Lbound(c) To Ubound(c)-1
        For m As Long=n+1 To Ubound(c)
            If c(n).centre.z<c(m).centre.z Then 
                Swap c(n),c(m)
            End If
        Next
    Next
End Sub

Function Expand(p() As V3,b As Single,shift As V3,i As Integer) As cube
    For n As Integer=Lbound(p,2) To Ubound(p,2)
        p(i,n).x=b*basecube(i,n).x+shift.x
        p(i,n).y=b*basecube(i,n).y+shift.y
        p(i,n).z=b*basecube(i,n).z+shift.z
    Next n
    Return cube(p())
End Function

Function Rotate(c As V3,p As V3,angle As V3,scale As V3=Type<V3>(1,1,1)) As V3
    Dim As Single sx=Sin(angle.x),sy=Sin(angle.y),sz=Sin(angle.z)
    Dim As Single cx=Cos(angle.x),cy=Cos(angle.y),cz=Cos(angle.z)
    Dim As Single dx=p.x-c.x,dy=p.y-c.y,dz=p.z-c.z
    Return Type<V3>((scale.x)*((cy*cz)*dx+(-cx*sz+sx*sy*cz)*dy+(sx*sz+cx*sy*cz)*dz)+c.x,_
    (scale.y)*((cy*sz)*dx+(cx*cz+sx*sy*sz)*dy+(-sx*cz+cx*sy*sz)*dz)+c.y,_
    (scale.z)*((-sy)*dx+(sx*cy)*dy+(cx*cy)*dz)+c.z)
End Function

Function perspective(p As V3,eyepoint As V3) As V3
    Dim As Double   w=1+(p.z/eyepoint.z)
    Return Type<V3>((p.x-eyepoint.x)/w+eyepoint.x,_
    (p.y-eyepoint.y)/w+eyepoint.y,_
    (p.z-eyepoint.z)/w+eyepoint.z)
End Function 

Function createcube(size As Double,centre As v3)As cube
    #define range(f,l) Rnd*((l)-(f))+(f)
    Dim As v3 a(1 To 6,1 To 4)
    For i As Integer=Lbound(basecube,1) To Ubound(basecube,1)
        Expand (a(),size,centre,i)
    Next i
    Var k=cube(a())
    For n As Long=1 To 6
        k.col(n)=Rgb(50+Rnd*200,50+Rnd*200,50+Rnd*200)
    Next n
    var sc=type<v3>(range(.1,.2),range(.1,5),range(.1,1))
    for n as long=1 to 6
        for m as long=1 to 4
            k.p(n,m)=rotate(centre,k.p(n,m),type<v3>(0,0,0),sc)
        next
         
        next
    Return k
End Function


Function rotatecube(g1 As cube,angle As v3) As cube
    Dim As v3 fulcrum=Type<v3>((g1.v1.x+g1.v2.x)/2,(g1.v1.y+g1.v2.y)/2,(g1.v1.z+g1.v2.z)/2)
    Dim As cube tmp1=g1
    tmp1.centre=fulcrum
    Dim As v3 eye=Type(512,678/2,3000)
    Dim As Double cx,cy,cz
    For m As Integer=1 To 6
        cx=0:cy=0:cz=0
        For n As Integer=1 To 4
            tmp1.p(m,n)=Rotate(fulcrum,g1.p(m,n),angle)
            tmp1.p(m,n)=perspective(tmp1.p(m,n),eye)  'apply the eye (perspective)
            'accumulate cx,cy,cz
            cx+=tmp1.p(m,n).x:cy+=tmp1.p(m,n).y:cz+=tmp1.p(m,n).z
        Next n
        cx=cx/4:cy=cy/4:cz=cz/4
        'get face centroid into zero'th index of 2nd. dimension
        tmp1.p(m,0)=Type<v3>(cx,cy,cz)
    Next m
    'rotate the diagonal ends also
    tmp1.v1=Rotate(fulcrum,g1.v1,angle)
    tmp1.v2=Rotate(fulcrum,g1.v2,angle)
    Return tmp1
End Function

Sub movecubes(c() As cube)
    Dim As v3 fulcrum
    For k As Long=1 To Ubound(c)
        For n As Long=1 To 6
            For m As Long=1 To 4
                c(k).p(n,m).z-=20
            Next m
        Next n
        c(k).v1=c(k).p(1,1)
        c(k).v2=c(k).p(2,3)
        fulcrum=Type<v3>((c(k).v1.x+c(k).v2.x)/2,(c(k).v1.y+c(k).v2.y)/2,(c(k).v1.z+c(k).v2.z)/2)
        c(k).centre=fulcrum
    Next k
    
    For k As Long=1 To Ubound(c)
        If c(k).centre.z<-2700 Then
            c(k)=createcube(20,Type<v3>(100+Rnd*700,100+Rnd*500,3000+Rnd*5500))
        End If
    Next k
End Sub

Sub fill(p() As v3,c As Ulong,im As Any Ptr=0)
    #define ub Ubound
    Dim As Long Sy=1e6,By=-1e6,i,j,y,k
    Dim As Single a(Ub(p)+1,1),dx,dy
    For i =0 To Ub(p)
        a(i,0)=p(i).x
        a(i,1)=p(i).y
        If Sy>p(i).y Then Sy=p(i).y
        If By<p(i).y Then By=p(i).y
    Next i
    Dim As Single xi(Ub(a,1)),S(Ub(a,1))
    a(Ub(a,1),0) = a(0,0)
    a(Ub(a,1),1) = a(0,1)
    For i=0 To Ub(a,1)-1
        dy=a(i+1,1)-a(i,1)
        dx=a(i+1,0)-a(i,0)
        If dy=0 Then S(i)=1
        If dx=0 Then S(i)=0
        If dy<>0 Andalso dx<>0 Then S(i)=dx/dy
    Next i
    For y=Sy-1 To By+1
        k=0
        For i=0 To Ub(a,1)-1
            If (a(i,1)<=y Andalso a(i+1,1)>y) Orelse _
            (a(i,1)>y Andalso a(i+1,1)<=y) Then
            xi(k)=(a(i,0)+S(i)*(y-a(i,1)))
            k+=1
        End If
    Next i
    For j=0 To k-2
        For i=0 To k-2
            If xi(i)>xi(i+1) Then Swap xi(i),xi(i+1)
        Next i
    Next j
    For i = 0 To k - 2 Step 2
        Line im,(xi(i)+0,y)-(xi(i+1)+1-0,y),c
    Next i
Next y
End Sub

Sub DrawCubeFace(c As cube,i As Integer,colour As Ulong) 
    Static As v3 p0(3)
    For n As Long=1 To 4 'p0 is zero based array, so fill it correctly
        p0(n-1).x=c.p(i,n).x
        p0(n-1).y=c.p(i,n).y
        p0(n-1).z=c.p(i,n).z
    Next
    fill(p0(),colour)'colour each face
End Sub

Sub FaceSort(array As cube,painter() As Long)
    For p1 As Integer  = 1 To 5
        For p2 As Integer  = p1 + 1 To 6
            If array.p(p1,0).z<array.p(p2,0).z Then Swap painter(p1),painter(p2):Swap array.p(p1,0),array.p(p2,0)
        Next p2
    Next p1
End Sub

Function Regulate(Byval MyFps As Long,Byref fps As Long) As Long
    Static As Double timervalue,lastsleeptime,t3,frames
    Var t=Timer
    frames+=1
    If (t-t3)>=1 Then t3=t:fps=frames:frames=0
    Var sleeptime=lastsleeptime+((1/myfps)-T+timervalue)*1000
    If sleeptime<1 Then sleeptime=1
    lastsleeptime=sleeptime
    timervalue=T
    Return sleeptime
End Function

Sub drawfaces(tmp As cube,painter() As  Long,x() As Ulong)
    Dim As Ulong colour
    For z As Integer=Lbound(tmp.p,1)+3 To Ubound(tmp.p,1)'Paint only the closest three faces of each
        Var p=painter(z)
        colour=x(p)
        Select Case p
        Case 1: DrawCubeFace(tmp,p,colour)
        Case 2: DrawCubeFace(tmp,p,colour)
        Case 3: DrawCubeFace(tmp,p,colour)
        Case 4: DrawCubeFace(tmp,p,colour)
        Case 5: DrawCubeFace(tmp,p,colour)
        Case 6: DrawCubeFace(tmp,p,colour)
        End Select
    Next z
End Sub



Dim As Long numcubes=100

Dim As cube c(1 To numcubes)
Dim As cube tmp(1 To numcubes)
Randomize 2
For n As Long=1 To numcubes
    c(n)=createcube(20,Type<v3>(100+Rnd*600,100+Rnd*500,3000+Rnd*5500))
Next n

'start setting face painting order to default
For n As Long=1 To numcubes
    For m As Long=1 To 6
        c(n).painter(m)=m
    Next m
Next n

Dim As Long fps
Dim As Double a
Dim As v3 angle(1 To numcubes)
Dim As Double rnds(1 To numcubes)
For n As Long=1 To numcubes
    rnds(n)=(Rnd-Rnd)
Next n

Screenres 1024,768,32
width 1024\8,768\16
color ,rgb(0,0,30)


Do
    a+=.05
    
    For n As Long=1 To numcubes
        angle(n)=Type<v3>(rnds(n)*a,(rnds(n)-rnds(n))*a*3,-rnds(n)*a)
    Next n
    
    For n As Long=1 To numcubes
        tmp(n)= rotatecube(c(n),angle(n))
    Next n
    
    
    'reset face painting order
    For n As Long=1 To numcubes
        For m As Long=1 To 6
            tmp(n).painter(m)=m
        Next m
    Next n
    Screenlock
    Cls
    Draw String(10,30),"Frame Rate = " & fps,rgb(255,255,255)
    
    'sort the face centriods and cubes by .z value of centriods
    CubeSort(tmp())
    For n As Long=1 To numcubes
        FaceSort(tmp(n),tmp(n).painter())
    Next n
    
    For n As Long=1 To numcubes
        drawfaces(tmp(n),tmp(n).painter(),tmp(n).col()) 'c(2) is the moveable cube, so it is sent for adjustment
    Next n
    
    movecubes(c())
    'drawfaces(c(2),tmp(2),tmp(2).painter(),m,tmp(2).col()) 'm is the mouse
    
    Screenunlock
    
    Sleep regulate(60,fps),1
Loop Until Inkey=Chr(27)


  
deltarho[1859]
Posts: 4702
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: peaceful travel among the stars

Post by deltarho[1859] »

Nice one dodicat. You graphics guys never cease to amaze me.

Multiple monitor issue again.

See UEZ's adaption of my code above to place output on the primary monitor.
dodicat
Posts: 8267
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: peaceful travel among the stars

Post by dodicat »

Here is the PLANKton in opengl smoothed polygons:

Code: Select all

#include "GL/gl.bi"
Dim Shared As long xres,yres


Sub setup Constructor 'for antialiasing polygons
    Screenres 1024,768,32,,2'= GFX_OPENGL
    Screeninfo xres,yres
    glEnable(GL_POLYGON_SMOOTH)
    glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST)
    glEnable(GL_BLEND)
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
    glOrtho 0, xres, yres,0,-1, 1
    glclearcolor 0,0,.2,1
End Sub



Type v3
    As Double x,y,z
End Type

'standard opengl type cube faces used as the base cube
Dim Shared As V3 basecube(1 To 6,1 To 4)= _
{{(-1,-1,-1),(1,-1,-1),(1,1,-1),(-1,1,-1)},_'front
{(1,-1,-1),(1,-1,1),(1,1,1),(1,1,-1)},_ 'right
{(-1,-1,1),(1,-1,1),(1,1,1),(-1,1,1)},_'back
{(-1,-1,-1),(-1,-1,1),(-1,1,1),(-1,1,-1)},_'left
{(1,1,-1),(1,1,1),(-1,1,1),(-1,1,-1)},_'top
{(1,-1,-1),(1,-1,1),(-1,-1,1),(-1,-1,-1)}}'base

Type cube
    As v3 p(1 To 6,0 To 4)
    As v3 v1,v2 'ends of cube diagonals
    As v3 centre 
    As Long painter(1 To 6)
    Declare Constructor
    Declare Constructor(() As v3)
    As Ulong col(1 To 6)'colour each of six faces
End Type


Constructor cube
End Constructor

Constructor cube(a() As v3)
For r As Long=1 To 6
    For c As Long=1 To 4
        p(r,c)=a(r,c)
    Next
Next
'two corner diagonals
v1=p(1,1)
v2=p(2,3)
centre=Type<v3>((v1.x+v2.x)/2,(v1.y+v2.y)/2,(v1.z+v2.z)/2)
End Constructor

Sub CubeSort(c() As cube)
    For n As Long=Lbound(c) To Ubound(c)-1
        For m As Long=n+1 To Ubound(c)
            If c(n).centre.z<c(m).centre.z Then 
                Swap c(n),c(m)
            End If
        Next
    Next
End Sub

Function Expand(p() As V3,b As Single,shift As V3,i As Integer) As cube
    For n As Integer=Lbound(p,2) To Ubound(p,2)
        p(i,n).x=b*basecube(i,n).x+shift.x
        p(i,n).y=b*basecube(i,n).y+shift.y
        p(i,n).z=b*basecube(i,n).z+shift.z
    Next n
    Return cube(p())
End Function

Function Rotate(c As V3,p As V3,angle As V3,scale As V3=Type<V3>(1,1,1)) As V3
    Dim As Single sx=Sin(angle.x),sy=Sin(angle.y),sz=Sin(angle.z)
    Dim As Single cx=Cos(angle.x),cy=Cos(angle.y),cz=Cos(angle.z)
    Dim As Single dx=p.x-c.x,dy=p.y-c.y,dz=p.z-c.z
    Return Type<V3>((scale.x)*((cy*cz)*dx+(-cx*sz+sx*sy*cz)*dy+(sx*sz+cx*sy*cz)*dz)+c.x,_
    (scale.y)*((cy*sz)*dx+(cx*cz+sx*sy*sz)*dy+(-sx*cz+cx*sy*sz)*dz)+c.y,_
    (scale.z)*((-sy)*dx+(sx*cy)*dy+(cx*cy)*dz)+c.z)
End Function

Function perspective(p As V3,eyepoint As V3) As V3
    Dim As Double   w=1+(p.z/eyepoint.z)
    Return Type<V3>((p.x-eyepoint.x)/w+eyepoint.x,_
    (p.y-eyepoint.y)/w+eyepoint.y,_
    (p.z-eyepoint.z)/w+eyepoint.z)
End Function 

Function createcube(size As Double,centre As v3)As cube
    #define range(f,l) Rnd*((l)-(f))+(f)
    Dim As v3 a(1 To 6,1 To 4)
    For i As Integer=Lbound(basecube,1) To Ubound(basecube,1)
        Expand (a(),size,centre,i)
    Next i
    Var k=cube(a())
    For n As Long=1 To 6
        k.col(n)=Rgb(50+Rnd*200,50+Rnd*200,50+Rnd*200)
    Next n
    var sc=type<v3>(range(.1,.2),range(.1,5),range(.1,1))
    for n as long=1 to 6
        for m as long=1 to 4
            k.p(n,m)=rotate(centre,k.p(n,m),type<v3>(0,0,0),sc)
        next
         
        next
    Return k
End Function


Function rotatecube(g1 As cube,angle As v3) As cube
    Dim As v3 fulcrum=Type<v3>((g1.v1.x+g1.v2.x)/2,(g1.v1.y+g1.v2.y)/2,(g1.v1.z+g1.v2.z)/2)
    Dim As cube tmp1=g1
    tmp1.centre=fulcrum
    Dim As v3 eye=Type(512,678/2,3000)
    Dim As Double cx,cy,cz
    For m As Integer=1 To 6
        cx=0:cy=0:cz=0
        For n As Integer=1 To 4
            tmp1.p(m,n)=Rotate(fulcrum,g1.p(m,n),angle)
            tmp1.p(m,n)=perspective(tmp1.p(m,n),eye)  'apply the eye (perspective)
            'accumulate cx,cy,cz
            cx+=tmp1.p(m,n).x:cy+=tmp1.p(m,n).y:cz+=tmp1.p(m,n).z
        Next n
        cx=cx/4:cy=cy/4:cz=cz/4
        'get face centroid into zero'th index of 2nd. dimension
        tmp1.p(m,0)=Type<v3>(cx,cy,cz)
    Next m
    'rotate the diagonal ends also
    tmp1.v1=Rotate(fulcrum,g1.v1,angle)
    tmp1.v2=Rotate(fulcrum,g1.v2,angle)
    Return tmp1
End Function

Sub movecubes(c() As cube)
    Dim As v3 fulcrum
    For k As Long=1 To Ubound(c)
        For n As Long=1 To 6
            For m As Long=1 To 4
                c(k).p(n,m).z-=20
            Next m
        Next n
        c(k).v1=c(k).p(1,1)
        c(k).v2=c(k).p(2,3)
        fulcrum=Type<v3>((c(k).v1.x+c(k).v2.x)/2,(c(k).v1.y+c(k).v2.y)/2,(c(k).v1.z+c(k).v2.z)/2)
        c(k).centre=fulcrum
    Next k
    
    For k As Long=1 To Ubound(c)
        If c(k).centre.z<-2700 Then
            c(k)=createcube(20,Type<v3>(100+Rnd*700,100+Rnd*500,3000+Rnd*5500))
        End If
    Next k
End Sub

Sub fill(p() as v3,c as ulong,al as ubyte=255)
             Var clr=Cptr(Ubyte Ptr,@c)
            glcolor4ub(clr[2],clr[1],clr[0],al)
            glBegin(GL_POLYGON)
            for n as long=0 to ubound(p)
                glVertex2f(p(n).x,p(n).y)
                next n
			glEnd( )
            end sub

Sub DrawCubeFace(c As cube,i As Integer,colour As Ulong) 
    Static As v3 p0(3)
    For n As Long=1 To 4 'p0 is zero based array, so fill it correctly
        p0(n-1).x=c.p(i,n).x
        p0(n-1).y=c.p(i,n).y
        p0(n-1).z=c.p(i,n).z
    Next
    fill(p0(),colour)'colour each face
End Sub

Sub FaceSort(array As cube,painter() As Long)
    For p1 As Integer  = 1 To 5
        For p2 As Integer  = p1 + 1 To 6
            If array.p(p1,0).z<array.p(p2,0).z Then Swap painter(p1),painter(p2):Swap array.p(p1,0),array.p(p2,0)
        Next p2
    Next p1
End Sub

Function Regulate(Byval MyFps As Long,Byref fps As Long) As Long
    Static As Double timervalue,lastsleeptime,t3,frames
    Var t=Timer
    frames+=1
    If (t-t3)>=1 Then t3=t:fps=frames:frames=0
    Var sleeptime=lastsleeptime+((1/myfps)-T+timervalue)*1000
    If sleeptime<1 Then sleeptime=1
    lastsleeptime=sleeptime
    timervalue=T
    Return sleeptime
End Function

Sub drawfaces(tmp As cube,painter() As  Long,x() As Ulong)
    Dim As Ulong colour
    For z As Integer=Lbound(tmp.p,1)+3 To Ubound(tmp.p,1)'Paint only the closest three faces of each
        Var p=painter(z)
        colour=x(p)
        Select Case p
        Case 1: DrawCubeFace(tmp,p,colour)
        Case 2: DrawCubeFace(tmp,p,colour)
        Case 3: DrawCubeFace(tmp,p,colour)
        Case 4: DrawCubeFace(tmp,p,colour)
        Case 5: DrawCubeFace(tmp,p,colour)
        Case 6: DrawCubeFace(tmp,p,colour)
        End Select
    Next z
End Sub

Sub drawstring(xpos As Long,ypos As Long,text As String ,col As Ulong,size As Single,xres As Long,yres As Long) Export
    glMatrixMode GL_PROJECTION 'save projection
    glPushMatrix
    glMatrixMode GL_MODELVIEW
    glPushMatrix
    
    glMatrixMode GL_PROJECTION 'make ortho
    glLoadIdentity
    glOrtho 0, xres, yres, 0,-1, 1
    glMatrixMode GL_MODELVIEW
    glLoadIdentity
    #define Red(c) ((c) Shr 16 And 255)
    #define Green(c) ((c) Shr  8 And 255)
    #define Blue(c) ((c) And 255)
    #define Alph(c) ((c) Shr 24)
    glColor4ub Red(col),Green(col),Blue(col),alph(col)
    glend
    glpointsize(1.1*size)
    glBegin (GL_POINTS)
    Type D2
        As Single x,y
    End Type
    Static As d2 cpt(),XY()
    Static As Long runflag
    If runflag=0 Then   
        Redim  XY(128,127)
        Redim cpt(1 To 64*2)
        Screen 8
        Width 640\8,200\16
        Dim As Ulong Pointer img
        Dim count As Long
        For ch As Long=1 To 127
            img=Imagecreate(640,200)
            Draw String img,(1,1),Chr(ch)
            For x As Long=1 To 8 
                For y As Long=1 To 16
                    If Point(x,y,img)<>0 Then
                        count=count+1
                        XY(count,ch)=Type<D2>(x,y)
                    End If
                Next y
            Next x
            count=0
            Imagedestroy img
        Next ch
        runflag=1
    End If
    If size=0 Then Exit Sub
    Dim As D2 np,t
    #macro Scale(p1,p2,d)
    np.x=d*(p2.x-p1.x)+p1.x
    np.y=d*(p2.y-p1.y)+p1.y
    #endmacro
    
    Dim As D2 c=Type<D2>(xpos,ypos)
    Dim As Long dx=xpos,dy=ypos
    For z6 As Long=1 To Len(text)
        Var asci=text[z6-1]
        For _x1 As Long=1 To 64*2
            t=Type<D2>(XY(_x1,asci).x+dx,XY(_x1,asci).y+dy)         
            Scale(c,t,size)
            cpt(_x1)=np
            
            If XY(_x1,asci).x<>0 Then
                If Abs(size)>0 Then
                    glVertex3f (cpt(_x1).x,(cpt(_x1).y),0)
                End If
            End If
        Next _x1
        dx=dx+8
    Next z6
    glend
    glMatrixMode GL_PROJECTION 'restore 
    glPopMatrix
    glMatrixMode GL_MODELVIEW
    glPopMatrix
End Sub

Sub inittext Constructor
    drawstring(0,0,"",0,0,0,0)
End Sub





Dim As Long numcubes=100

Dim As cube c(1 To numcubes)
Dim As cube tmp(1 To numcubes)
Randomize 2
For n As Long=1 To numcubes
    c(n)=createcube(20,Type<v3>(100+Rnd*900,100+Rnd*600,3000+Rnd*5500))
Next n

'start setting face painting order to default
For n As Long=1 To numcubes
    For m As Long=1 To 6
        c(n).painter(m)=m
    Next m
Next n

Dim As Long fps
Dim As Double a
Dim As v3 angle(1 To numcubes)
Dim As Double rnds(1 To numcubes)
For n As Long=1 To numcubes
    rnds(n)=(Rnd-Rnd)
Next n

Do
    a+=.05
    
    For n As Long=1 To numcubes
        angle(n)=Type<v3>(rnds(n)*a,(rnds(n)-rnds(n))*a*3,-rnds(n)*a)
    Next n
    
    For n As Long=1 To numcubes
        tmp(n)= rotatecube(c(n),angle(n))
    Next n
    
    
    'reset face painting order
    For n As Long=1 To numcubes
        For m As Long=1 To 6
            tmp(n).painter(m)=m
        Next m
    Next n
   
   ' Draw String(10,30),"Frame Rate = " & fps,rgb(255,255,255)
    
    'sort the face centriods and cubes by .z value of centriods
    CubeSort(tmp())
    For n As Long=1 To numcubes
        FaceSort(tmp(n),tmp(n).painter())
    Next n
     glClear(GL_COLOR_BUFFER_BIT)
      drawstring(10,30,"Frame Rate = " &fps,rgb(255,255,255),2,xres,yres)
    For n As Long=1 To numcubes
        drawfaces(tmp(n),tmp(n).painter(),tmp(n).col()) 
    Next n
    
    movecubes(c())
  
    flip
    
    Sleep regulate(60,fps),1
Loop Until Inkey=Chr(27)


   
Post Reply