Magic Procedural Forest...

Miscellaneous Forums/Blitz Showcase/Magic Procedural Forest...

MERRY CHRISTMAS everyone! :)

Just had a funny idea about making a procedural tree for my little painter. I sometimes make little test routines outside to check if an idea works. This time it was too freaking funny and somehow cool to just keep it hidden.

...for a more elaborate version:
HAPPY TREES (happy_trees.zip)

SuperStrict
'======================================================='
'magic procedural forest - www.Taron.de (christmas 2008)'
'======================================================='
Framework brl.d3d7Max2D
Import brl.random

SetGraphicsDriver D3D7Max2DDriver()
Graphics 800,600,0,60
SeedRnd MilliSecs()

Global brush:TPixmap = CreatePixmap(100,100,PF_RGBA8888)
For Local y:Float = 0 Until 100
	For Local x:Float = 0 Until 100
		Local a:Int = 0
		Local ix:Float = x-50
		Local iy:Float = y-50
		Local dot:Float = ix*ix + iy*iy
		If dot Then dot = Sqr(dot)
		If dot >50.0 Then dot = 50
		dot:*5.1
		a = 255-dot
		ix = x-20
		iy = y-40
		dot = ix*ix + iy*iy
		If dot Then dot = Sqr(dot)
		If dot >100.0 Then dot = 100.0
		If dot <0 Then dot = 0.0
			
		Local col:Int = (100-dot)*2
		brush.WritePixel(x,y,col|col Shl 8|col Shl 16|a Shl 24)
	Next
Next

Type branch
	Global list:TList = CreateList()
	Field x:Float
	Field y:Float
	Field dx:Float
	Field dy:Float
	Field size:Float
	Field img:TImage = LoadImage(brush)
	
	Method grow()
		SetScale size^2,size^2
		DrawImage(img,x,y)
		
		x:+dx*size
		y:+dy*size
		size:*(0.97+Rnd(0,0.04))
		dx:+Rnd(-0.85,0.85)
		dy:+Rnd(-0.5,0.5)
		If Rnd(0,10)<-0.1+(1.0-size) And size > 0.3 Then Create(list,x,y,Rnd(-1.0,1.0),dy,size)
		If size<0.1 Then list.Remove(Self)
	End Method
	
	Function Create:branch(list:TList, x:Int, y:Int, dx:Int, dy:Int, size:Float)
		Local b:branch = New branch
		b.x = x
		b.y = y
		b.dx = dx
		b.dy = dy
		b.size = size
		b.img = LoadImage(brush)
		ListAddLast list,b
		Return b
	End Function
End Type

Local c:Int = 0

SetBlend ALPHABLEND
SetAlpha 1.0
SetColor 0,0,0
SetScale 1.0,1.0

SetClsColor 30,60,90
Cls
Repeat 
For Local tree:branch = EachIn branch.list; tree.grow();Next
If branch.list.Count() = 0 And c < 255 Then branch.Create(branch.list,Rnd(0,800),Rnd(550,650),0,-4,1.0);c:+2;SetColor c,c*Rnd(0.7,0.9),c*Rnd(0.3,0.6)
Flip 0
Until KeyHit(KEY_ESCAPE)



Have fun and happy holidays!

Interesting and if you add some watery effects it will look more like an algae forest.

Barney

Nice algo. And i agree with Barnabius, it looks somehow more like underwater plants. Nevertheless those which are drawn till outside the top of the screen are looking like quite good trees.

Niiiice...it would make a wonderful screensaver. I really had fun watching as creepy trees rise beyond me :D

You can also make a 2D tree generator / sprite generator that saves alpha'd pngs.

Turn down the alpha right before the repeat to like 0.1 and you'll have really an underwater coral reef thingy! ;)

Yeah, that's the idea, Mortiis, in some regards. I want it to be a painting feature, just for fun. I'm just too lazy to always draw my trees. I'll give only very few parameters to keep it simple and instead make a few presets for different types of trees. I'll put in a way to let gesture affect the treegrowth so it keeps a personal touch, you know.

More than anything, you can have all the fun you can think of with it! It's my christmas present to all of you and it's hopefully one that keeps on giving! 8)))

THANK YOU, by the way, I'm happy you like it, too!

Here's a little underwater variation:
SuperStrict
'======================================================='
'magic procedural forest - www.Taron.de (christmas 2008)'
'======================================================='
Framework brl.d3d7Max2D
Import brl.random
Import brl.eventqueue

SetGraphicsDriver D3D7Max2DDriver()
Graphics 800,600,0,60
SeedRnd MilliSecs()
SetWindowTextA( pub.win32.GetActiveWindow(),"procedural corals" )

