Recent

Author Topic: Copper Chunky Pixel  (Read 458 times)

Gigatron

  • Sr. Member
  • ****
  • Posts: 276
  • Amiga Rulez !!
Copper Chunky Pixel
« on: May 11, 2025, 02:48:24 am »
Hi,

A nice fx from amiga called copper chunky;
Working with grid cells , code from a javascript version not optimized yet !

example of this code on Scoopex Cracktro : https://youtu.be/urhCo_3Khd4?si=0viz1GNDdnYe0X6v&t=14
Or Digital A maze intro
https://youtu.be/fcB-v8D3i6s?si=8soBKLQwBaIIakbA&t=72

Explanation of Copper Chunky : https://www.youtube.com/watch?v=ste_ejNVvDk

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls,
  9.   BGRAVirtualScreen, BGRABitmap, BGRABitmapTypes;
  10.  
  11. type
  12.   { TForm1 }
  13.   TForm1 = class(TForm)
  14.     BGRAVirtualScreen1: TBGRAVirtualScreen;
  15.     Button1: TButton;
  16.     Panel1: TPanel;
  17.     Timer1: TTimer;
  18.     procedure BGRAVirtualScreen1Redraw(Sender: TObject; Bitmap: TBGRABitmap);
  19.     procedure Button1Click(Sender: TObject);
  20.     procedure FormCreate(Sender: TObject);
  21.     procedure Timer1Timer(Sender: TObject);
  22.   private
  23.     ZoomFactor: Single;
  24.     MaxZoom: Single;
  25.     MinZoom: Single;
  26.     CellSize: Integer;
  27.     Angle: Single;
  28.     RotSpeed: Single;
  29.     Tmr: Single;
  30.     ZoomCenter: Single;
  31.     ZoomAmp: Single;
  32.   public
  33.   end;
  34.  
  35. var
  36.   Form1: TForm1;
  37.   tex : TBGRABitmap;
  38.  
  39. implementation
  40.  
  41. {$R *.lfm}
  42.  
  43. { TForm1 }
  44.  
  45. procedure TForm1.FormCreate(Sender: TObject);
  46. begin
  47.   // texture
  48.   tex := TBGRABitmap.Create('gl.png');
  49.   MaxZoom :=  5.0;
  50.   MinZoom := 2.0;
  51.   CellSize := 8;
  52.   Angle := 0;
  53.   RotSpeed := 0.6;
  54.   Tmr := 0;
  55.   ZoomCenter := (MaxZoom + MinZoom) / 2;
  56.   ZoomAmp := (MaxZoom - MinZoom) / 2;
  57.   ZoomFactor := ZoomCenter / 8;
  58.  
  59. end;
  60.  
  61. procedure TForm1.BGRAVirtualScreen1Redraw(Sender: TObject; Bitmap: TBGRABitmap);
  62. var
  63.   x, y: Integer;
  64.   bx, by: Integer;
  65.   dx, dy: Single;
  66.   sx, sy: Integer;
  67.   centerX, centerY: Single;
  68.   zoom: Single;
  69.   col: TBGRAPixel;
  70.   angleRad: Single;
  71.   sinVal, cosVal: Single;
  72.   rotX, rotY: Single;
  73. begin
  74.  
  75.   centerX := tex.Width / 2;
  76.   centerY := tex.Height / 2;
  77.   zoom := 1 / ZoomFactor;
  78.   angleRad := Angle * Pi / 180;
  79.   sinVal := Sin(angleRad);
  80.   cosVal := Cos(angleRad);
  81.   Bitmap.Fill(BGRABlack);
  82.   // pixel fx ok with pascal
  83.   for y := 0 to (BGRAVirtualScreen1.Height - 1) div CellSize do
  84.   begin
  85.     for x := 0 to (BGRAVirtualScreen1.Width - 1) div CellSize do
  86.     begin
  87.       dx := (x * CellSize - BGRAVirtualScreen1.Width/2) * zoom;
  88.       dy := (y * CellSize - BGRAVirtualScreen1.Height/2) * zoom;
  89.       rotX := dx * cosVal - dy * sinVal;
  90.       rotY := dx * sinVal + dy * cosVal;
  91.       sx := Round(centerX + rotX);
  92.       sy := Round(centerY + rotY);
  93.       // Replace pixel on each cells adapted from js;
  94.       if (sx >= 0) and (sx < tex.Width) and (sy >= 0) and (sy < tex.Height) then
  95.       begin
  96.         // get pixel source
  97.         col := tex.GetPixel(sx, sy);
  98.         // cells block
  99.         for by := 0 to CellSize - 1 do
  100.         begin
  101.           for bx := 0 to CellSize - 1 do
  102.           begin
  103.             if (x * CellSize + bx < BGRAVirtualScreen1.Width) and
  104.             (y * CellSize + by < BGRAVirtualScreen1.Height) then
  105.             begin
  106.               Bitmap.SetPixel(x * CellSize + bx, y * CellSize + by, col);
  107.             end;
  108.           end;
  109.         end;
  110.  
  111.       end;
  112.     end;
  113.   end;
  114.  
  115. end;
  116.  
  117. procedure TForm1.Button1Click(Sender: TObject);
  118. begin
  119.   RotSpeed := -RotSpeed;
  120. end;
  121.  
  122. procedure TForm1.Timer1Timer(Sender: TObject);
  123. begin
  124.   Tmr := Tmr + 0.01;  // counter timer
  125.   ZoomFactor := ZoomCenter + (ZoomAmp * Sin(Tmr * 0.5));
  126.   Angle := Angle + RotSpeed;
  127.   BGRAVirtualScreen1.RedrawBitmap;
  128. end;
  129.  
  130. end.

