### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: Sand Demo  (Read 935 times)

#### OwlOfTime

• Hero Member
• Posts: 3827
##### Sand Demo
« on: April 17, 2021, 07:19:16 pm »
Hi, I made a sand demo with BGRABitmap.

https://github.com/bgrabitmap/demo/tree/master/sand

Attached screenshot (The starting color is random).

Another I did, web version (not made with FPC, only typescript)
https://lainz.github.io/webapps/sand/

Both the web version and FPC version needs optimization, the web version can use webassembly and webgl. The FPC version can use scanline or opengl.

Feel free to play with the code!
Just Why?

#### circular

• Hero Member
• Posts: 3709
##### Re: Sand Demo
« Reply #1 on: April 17, 2021, 07:38:47 pm »
One way you can optimize is indeed to use something like ScanLine. You can add a one-pixel border to the image that will never contain sand and then use a pointer to the pixel of the sand particle. You can then just add and subtract 1 for left and right and add and subtract the row size for up and down (the sign may change, so you need to take into account the line order).

Unfortunately I cannot open it with my current version of Lazarus 2.0.10. I presume it is from a newer version?
« Last Edit: April 17, 2021, 07:48:56 pm by circular »
Conscience is the debugger of the mind

#### winni

• Hero Member
• Posts: 2404
##### Re: Sand Demo
« Reply #2 on: April 17, 2021, 08:48:18 pm »
Hi!

What might help is my procedure FillNaturalColor.
As parameter you need the destination BGRAbitmap, a rectangle and the
Hue-Value reduced to a byte:  round (360/Hue360 * 255)

The procedure produces a noisy natural area with your hue.
You can experiment with the 5 const values,  but take care that you dont't get a byte underflow or overflow. Now the const values take care of that.

The hue value of sand is around 55. If the result is too dark or bright you must do that on your own.

Code: Pascal  [Select][+][-]
1. // fill with noisy color Hue
2. procedure FillNaturalColor (Dest: TBGRABitmap; R : TRect; Hue: byte);
3. const RangeHue = 8;
4.       RangeLight = 58;
5.       RangeSat = 95;
6.       BaseLight =  113;
7.       BaseSat = 157;
8. var x,y : Integer;
9.     h,l,s : byte;
10.     col : TBGRAPixel;
11.     begin
12.     For y := R.Top to R.Bottom-1 do
13.      begin
14.      for x := R.left to R.Right - 1 do
15.        begin
16.         h := byte(Hue + Random(RangeHue +1));
17.         l := BaseLight + Random (RangeLight+1);
18.         s := BaseSat+ Random (RangeSat+1);
19.         col := HSLAToBGRA(HSLA(h*256,s*256,l*256));
20.         dest.setPixel(x,y,col);
21.        end;  //x
22.      end; // y
23.     end;
24.

Example in the attachment.

Winni

#### OwlOfTime

• Hero Member
• Posts: 3827
##### Re: Sand Demo
« Reply #3 on: April 18, 2021, 02:47:14 am »
Hi circular. Try again I fixed it.

Hi winni. Thanks. I already have color noise but it's soften. I've not tweaked the fpc version yet just a quick port from the web version.

Enjoy open source!
Just Why?

#### Fred vS

• Hero Member
• Posts: 2220
##### Re: Sand Demo
« Reply #4 on: April 18, 2021, 03:50:50 am »
Hello Lainz.

I try to make your sand dance but get a error while compiling, on Linux 64 bit, fpc 3.2.0 and Lazarus 2.0.10.

I use last bgrabitmap V11 and bgracontrols V7.

This is the line that makes problems, in umain.pas(165,27) ;

Code: Pascal  [Select][+][-]
1.  sand.SetPixel(x, y, p);

This is the error:

Quote
umain.pas(165,27) Error: Can't determine which overloaded function to call
unibitmapgeneric.inc(37,15) Hint: Found declaration: SetPixel(Int64;Int64;const TBGRAPixel);