Global brush:TPixmap = CreatePixmap(100,100,PF_RGBA8888)
For Local y:Float = 0 Until 100
	For Local x:Float = 0 Until 100
		Local a:Int = 0
		Local ix:Float = x-50
		Local iy:Float = y-50
		Local dot:Float = ix*ix + iy*iy
		If dot Then dot = Sqr(dot)
		If dot >50.0 Then dot = 50
		dot:*5.1
		a = 255-dot
		ix = x-20
		iy = y-40
		dot = ix*ix + iy*iy
		If dot Then dot = Sqr(dot)
		If dot >100.0 Then dot = 100.0
		If dot <0 Then dot = 0.0
			
		Local col:Int = (100-dot)*2
		brush.WritePixel(x,y,col|col Shl 8|col Shl 16|a Shl 24)
	Next
Next
Global bg:TPixmap = CreatePixmap(1,600,pf_rgba8888)
For Local y:Float = 0 Until 600
	Local r:Int = Int((1.0-y/600)*$5f) & $ff
	Local g:Int = Int((1.0-y/780)*$ff) & $ff
	Local b:Int = Int((1.0-y/800)*$ff) & $ff
	bg.WritePixel(0,y,b|g Shl 8|r Shl 16|255 Shl 24)
Next
Global bgi:timage = LoadImage(bg)

Type branch
	Global list:TList = CreateList()
	Field x:Float
	Field y:Float
	Field dx:Float
	Field dy:Float
	Field size:Float
	Field img:TImage = LoadImage(brush)
	
	Method grow()
		SetScale size^2,size^2
		DrawImage(img,x,y)
		
		x:+dx*size
		y:+dy*size
		size:*(0.97+Rnd(0,0.04))
		dx:+Rnd(-0.85,0.85)
		dy:+Rnd(-0.5,0.5)
		If Rnd(0,10)<-0.1+(1.0-size) And size > 0.3 Then Create(list,x,y,Rnd(-1.0,1.0),dy,size)
		If size<0.1 Then list.Remove(Self)
	End Method
	
	Function Create:branch(list:TList, x:Int, y:Int, dx:Int, dy:Int, size:Float)
		Local b:branch = New branch
		b.x = x
		b.y = y
		b.dx = dx
		b.dy = dy
		b.size = size
		b.img = LoadImage(brush)
		ListAddLast list,b
		Return b
	End Function
End Type

Local r:Int = 255
Local g:Int = 255
Local b:Int = 255

SetBlend ALPHABLEND
SetAlpha 1.0
SetColor 155,155,155
SetScale 1.0,1.0
DrawImageRect(bgi,0,0,800,600)

Repeat 
	Local Event:TEvent = CurrentEvent
	event.id = PollEvent()
	If event.id = 259 Then Exit
	SetAlpha 0.8
	SetColor r,g*Rnd(0.8,0.99),b*Rnd(0.7,0.9)
	For Local tree:branch = EachIn branch.list; tree.grow();Next
	If branch.list.Count() = 0 
		branch.Create(branch.list,Rnd(0,800),Rnd(550,650),0,-4,0.7)
		SetAlpha 0.05
		SetColor Rnd(0,155),155,155'30,60,90
		SetScale 1,1
		DrawImageRect(bgi,0,0,800,600)
		g = Rnd(150,255)
		b = Rnd(50,200)
	EndIf	
	Flip 0
Until KeyHit(KEY_ESCAPE)



How do you come up with this stuff?

Fascinating. Some of you might see a massive speed increase if you switch the driver to OpenGL.

Well, amazingly it's the same process of learing to make any kind of art. Spend time by looking at things around you in nature! There are countless things that can inspire in endless amounts of ways. It's, however, easiest, when you want to do something specific. To achive it you look left and right as you walk forward and you practically grab things from the wayside, so to say. The rest is just logic. :)

I've changed the threshold/cutoff time for the branches to a size < 0.1 which is small enough. New trees/corals will grow earlier. Switch flip to flip 1, if you'd like to see the things grow! Kinda fun, too...

Thanks, Plash!

Great stuff!

Fish make it an even better reef.


SuperStrict
'======================================================='
'magic procedural forest - www.Taron.de (christmas 2008)'
'======================================================='
Framework brl.d3d7Max2D
Import brl.random
Import brl.eventqueue

SetGraphicsDriver D3D7Max2DDriver()
Graphics 800,600,0,60
SeedRnd MilliSecs()
SetWindowTextA( pub.win32.GetActiveWindow(),"procedural corals" )