Base code js :
Code: Javascript  [Select][+][-]
  1. function rotozoom() {
  2.     const centerX = srcWidth / 2;
  3.     const centerY = srcHeight / 2;
  4.     const zoom = 1 / config.zoom;
  5.     const angleRad = config.angle * Math.PI / 180;
  6.     const sin = Math.sin(angleRad);
  7.     const cos = Math.cos(angleRad);
  8.    
  9.     const bufferData = bufferCtx.createImageData(config.width, config.height);
  10.     const pixels = bufferData.data;
  11.     const step = config.blockSize;
  12.        
  13.         clearCanvas();
  14.    
  15.     for (let y = 0; y < config.height; y += step) {
  16.         for (let x = 0; x < config.width; x += step) {
  17.             // Transformation
  18.             const dx = (x - config.width/2) * zoom;
  19.             const dy = (y - config.height/2) * zoom;
  20.             const sx = Math.floor(centerX + dx * cos - dy * sin);
  21.             const sy = Math.floor(centerY + dx * sin + dy * cos);
  22.  
  23.             if (sx >= 0 && sx < srcWidth && sy >= 0 && sy < srcHeight) {
  24.                 const srcPos = (sy * srcWidth + sx) << 2;
  25.                
  26.                 for (let by = 0; by < step && y + by < config.height; by++) {
  27.                     for (let bx = 0; bx < step && x + bx < config.width; bx++) {
  28.                         const destPos = ((y + by) * config.width + (x + bx)) << 2;
  29.                         pixels[destPos] = srcData[srcPos];       // R
  30.                         pixels[destPos+1] = srcData[srcPos+1];   // G
  31.                         pixels[destPos+2] = srcData[srcPos+2];   // B
  32.                         pixels[destPos+3] = 255;                 // A
  33.                     }
  34.                 }
  35.             }
  36.         }
  37.     }
  38.    
  39.     bufferCtx.putImageData(bufferData, 0, 0);
  40.     ctx.drawImage(buffer, 0, 0);
  41. }
« Last Edit: May 11, 2025, 02:37:11 pm by Gigatron »
Sub Quantum Technology ! Gigatron 68000 Colmar France;

Gigatron

  • Sr. Member
  • ****
  • Posts: 276
  • Amiga Rulez !!
Re: Copper Chunky Pixel
« Reply #1 on: May 11, 2025, 02:57:04 pm »
Hi

A new version of this nice chunky copper effect , Pascal version is near 95% of the original amiga
effet version. https://www.youtube.com/watch?v=ste_ejNVvDk

Source bird image from : https://powerprograms.nl/amiga/copper-chunky.html

