clip rect namespace

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

clip rect namespace

Post by dafhi »

Code: Select all

/' -- clip rect namespace - 2024 Feb 9 - by dafhi

  a namespaced clip rect for 2d graphics

    updates
demo and comments

  renames
project:  low level 2d clipper -> clip rect
set -> setrc
custom_blit -> custom_draw

'/

type imvars '' helper
  declare sub   get_info( byref p as any ptr = 0 )
  
  as long       w
  as long       h
  as long       pitch,rate
  as long       bypp,bpp
  as any ptr    pixels, im
  as string     driver_name
end type

sub imvars.get_info( byref p as any ptr )
  if p = 0 then
    ScreenInfo w,h, bpp, bypp, pitch, rate, driver_name
    pixels = screenptr
  else
    ImageInfo p, w, h, bypp, pitch, pixels
  endif
  im = p
end sub

#define min( a, b)    iif( (a)<(b), (a), (b) )
#define max( a, b)    iif( (a)>(b), (a), (b) )


  namespace clp_rec

  '' internals

dim as imvars     buf     ' primary hard limit (w,h)

dim as short      x0, x1  ' secondary hard limit
dim as short      y0, y1

type rect field = 2       ' alignment
  dim as short    x0, x1
  dim as short    y0, y1
end type

dim as rect       rc      ' helper

/'  = example =

  clp_rec.acquire_buf  0      ''  app window (0) or fb image
  clp_rec.set_clp 5,5, 50, 40 '' (optional)

  sub custom_blit( x as short, y as short, w as short, h as short )
      using clp_rec                 ''  helper
    setrc rc, x, y, w, h            ''
    for y as long = rc.y0 to rc.y1
    for x as long = rc.x0 to rc.x1
    ..
'/

sub setrc( byref r as rect, x as short, y as short, w as short, h as short )
  r.x0 = max( x0, x )
  r.y0 = max( y0, y )
  r.x1 = min( x1, x+w-1 )
  r.y1 = min( y1, y+h-1 )
end sub

sub set_clp( _
    xx as short, yy as short, _
    ww as short = 100, hh as short = 100 )
    
  x0 = max(0,xx)
  y0 = max(0,yy)
  x1 = min(xx + ww-1, buf.w-1)
  y1 = min(yy + hh-1, buf.h-1)
  
  setrc rc, xx, yy, ww, hh
end sub

sub acquire_buf( p as any ptr )
  buf.get_info p
  if buf.h > 0 then set_clp 0,0, buf.w,buf.h
end sub

end namespace ' --- clp_rec


' -- Main
'
sub custom_draw( _
  x as short = 0, y as short = 0, _
  ww as short = 100, hh as short = 100, _color as ulong = -1 )
  
    using clp_rec                 ' helper
  setrc rc, x, y, ww, hh            '
    
  for y as long = rc.y0 to rc.y1
  for x as long = rc.x0 to rc.x1
    pset (x,y), _color
  next
  next
  
end sub


  const w = 800
  const h = 600

screenres w, h, 32

clp_rec.acquire_buf 0 '' app window (0) or fb image

clp_rec.set_clp 20, 20, 200, 200

for i as long = 1 to 1500
  var size  =  12
  var x     = (20-size) + (200+size)*rnd
  var y     = (20-size) + (200+size)*rnd
  custom_draw x,y, size, size, rnd * culng(-1)
next

sleep
Last edited by dafhi on Feb 09, 2024 5:29, edited 4 times in total.
neil
Posts: 594
Joined: Mar 17, 2022 23:26

Re: low level 2d clipper

Post by neil »

Hi dafhi I tested your low-level 2D clipper, and it runs OK.
Last edited by neil on Jan 17, 2024 8:58, edited 1 time in total.
neil
Posts: 594
Joined: Mar 17, 2022 23:26

Re: low level 2d clipper

Post by neil »

A few changes and it runs a little slower.

Code: Select all

/' -- low level 2d clipper - 2024 Jan 16 - by dafhi

  updates