Global brush:TPixmap = CreatePixmap(100,100,PF_RGBA8888)
For Local y:Float = 0 Until 100
	For Local x:Float = 0 Until 100
		Local a:Int = 0
		Local ix:Float = x-50
		Local iy:Float = y-50
		Local dot:Float = ix*ix + iy*iy
		If dot Then dot = Sqr(dot)
		If dot >50.0 Then dot = 50
		dot:*5.1
		a = 255-dot
		ix = x-20
		iy = y-40
		dot = ix*ix + iy*iy
		If dot Then dot = Sqr(dot)
		If dot >100.0 Then dot = 100.0
		If dot <0 Then dot = 0.0
			
		Local col:Int = (100-dot)*2
		brush.WritePixel(x,y,col|col Shl 8|col Shl 16|a Shl 24)
	Next
Next
Global bg:TPixmap = CreatePixmap(1,600,pf_rgba8888)
For Local y:Float = 0 Until 600
	Local r:Int = Int((1.0-y/600)*$5f) & $ff
	Local g:Int = Int((1.0-y/780)*$ff) & $ff
	Local b:Int = Int((1.0-y/800)*$ff) & $ff
	bg.WritePixel(0,y,b|g Shl 8|r Shl 16|255 Shl 24)
Next
Global bgi:timage = LoadImage(bg)

Type branch
	Global list:TList = CreateList()
	Field x:Float
	Field y:Float
	Field dx:Float
	Field dy:Float
	Field size:Float
	Field img:TImage = LoadImage(brush)
	
	Method grow()
		SetScale size^2,size^2
		DrawImage(img,x,y)
		
		x:+dx*size
		y:+dy*size
		size:*(0.97+Rnd(0,0.04))
		dx:+Rnd(-0.85,0.85)
		dy:+Rnd(-0.5,0.5)
		If Rnd(0,10)<-0.1+(1.0-size) And size > 0.3 Then Create(list,x,y,Rnd(-1.0,1.0),dy,size)
		If size<0.1 Then list.Remove(Self)
	End Method
	
	Function Create:branch(list:TList, x:Int, y:Int, dx:Int, dy:Int, size:Float)
		Local b:branch = New branch
		b.x = x
		b.y = y
		b.dx = dx
		b.dy = dy
		b.size = size
		b.img = LoadImage(brush)
		ListAddLast list,b
		Return b
	End Function
End Type

Local r:Int = 255
Local g:Int = 255
Local b:Int = 255

SetBlend ALPHABLEND
SetAlpha 1.0
SetColor 155,155,155
SetScale 1.0,1.0
DrawImageRect(bgi,0,0,800,600)

Local fish:Byte = 0 
Repeat 
	Local Event:TEvent = CurrentEvent
	event.id = PollEvent()
	If event.id = 259 Then Exit
	SetAlpha 0.8
	SetColor r,g*Rnd(0.8,0.99),b*Rnd(0.7,0.9)
	For Local tree:branch = EachIn branch.list; tree.grow();Next
	If branch.list.Count() = 0 
		branch.Create(branch.list,Rnd(0,800),Rnd(550,650),0,-4,0.7)
		SetAlpha 0.05
		SetColor Rnd(0,155),155,155'30,60,90
 		SetScale 1,1
		DrawImageRect(bgi,0,0,800,600)
		g = Rnd(150,255)
		b = Rnd(50,200)
	EndIf	
	 
      fish=fish+1
	If fish=0 Then  
	SetScale 1,1
      SetColor 255,255,255 
      DrawText "Fish",Rnd(0,800),Rnd(0,600) 
      If fish = 10 Then fish=0
      EndIf 
	Flip 0
Until KeyHit(KEY_ESCAPE)


Cool stuff Taron.

Why do you use SetWindowTextA?

You can just use AppTitle (just put it before your graphics command)...

SuperStrict
AppTitle = "Pixel Test"
Graphics 800,600,0
Local time% = 0
Local stepper%=0
Repeat
	Local r% = Rand(0,255)
	Local g% = Rand(0,255)
	Local b% = Rand(0,255)
	SetColor r,g,b
	Plot Rand(0,800),Rand(0,600)
	
	' flip every 1/4 second
	 If MilliSecs()-time>250
		stepper=0
		time=MilliSecs()
		Flip
	Else
		stepper:+1
	EndIf	
Until KeyHit(KEY_ESCAPE)


UH, HAHAHA! Thanks, I didn't know! I'm trying to figure things out by myself as much as possible and just came across the whole windows command section during a debug. But, yeah, that looks a bit easier, haha!

THANKS! 8)

Try the Happy Trees now...

...I've added quite a few things and believe it's getting really trippy!

shortcuts:
t: take a fancy snapshot and save it as .png
b: blur on/off

...well, it's all in the app title!

Happy Trees.zip

iam a Happy Tree Friend ;)

cool thanks for sharing