You can change cellsize, speed, zoom factor and reverse rotation.
This demo is running fullscreen to see how BGRA and Pascal code is faster !!

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls,
  9.   Spin, BGRAVirtualScreen, BGRABitmap, BGRABitmapTypes;
  10.  
  11. type
  12.   { TForm1 }
  13.   TForm1 = class(TForm)
  14.     BGRAVirtualScreen1: TBGRAVirtualScreen;
  15.     Button1: TButton;
  16.     FloatSpinEdit1: TFloatSpinEdit;
  17.     FloatSpinEdit2: TFloatSpinEdit;
  18.     Panel1: TPanel;
  19.     SpinEdit1: TSpinEdit;
  20.     Timer1: TTimer;
  21.     procedure BGRAVirtualScreen1Redraw(Sender: TObject; Bitmap: TBGRABitmap);
  22.     procedure Button1Click(Sender: TObject);
  23.     procedure FormCreate(Sender: TObject);
  24.     procedure Timer1Timer(Sender: TObject);
  25.   private
  26.     ZoomFactor, MaxZoom, MinZoom, Angle, RotSpeed, Tmr, ZoomCenter, ZoomAmp: Single;
  27.     CellSize: Integer;
  28.   public
  29.   end;
  30.  
  31. var
  32.   Form1: TForm1;
  33.   tex : TBGRABitmap;
  34.  
  35. implementation
  36.  
  37. {$R *.lfm}
  38.  
  39. { TForm1 }
  40.  
  41. procedure TForm1.FormCreate(Sender: TObject);
  42. begin
  43.   // texture
  44.   tex := TBGRABitmap.Create('bird.jpg');
  45.   MaxZoom :=  4.0;
  46.   MinZoom := 1.5;
  47.   CellSize := 12;
  48.   Angle := 0;
  49.   RotSpeed := 0.6;
  50.   Tmr := 0;
  51.   ZoomCenter := (MaxZoom + MinZoom) / 2;
  52.   ZoomAmp := (MaxZoom - MinZoom) / 2;
  53.   ZoomFactor := ZoomCenter / 8;
  54. end;
  55.  
  56. procedure TForm1.BGRAVirtualScreen1Redraw(Sender: TObject; Bitmap: TBGRABitmap);
  57. var
  58.   x, y: Integer;
  59.   bx, by: Integer;
  60.   dx, dy: Single;
  61.   sx, sy: Integer;
  62.   centerX, centerY: Single;
  63.   zoom: Single;
  64.   col: TBGRAPixel;
  65.   angleRad: Single;
  66.   sinVal, cosVal: Single;
  67.   rotX, rotY: Single;
  68. begin
  69.  
  70.   centerX := tex.Width / 2;
  71.   centerY := tex.Height / 2;
  72.   zoom := 1 / ZoomFactor;
  73.   angleRad := Angle * Pi / 180;
  74.   sinVal := Sin(angleRad);
  75.   cosVal := Cos(angleRad);
  76.   Bitmap.Fill(BGRABlack);
  77.   // pixel fx ok with pascal
  78.   for y := 0 to (BGRAVirtualScreen1.Height - 1) div CellSize do
  79.   begin
  80.     for x := 0 to (BGRAVirtualScreen1.Width - 1) div CellSize do
  81.     begin
  82.       dx := (x * CellSize - BGRAVirtualScreen1.Width/2) * zoom;
  83.       dy := (y * CellSize - BGRAVirtualScreen1.Height/2) * zoom;
  84.       rotX := dx * cosVal - dy * sinVal;
  85.       rotY := dx * sinVal + dy * cosVal;
  86.       sx := Round(centerX + rotX);
  87.       sy := Round(centerY + rotY);
  88.       // Replace pixel on each cells inside limits adapted from js;
  89.       if (sx >= 0) and (sx < tex.Width) and (sy >= 0) and (sy < tex.Height) then
  90.       begin
  91.         // get pixel source
  92.         col := tex.GetPixel(sx, sy);
  93.         // fill cells block
  94.         for by := 0 to CellSize - 1 do
  95.         begin
  96.           for bx := 0 to CellSize - 1 do
  97.           begin
  98.             if (x * CellSize + bx < BGRAVirtualScreen1.Width) and
  99.             (y * CellSize + by < BGRAVirtualScreen1.Height) then
  100.             begin
  101.               Bitmap.SetPixel(x * CellSize + bx, y * CellSize + by, col);
  102.             end;
  103.           end;
  104.         end;
  105.       end;
  106.  
  107.     end;
  108.   end;
  109.  
  110. end;
  111.  
  112. procedure TForm1.Button1Click(Sender: TObject);
  113. begin
  114.   FloatSpinEdit1.Value := -FloatSpinEdit1.Value;
  115. end;
  116.  
  117. procedure TForm1.Timer1Timer(Sender: TObject);
  118. begin
  119.   Tmr := Tmr + 0.01;  // counter timer
  120.   ZoomFactor := ZoomCenter + (ZoomAmp * Sin(Tmr * 0.5));
  121.   Angle := Angle + RotSpeed;
  122.   CellSize := SpinEdit1.Value;
  123.   RotSpeed := FloatSpinEdit1.Value;
  124.   ZoomFactor := FloatSpinEdit2.Value; // never negative ! div / 0
  125.   BGRAVirtualScreen1.RedrawBitmap;
  126. end;
  127. end.
« Last Edit: May 11, 2025, 03:18:58 pm by Gigatron »
Sub Quantum Technology ! Gigatron 68000 Colmar France;

 

TinyPortal © 2005-2018