- Joined
- Dec 13, 2018
- Messages
- 384
Shows how to write pixels using a databuffer with mojo 2 (a bit more interesting than the official example I re-wrote). Modify the number of control points or the control point radius, angle step or colour values and the image transparency, to get different effects.
The program creates a simple Voronoi diagram, where each point is coloured according to the nearest 'control point'. The control points are rotated to give interesting visual effects - they could be transformed using trig functions or bitwise operations to give a broader range of effects.
Cerberus:
Strict
Import mojo2
Import brl.databuffer
Const XSIZE:Int = 320
Const YSIZE:Int = 240
Const INTSIZE:Int = 4
Const NUMPOINTS:Int = 8
Function Main:Int()
New MyGame()
Return 0
End
Global pixels:DataBuffer = New DataBuffer(INTSIZE * XSIZE * YSIZE)
Class ControlPoint
Field x:Float
Field y:Float
Field cx:Float
Field cy:Float
Field abgr:Int
Field angle:Float
Field angleStep:Float
Field radius:Float
Method New(xx:Float , yy:Float, r:Int, g:Int, b:Int)
cx = xx
cy = yy
abgr = r + (g Shl 8) + (b Shl 16) + (255 Shl 24)
angle = Rnd(360)
radius = Rnd(40, 80)
x = cx + radius * Cos(angle)
y = cy + radius * Sin(angle)
angleStep = Rnd(0.5, 1)
End
Method Update:Void()
x = cx + radius * Cos(angle)
y = cy + radius * Sin(angle)
angle += angleStep
End
End
Class MyGame Extends App
Field myImage:Image
Field myCanvas:Canvas
Field cp:ControlPoint[NUMPOINTS]
Method OnCreate:Int()
Local date := GetDate()
Seed = date[3] * 3600000 + date[4] * 60000 + date[5] * 1000 + date[6]
SetUpdateRate(60)
myCanvas = New Canvas()
' Create a 320 x 200 image with top left handle
myImage = New Image(XSIZE, YSIZE, 0.5, 0.5)
' add control points
For Local i:Int = 0 Until NUMPOINTS
cp[i] = New ControlPoint(Rnd(XSIZE), Rnd(YSIZE), Int(Rnd(256)), Int(Rnd(256)), int(Rnd(256)))
Next
' initial fill
UpdatePixels()
Return 0
End
Method UpdatePixels:Void()
Local pos:Int = 0
For Local y:Int = 0 Until YSIZE
For Local x:Int = 0 Until XSIZE
Local dist:Float = 123456789
Local index:Int
'get nearest cp to this pixel
For Local i:Int = 0 Until NUMPOINTS
Local a:Float = x - cp[i].x
Local b:Float = y - cp[i].y
Local hyp:Float = (a * a) + (b * b)'Sqrt((a * a) + (b * b))
If hyp <= dist Then
dist = hyp
index = i
Endif
Next
' set this pixel to nearest control point's colour
pixels.PokeInt(pos, cp[index].abgr)
pos += INTSIZE
Next
Next
' write databuffer to image
myImage.WritePixels(0, 0, XSIZE, YSIZE, pixels)
' update control points
For Local i: Int = 0 Until NUMPOINTS
cp[i].Update()
Next
End
Method OnRender:Int()
' draw a scaled version of the image, no canvas clear, high transparency
myCanvas.SetColor(1, 1, 1, 0.025)
myCanvas.DrawImage(myImage, DeviceWidth()/2, DeviceHeight()/2, 0, 2, 2)
myCanvas.Flush()
Return 0
End
Method OnUpdate:Int()
UpdatePixels()
Return 0
End
End