That is some talent there! I am shure what we are seeing is just the tip of the iceberg. Dito, Thanks for sharing.

this looks really coolio! nice job!

this is friggin awesome! Nice job man

THANKS everyone! I'm thrilled enough by it to continue with it a little bit.

Just updated the zip today!

(...maybe I give it version numbers?!)

2 therevills:
AppTitle only allows you to change the title once in the beginning. The SetWindowTextA function allows you to change it anytime. The new version shows the on/off status of "blur" and "leaves" up in the title! ;)

(...yes you can switch the leaves on/off now, too!)

2 Jesse:
Well, I somehow like to start with the tip, hahaha, haha. But considering my painter/animator you are perfectly right. It's already lots of fun and once I put the tree making into it, it'll be something else completely! I have a number of very curious ideas in that regard! 8)

Thats pretty cool. Would make a good screensaver :)

Nice, but like others, I am not touching EXEs posted on this forum for a while.

I'm willing to accept the challenge to turn this into a screen saver ( I do have some experience :-) ).

So Taron if you're willing to open up the source then let me know...

This would be a gorgeous screensaver.

Wow, well, no worries in regards to my exes. I'm one of them radicals, who would like to send virus or otherwise malicious code creators to explorations about the human resilliance to the arctic ocean in the nude and the presence of a set of hungry orcas. 8}

Hey Boiled (very nice name!),
I only had a bit of trouble with the backbuffer on some gfxboards, on laptops in this case. Could be only some funny defaults, hopefully. Other than that I guess I would simply hide the window to let it run in the background, waiting for nothing to happen for a given amount of time. Should be fairly easy, but thank you so much for your offer! I think it's great. Maybe one day we'll all do something together, would be fun (...and horrific chaos, I'm sure!)! I think I'll tackle this one for a bit longer, though. Should I run into troubles, I'd be really happy, if you wouldn't mind a lil' chat, hehe.

Taron,

no problem, please check check out my commercial screen savers here - http://www.boiledsweets.com They run in the preview window and are highly configurable, not just exe's renamed to scr. Also proper screen savers flag to windows that a screen saver is running. You should let windows fire up the screen saver else it will be running in background all the time, not nice!!!

Anyhow please release an exe that detects the desktop resolution and runs in that size in full screen, thanks in advance...

As for trojans, use a decent AV/T product like Kapersky!

Awesome, thanks! Looks like there's really something very cool for me to learn! Well...hmmm...or we could make it a tiny joined-venture...hmmm...I'd say we should talk about it! Feel free to email me anytime.

Kapersky, hm...I'll check into that.

I have a fullscreen version, but it acts funky on mobile cards. Seems like it disregards the backbuffer flag (flicker). On my machine it runs perfectly at 1680x1050, but only with openGL. DirectX causes the same funky buffer flicker... ...havn't figured out the reason, yet.

Anyway, thank you so very much, it's awesome advice and loads of motivating energy! (...gotta watch out that I don't explode from it, I'm already so motivated by default!)

Fascinating. Some of you might see a massive speed increase if you switch the driver to OpenGL.

Some of you might get a massive headache if you switch the driver to OpenGL.

Any idea why it flashes black after changing the driver to GLMax2d?

as i've mentioned above...something funky going on there?!

HOWEVER, Boiled, I'm done with the screen saver! I'll test it on the laptop tomorrow, but it works beautifully already, fully integrated into Windows system! I'll post a version after testing it on laptop...

Well...tested it, but I still have either the flicker problems or something even more wicked on the darn laptop's mobile board. No clue what that is, really. It's a real shame, because otherwise it totally rocks!

I hope we can get that sorted out?!


DX7 on my Nvidia flickers at fullscreen
OGL works perfectly!
OGL & DX7 flicker on laptop

finally checked this out, and wow this is awesome.

you should add the odd:
butterfly/swarm of bugs/firefly

but at the same time that might be going a little over board because it's very cool as is, but might be neat to see some insects flying around once in awhile.

if you do the insect thing draw them between the background picture and the new tree and just hide them before making the new background picture.

anyways good job, i might actually start using a screensaver again.

This is pretty darn awesome. I think your screensaver version should include a slider to slow down/speed up the growth of the tree.

SpaceAce

Nice work!

Another idea would be to create little MONKEYS that run up these trees. :D

Haha...flies and monkeys... check! 8D
...nah, I think the best part is the fantasies it inspires! :}

The config will have all sorts of options in it, including speed, colors/changes, shapes, leaves and everything most likely with min/max for variations. Plus some extras.

The reason for why additional activity would be problematic is, because of the fundamental principle behind it right now. I am, however, already thinking about an alternative, which could make it much more flexible to more variety of content.

Man, you make me happy there! Thanks a whole lot! 8)))