imvars class (helper)
renamed set_clprec -> set_clp
renamed clp_rec.rc -> clp_rec.rect
removed rect constructor
added clp_rec .. dim as rect  rc
reverted to min/max using iif(

'/

type imvars '' helper
  declare sub   get_info( byref p as any ptr = 0 )
  
  as long       w '' apparently imageinfo no longer likes integer
  as long       h
  as long       pitch,rate
  as long       bypp,bpp
  as any ptr    pixels, im
  as string     driver_name
end type

sub imvars.get_info( byref p as any ptr )
  if p = 0 then
    ScreenInfo w,h, bpp, bypp, pitch, rate, driver_name
    pixels = screenptr
  else
    ImageInfo p, w, h, bypp, pitch, pixels
  endif
  im = p
end sub

#define min( a, b)    iif( (a)<(b), (a), (b) )
#define max( a, b)    iif( (a)>(b), (a), (b) )


  namespace clp_rec  /' -- low level 2d clipper
  
   - code example

  screenres 800,600

  clp_rec.acquire_buf  0      ''  app window (0) or fb image
  clp_rec.set_clp 5,5, 50, 40 '' (optional)

  sub custom_blit( x as short, y as short, w as short, h as short )
  
      using clp_rec                 ''  helper
    set rc, x, y, w, h              ''
    for y as long = rc.y0 to rc.y1  ''
    for x as long = rc.x0 to rc.x1  ''
      ..
'/

  ' internals -
  
  dim as imvars buf         ' primary hard limit (w,h)

  dim as short      x0, x1  ' secondary hard limit
  dim as short      y0, y1

  type rect field = 2 '' alignment
    dim as short      x0, x1
    dim as short      y0, y1
  end type
  
  dim as rect   rc  '' helper

sub set( byref r as rect, x as short, y as short, w as short, h as short )
  r.x0 = max( x0, x )
  r.y0 = max( y0, y )
  r.x1 = min( x1, x+w-1 )
  r.y1 = min( y1, y+h-1 )
end sub

sub set_clp( _
    xx as short, yy as short, _
    ww as short = 100, hh as short = 100 )
    
  x0 = max(0,xx)
  y0 = max(0,yy)
  x1 = min(xx + ww-1, buf.w-1)
  y1 = min(yy + hh-1, buf.h-1)
  
  set rc, xx, yy, ww, hh '' helper
end sub

sub acquire_buf( p as any ptr )
  buf.get_info p
  if buf.h > 0 then set_clp 0,0, buf.w,buf.h
end sub

end namespace ' ----------- clp_rec

'
' -- Main
'

sub custom_blit( _
  x as short = 0, y as short = 0, _
  w as short = 100, h as short = 100, _color as ulong = -1 )
  
    using clp_rec                 '
  set rc, x, y, w, h              ' helper
    
  for y as long = rc.y0 to rc.y1  '
  for x as long = rc.x0 to rc.x1  '
    pset (x,y), _color
  next
  next

end sub

  const w = 800
  const h = 600

screenres w, h, 32

clp_rec.acquire_buf 0 '' app window (0) or fb image

var x0 = 20, clp_w = 200
var y0 = 20, clp_h = 200

clp_rec.set_clp x0, y0, clp_w, clp_h

'' demo
dim as double t = timer

dim as single t_demo_seconds = 18
dim as double t_demo_end = t + t_demo_seconds

var shape_w = 40
var shape_h = 40

dim as single cen_x = (x0 + clp_w - shape_w)/2
dim as single cen_y = (y0 + clp_h - shape_h)/2

dim as single move_x = clp_w / 2
dim as single move_y = clp_h / 2

dim as double ax
dim as double ay

while t < t_demo_end

  var tp = t:  t = timer
  var dt = (t - tp) * .75
  
  var x = cen_x + move_x*sin(ax):  ax += 1.3 * dt
  var y = cen_y + move_y*sin(ay):  ay += 2.1 * dt
  
  screenlock
  line (x0,y0)-(x0+clp_w,y0+clp_h),rgb(0,0,0), bf '' clear
  custom_blit x,y, shape_w, shape_h, rgb(0,255,0)
  screenunlock
  
  if inkey<>"" then exit while
  sleep 1
wend

locate 2,2
? "demo finished!"

sleep 1500
Post Reply