Fre;D
« Last Edit: April 18, 2021, 03:56:58 am by Fred vS »
I use Lazarus 2.0.6 32/64 and FPC 3.2.0 32/64 on Debian 10.2 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs
https://gitlab.com/fredvs

#### OwlOfTime

• Hero Member
• Posts: 3827
##### Re: Sand Demo
« Reply #5 on: April 18, 2021, 03:54:36 am »
Hi. If you add a intermediate variable like a tbgrapixel and convert the hsla before sending to set pixel?
Just Why?

#### Fred vS

• Hero Member
• Posts: 2220
##### Re: Sand Demo
« Reply #6 on: April 18, 2021, 03:58:35 am »
Hi. If you add a intermediate variable like a tbgrapixel and convert the hsla before sending to set pixel?

Maybe it will work (if you explain me how to do)...
I use Lazarus 2.0.6 32/64 and FPC 3.2.0 32/64 on Debian 10.2 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs
https://gitlab.com/fredvs

#### OwlOfTime

• Hero Member
• Posts: 3827
##### Re: Sand Demo
« Reply #7 on: April 18, 2021, 04:04:50 am »
Var
Px: tbgrapixel;
...
Px := p;
... Setpixel(..., Px);
Just Why?

#### Fred vS

• Hero Member
• Posts: 2220
##### Re: Sand Demo
« Reply #8 on: April 18, 2021, 04:07:33 am »
Var
Px: tbgrapixel;
...
Px := p;
... Setpixel(..., Px);

Together!

I did this and it works.

Code: Pascal  [Select][+][-]
1. procedure TfrmMain.putSand(const x: integer; const y: integer);
2. var
3.   p: THSLAPixel;
4.   p2: tbgrapixel;
5. begin
6.   if isWhite(x, y) then
7.   begin
8.     p.hue := round(hsla);
9.     p.saturation := randomRange(32768, 65535 - (32768 div 2));
10.     p.lightness := 32768;
11.     p.alpha := 65535;
12.     p2 := p;
13.     sand.SetPixel(x, y, p2);
14.     hsla := hsla + 1 / size;
15.     if (hsla > 65535) then
16.       hsla := 0;
17.   end;
18. end;

WOW!
« Last Edit: April 18, 2021, 04:17:08 am by Fred vS »
I use Lazarus 2.0.6 32/64 and FPC 3.2.0 32/64 on Debian 10.2 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs
https://gitlab.com/fredvs

#### OwlOfTime

• Hero Member
• Posts: 3827
##### Re: Sand Demo
« Reply #9 on: April 18, 2021, 04:19:53 am »
Yes it's really cool and easy to code. If you want you can search some videos where is explained how to do water and many more.
Just Why?

#### circular

• Hero Member
• Posts: 3709
##### Re: Sand Demo
« Reply #10 on: April 18, 2021, 12:37:38 pm »
Hi

I've optimized the code and also to use OpenGL.

It is much faster with OpenGL because the image is stretched. Doing the stretch by software is a bit slow and even using the stretch draw of TBitmap is slow in particular on Retina.
Conscience is the debugger of the mind

#### OwlOfTime

• Hero Member
• Posts: 3827
##### Re: Sand Demo
« Reply #11 on: April 18, 2021, 01:16:09 pm »
Thanks Johann.

Edit: Seems that doesn't works on Windows.

Attached image, it moves to the left, but that's all it does.
« Last Edit: April 18, 2021, 02:52:46 pm by lainz »
Just Why?

#### circular

• Hero Member
• Posts: 3709
##### Re: Sand Demo
« Reply #12 on: April 18, 2021, 06:41:31 pm »
Ok, I thought of something that might not work, the actual row size may be different. Please have a try with last change
Conscience is the debugger of the mind

#### OwlOfTime

• Hero Member
• Posts: 3827
##### Re: Sand Demo
« Reply #13 on: April 18, 2021, 06:57:09 pm »
It works now thanks.
Just Why?