It is currently Sun Jan 24, 2021 9:36 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: [Library] SPP (SimplePixelProc) - GFX library [Win x64/x86]
PostPosted: Fri Jan 08, 2021 9:08 pm 
Offline
Addict
Addict
User avatar

Joined: Sun Sep 11, 2016 2:17 pm
Posts: 804
SPP is a small, experimental gfx library written in PureBasic.

Motivation: Shaders are cool! http://www.shadertoy.com

For me SPP is a tool to learn glsl shader coding without the need to learn the glsl syntax first :)
The PixelProc callback is called for every pixel (like a shader would).
Doing complex math on every pixel is slow thats why SPP supports multithreading
to mitigate performance issues as good as possible.

Its good enough to learn, experiment and write small shaderlike programs.

Note:
Since the backbuffer is fully accessible you can pretty much do whatever you want.
You dont need to use the PixelProc callback at all - just fill the backbuffer and render it ;)

Example 'shader':
Image

Include:
Code:

EnableExplicit

;Name:    SPP lib (Simple Pixel Process)
;Version: Alpha (Draft 4)
;Author:  Mijikai
;License: CC BY 3.0 / https://creativecommons.org/licenses/by/3.0/

#SPP_VERSION = $0001

CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
  Import "spp32.lib"
    sppContext.i(Hwnd.i,Width.i,Height.i,ColorBack.i = $0,ColorFront.i = $111111)
    sppVersion.i()
  EndImport
CompilerElse
  Import "spp64.lib"
    sppContext.i(Hwnd.i,Width.i,Height.i,ColorBack.i = $0,ColorFront.i = $111111)
    sppVersion.i()
  EndImport
CompilerEndIf

Interface SPP
  Viewport.i()                                            ;<- updates the viewport when the window/screen is resized (respects the aspect ratio)
  Clear.i(Color.i = $FF000000)                            ;<- clears/fills the backbuffer with the specified color
  SwapBuffer.i()                                          ;<- flips aka. renders the backbuffer
  Buffer.i(*Buffer = #Null)                               ;<- returns a pointer to the backbuffer or fills a SPP_BUFFER structure
  Pixel.i(*Pixel,*Color)                                  ;<- changes the color of the pixel pointet to by *Pixel with the color pointet to by *Color (color has to be a vec4)
  PixelProc.i(*Callback = #Null,MultiThreaded.i = #False) ;<- creates a callback / if MultiThreaded is #True threading is enabled (1 thread for every physical processor or at least 2)
                                                          ;   if MuliThreaded > 1 threads are created according to the screen size!
  Event.i(Milliseconds.i = 16)                            ;<- creates a timed event that can be used with the wait function (returns #True if the event could be created)
  Wait.i()                                                ;<- waits for a timed event (default 16 ms ~ 60 fps)
  Info.i(*Frames,*Time)                                   ;<- returns the fps (integer) and time (float) in seconds since the the first frame was rendered
  Release.i()                                             ;<- releases all
EndInterface

Structure SPP_RECT
  x.l
  y.l
  w.l
  h.l
EndStructure

Structure SPP_BUFFER
  output.SPP_RECT
  *bits
  pitch.i
  size.i
EndStructure

;Procedure.i Callback(*coord.VEC2,*color.VEC4);<- PixelProc
  ;*coord <- coordinates of the current pixel
  ;*color <- pointer to a vec4 that receives the color (alpha is ignored)
  ;ProcedureReturn
;EndProcedure


Example Code:
Code:

EnableExplicit

;Example 'Shader'
;Author: Mijikai

XIncludeFile "spp.pbi"

Structure VEC2
  x.f:y.f
EndStructure

Structure VEC3
  x.f:y.f:z.f
EndStructure

Structure VEC4
  x.f:y.f:z.f:w.f
EndStructure

Global time.f

Macro Vec2(_v_,_x_,_y_)
  _v_\x = _x_:_v_\y = _y_
EndMacro

Macro Vec4(_v_,_x_,_y_,_z_,_w_)
  _v_\x = _x_:_v_\y = _y_:_v_\z = _z_:_v_\w = _w_
EndMacro

Macro Vec2Rotate(_v_,_a_,_out_)
  _out_\x = _v_\x * Cos(_a_) - _v_\y * Sin(_a_)
  _out_\y = _v_\x * Sin(_a_) + _v_\y * Cos(_a_)
EndMacro

Macro Vec2UV(_v_,_w_,_h_,_out_)
  _out_\x = ((_v_\x / _w_) * 2.0 - 1.0) * (_w_ / _h_)
  _out_\y = (_v_\y / _h_) * 2.0 - 1.0
EndMacro

Procedure.i Callback(*coord.VEC2,*color.VEC4)
  Protected uv.VEC2,rot.VEC2,col.VEC3,d.f,m.f
  Vec2UV(*coord,960,600,uv)
  Vec2Rotate(uv,time,rot)
  d = 0.6 - Sin(Abs(rot\x) * Cos(Abs(uv\x) + rot\x) * 40.0) * 1.1
  d + Cos(Abs(Mod(d,20.0)))
  If Abs(uv\x + Sin(time * 10.0 + uv\y * 4) / 10.0) < 0.4
    col\x = Abs(uv\x + Sin(time * 8.0 + uv\y * 4) / 10.0) + d / 80.0
    col\y = col\x / 10.0
    col\z = 1.0 - col\x
  Else
    col\x = Abs(uv\x) / d - 0.4
    col\y = Sin(Sin(time * 2.0) * 5.0 * Abs(rot\y)) - d
    col\z = 1.0 - col\x + Cos(Abs(rot\y)) - d
  EndIf
  Vec4(*color,col\x,col\y,col\z,1.0)
  ProcedureReturn
EndProcedure

Procedure.i Main(Width.i,Height.i)
  Protected *spp.SPP,fps.i
  If sppVersion() = #SPP_VERSION
    If OpenWindow(0,0,0,Width,Height,#Null$,#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget)
      WindowBounds(0,WindowWidth(0),WindowHeight(0),#PB_Ignore,#PB_Ignore)
      *spp = sppContext(WindowID(0),WindowWidth(0),WindowHeight(0))
      If *spp
        If *spp\Event()
          *spp\PixelProc(@Callback(),#True)
          Repeat
            Repeat
              Select WindowEvent()
                Case #PB_Event_SizeWindow:*spp\Viewport()
                Case #PB_Event_CloseWindow:Break 2
                Case #Null:Break
              EndSelect
            ForEver
            *spp\Clear()
            *spp\SwapBuffer()
            *spp\Wait()
            *spp\Info(@fps,@time)
            SetWindowTitle(0,"FPS: " + Str(fps))
          ForEver
        EndIf
        *spp\Release()
      EndIf
      CloseWindow(0) 
    EndIf 
  EndIf
  ProcedureReturn
EndProcedure

Main(960,600)

End


Download (Library):
https://www.dropbox.com/s/c2nk3mi0pbu3za0/spp_alpha.zip?dl=0

Have fun learning & experimenting :D


Top
 Profile  
Reply with quote  
 Post subject: Re: [Library] SPP (SimplePixelProc) - GFX library [Win x64/x
PostPosted: Sun Jan 10, 2021 10:36 am 
Offline
Addict
Addict
User avatar

Joined: Sun Sep 11, 2016 2:17 pm
Posts: 804
Another example :)

SDF Raymarching
Image

Code:
Code:
EnableExplicit

;Example Raymarching

;Infos & Tutorials:
;https://www.iquilezles.org/www/index.htm

;------------------------------------------------------------------------------------

XIncludeFile "spp.pbi"

;------------------------------------------------------------------------------------

Structure VEC2
  x.f
  y.f
EndStructure

Structure VEC3
  x.f
  y.f
  z.f
EndStructure

Structure VEC4
  x.f
  y.f
  z.f
  w.f
EndStructure

;------------------------------------------------------------------------------------

#SPP_W = 960
#SPP_H = 600

Global time.f

;------------------------------------------------------------------------------------

Macro valMin(_a_,_b_,_out_)
  If _a_ < _b_
    _out_ = _a_
  Else
    _out_ = _b_
  EndIf
EndMacro

Macro valMax(_a_,_b_,_out_)
  If _a_ > _b_
    _out_ = _a_
  Else
    _out_ = _b_
  EndIf
EndMacro

Macro vec2(_v_,_x_,_y_)
  _v_\x = _x_
  _v_\y = _y_
EndMacro

Macro vec2Length(_v_)
  Sqr((_v_\x * _v_\x) + (_v_\y * _v_\y))
EndMacro

Macro vec3(_v_,_x_,_y_,_z_)
  _v_\x = _x_
  _v_\y = _y_
  _v_\z = _z_
EndMacro

Macro vec4(_v_,_x_,_y_,_z_,_w_)
  _v_\x = _x_
  _v_\y = _y_
  _v_\z = _z_
  _v_\w = _w_
EndMacro

Macro vec3MulVal(_v_,_val_,_out_)
  _out_\x = _v_\x * _val_
  _out_\y = _v_\y * _val_
  _out_\z = _v_\z * _val_
EndMacro

Macro vec3Add(_v1_,_v2_,_out_)
  _out_\x = _v1_\x + _v2_\x
  _out_\y = _v1_\y + _v2_\y
  _out_\z = _v1_\z + _v2_\z
EndMacro

Macro vec3Sub(_v1_,_v2_,_out_)
  _out_\x = _v1_\x - _v2_\x
  _out_\y = _v1_\y - _v2_\y
  _out_\z = _v1_\z - _v2_\z
EndMacro

Macro vec3Abs(_v_,_out_)
  _out_\x = Abs(_v_\x)
  _out_\y = Abs(_v_\y)
  _out_\z = Abs(_v_\z)
EndMacro

Macro vec3SubVal(_v_,_val_,_out_)
  _out_\x = _v_\x - _val_
  _out_\y = _v_\y - _val_
  _out_\z = _v_\z - _val_
EndMacro

Macro vec3MaxVal(_v_,_val_,_out_)
  valMax(_v_\x,_val_,_out_\x)
  valMax(_v_\y,_val_,_out_\y)
  valMax(_v_\z,_val_,_out_\z)
EndMacro

Macro vec3RayPos(_ro_,_rd_,_dst_,_out_)
  vec3MulVal(_rd_,_dst_,_out_)
  vec3Add(_ro_,_out_,_out_)
EndMacro

Macro vec3Length(_v_)
  Sqr((_v_\x * _v_\x) + (_v_\y * _v_\y) + (_v_\z * _v_\z))
EndMacro

Macro vec3DivVal(_v_,_val_,_out_)
  _out_\x = _v_\x / _val_
  _out_\y = _v_\y / _val_
  _out_\z = _v_\z / _val_
EndMacro

Macro rayScreen(_v_,_w_,_h_,_out_)
  If _w_ > _h_
    vec2(_out_,(_v_\x - (0.5 * _w_)) / _h_,(_v_\y - (0.5 * _h_)) / _h_)
  Else
    vec2(_out_,(_v_\x - (0.5 * _w_)) / _w_,(_v_\y - (0.5 * _h_)) / _w_)
  EndIf
EndMacro

Procedure.i vec3Normalize(*v.vec3)
  Protected length.f
  length = vec3Length(*v)
  vec3DivVal(*v,length,*v)
  ProcedureReturn
EndProcedure

;------------------------------------------------------------------------------------

Procedure.f sdfCube(*ray.VEC3,*pos.VEC3,size.f)
  Protected mov.VEC3
  vec3Sub(*ray,*pos,mov)
  vec3Abs(mov,mov)
  vec3SubVal(mov,size,mov)
  vec3MaxVal(mov,0.0,mov)
  ProcedureReturn vec3Length(mov)
EndProcedure

Procedure.f sdfTorus(*ray.VEC3,*pos.VEC3,radius.f,size.f)
  Protected dst.VEC3
  vec2(dst,*ray\x - *pos\x,*ray\z - *pos\z)
  vec2(dst,vec2Length(dst) - radius,*ray\y - *pos\y)
  ProcedureReturn vec2Length(dst) - size
EndProcedure

Procedure.f Scene(*ray.VEC3)
  Protected a.VEC3,b.VEC3,c.VEC3
  Protected cube.f,torus.f,d.f,m.f
  *ray\z = Mod(*ray\z + Sin(time / 100.0) * 100.0,8.0) - 4.0
  *ray\x = Mod(*ray\x + Sin(time / 4.0) * 100,8.0) - 4.0
  *ray\y = Mod(Abs(*ray\y) + Sin(time / 10.0),20.0) - 2.0
  vec3(a,0.0,4.0,0.0)
  vec3(b,0.0,6.0,0.0)
  cube = sdfCube(*ray,@a,1.0)
  torus = sdfTorus(*ray,@b,2.0,0.4)
  valMin(cube,torus,d)
  ProcedureReturn d
EndProcedure

Procedure.f Raymarch(*ro.VEC3,*rd.VEC3)
  Protected ray.VEC3,t.f,d.f,i.i
  For i = 0 To 127
    vec3RayPos(*ro,*rd,d,ray)
    t = Scene(@ray):d + t
    If t < 0.01 Or d > 128.0
      Break
    EndIf
  Next
  ProcedureReturn d
EndProcedure

Procedure.i Callback(*coord.VEC2,*color.VEC4)
  Protected uv.VEC2
  Protected ro.VEC3
  Protected rd.VEC3
  Protected d.f
  rayScreen(*coord,320,200,uv)
  vec3(ro,1000.0,12.0 * time,48.0 * time)
  vec3(rd,uv\x,uv\y,1.0)
  vec3Normalize(rd)
  d = 1.2 - (Raymarch(@ro,@rd) / 200.0)
  vec4(*color,Abs(uv\y),d * Sin(time) * Abs(uv\y),d,1.0)
  ProcedureReturn
EndProcedure

;------------------------------------------------------------------------------------

Procedure.i Main()
  Protected *spp.SPP,fps.i
  If sppVersion() = #SPP_VERSION
    If OpenWindow(0,0,0,#SPP_W,#SPP_H,#Null$,#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget)
      WindowBounds(0,WindowWidth(0),WindowHeight(0),#PB_Ignore,#PB_Ignore)
      *spp = sppContext(WindowID(0),320,200)
      If *spp
        If *spp\Event()
          *spp\PixelProc(@Callback(),#True)
          Repeat
            Repeat
              Select WindowEvent()
                Case #PB_Event_SizeWindow:*spp\Viewport()
                Case #PB_Event_CloseWindow:Break 2
                Case #Null:Break
              EndSelect
            ForEver
            *spp\Clear()
            *spp\SwapBuffer()
            *spp\Wait()
            *spp\Info(@fps,@time)
            SetWindowTitle(0,"FPS: " + Str(fps))
          ForEver
        EndIf
        *spp\Release()
      EndIf
      CloseWindow(0) 
    EndIf 
  EndIf
  ProcedureReturn
EndProcedure

Main()

End




Top
 Profile  
Reply with quote  
 Post subject: Re: [Library] SPP (SimplePixelProc) - GFX library [Win x64/x
PostPosted: Sun Jan 10, 2021 10:51 pm 
Offline
User
User

Joined: Sun Oct 09, 2011 7:39 am
Posts: 41
Thx, that's really nice!
Some time ago I wrote a similar program, but it wasn't quite as fast as your library.


Top
 Profile  
Reply with quote  
 Post subject: Re: [Library] SPP (SimplePixelProc) - GFX library [Win x64/x
PostPosted: Mon Jan 11, 2021 10:17 pm 
Offline
Addict
Addict
User avatar

Joined: Sun Sep 11, 2016 2:17 pm
Posts: 804
Mr.L wrote:
Thx, that's really nice!
Some time ago I wrote a similar program, but it wasn't quite as fast as your library.

Thank you :)

--------------------------------------------------------------------------------

Update Alpha 2:
I added a new function sppWindow() which creates a window that hosts a PixelProc callback.
A very fast and easy way to setup SPP 8)
Quote:
sppWindow.i(Title.s,WndWidth.i,WndHeight.i,WndType.i,ScrWidth.i,ScrHeight.i,*Callback,MultiThreaded.i = #False,Milliseconds.i = 16,*Time.Float = #Null,*Frames.Integer = #Null,ShowFrames.i = #True)

Following window modes are supported:

Code:
Enumeration
  #SPP_WINDOW_NORMAL
  #SPP_WINDOW_SIZEABLE
  #SPP_WINDOW_POPUP
  #SPP_WINDOW_SCREEN
EndEnumeration


Example:
Code:
EnableExplicit

XIncludeFile "spp.pbi"

Global time.f
Global fps.i

Structure VEC2
  x.f
  y.f
EndStructure

Structure VEC4
  x.f
  y.f
  z.f
  w.f
EndStructure

Procedure.i Callback(*coord.VEC2,*color.VEC4);<- PixelProc
 ; vec4(*color,0.3 + Sin(time * 4.0),0.6 - Cos(time * 4.0),0.0,1.0)
  *color\x = Sin(time * 4.0)
  *color\y = Cos(time * 4.0)
  ProcedureReturn;<- fastest way to return
EndProcedure

Procedure.i Main()
  Protected state.i
  If sppVersion() = #SPP_VERSION;<- Check if the version is valid!
    state = sppWindow("Test Window",960,600,#SPP_WINDOW_SIZEABLE,320,200,@Callback(),#False,16,@time,@fps,#True);<- If the return is > 0 everything worked!
    ;Note:
    ;#SPP_WINDOW_POPUP -> pressing [ESC] will close the window!
    ;#SPP_WINDOW_SCREEN -> pressing [ESC] will toggle between #SPP_WINDOW_SCREEN and #SPP_WINDOW_NORMAL!
    ;In order to detect [ESC] the window needs to have the input focus!
    ;Dont use Debug on *Time & *Frames!
  EndIf
  If state
    Debug "All went fine!"
  Else
    Debug "There was an error!"
  EndIf
  ProcedureReturn
EndProcedure

Main()

End


Download Alpha 2:
https://www.dropbox.com/s/315f9g9n3imc1ez/spp_alpha_2.zip?dl=0

Have fun :D


Top
 Profile  
Reply with quote  
 Post subject: Re: [Library] SPP (SimplePixelProc) - GFX library [Win x64/x
PostPosted: Fri Jan 15, 2021 4:44 pm 
Offline
Addict
Addict
User avatar

Joined: Sun Sep 11, 2016 2:17 pm
Posts: 804
Update Alpha 3:
- fixed a small bug

Example Blobs:
Image

Code:
Code:
EnableExplicit

;Example 'Shader': Blobs
;Original by PauloFalcao: https://www.shadertoy.com/view/lsfGzr

XIncludeFile "spp.pbi"

Structure VEC2
  x.f
  y.f
EndStructure

Structure VEC4
  x.f
  y.f
  z.f
  w.f
EndStructure

Global time.f

Procedure.f MakePoint(x.f,y.f,fx.f,fy.f,sx.f,sy.f)
  Protected xx.f,yy.f
  xx = x + Sin(time * fx) * sx
  yy = y + Cos(time * fy) * sy
  If xx Or yy
    ProcedureReturn 1.0 / Sqr(xx * xx + yy * yy)
  EndIf
  ProcedureReturn 0.0
EndProcedure

Procedure.i Callback(*coord.VEC2,*color.VEC4)
  Protected x.f,y.f,a.f,b.f,c.f
  x = ((*coord\x / 320) * 2.0 - 1.0) * 2.0
  y = ((*coord\y / 320) * 2.0 - (200 / 320)) * 2.0
  a = MakePoint(x,y,3.3,2.9,0.3,0.3)
  a + MakePoint(x,y,1.9,2.0,0.4,0.4)
  a + MakePoint(x,y,0.8,0.7,0.4,0.5)
  a + MakePoint(x,y,2.3,0.1,0.6,0.3)
  a + MakePoint(x,y,0.8,1.7,0.5,0.4)
  a + MakePoint(x,y,0.3,1.0,0.4,0.4)
  a + MakePoint(x,y,1.4,1.7,0.4,0.5)
  a + MakePoint(x,y,1.3,2.1,0.6,0.3)
  a + MakePoint(x,y,1.8,1.7,0.5,0.4)
  b = MakePoint(x,y,1.2,1.9,0.3,0.3)
  b + MakePoint(x,y,0.7,2.7,0.4,0.4)
  b + MakePoint(x,y,1.4,0.6,0.4,0.5)
  b + MakePoint(x,y,2.6,0.4,0.6,0.3)
  b + MakePoint(x,y,0.7,1.4,0.5,0.4)
  b + MakePoint(x,y,0.7,1.7,0.4,0.4)
  b + MakePoint(x,y,0.8,0.5,0.4,0.5)
  b + MakePoint(x,y,1.4,0.9,0.6,0.3)
  b + MakePoint(x,y,0.7,1.3,0.5,0.4)
  c = MakePoint(x,y,3.7,0.3,0.3,0.3)
  c + MakePoint(x,y,1.9,1.3,0.4,0.4)
  c + MakePoint(x,y,0.8,0.9,0.4,0.5)
  c + MakePoint(x,y,1.2,1.7,0.6,0.3)
  c + MakePoint(x,y,0.3,0.6,0.5,0.4)
  c + MakePoint(x,y,0.3,0.3,0.4,0.4)
  c + MakePoint(x,y,1.4,0.8,0.4,0.5)
  c + MakePoint(x,y,0.2,0.6,0.6,0.3)
  c + MakePoint(x,y,1.3,0.5,0.5,0.4)
  *color\x = a / 32.0
  *color\y = b / 32.0
  *color\z = c / 32.0
  ProcedureReturn
EndProcedure

sppWindow("Example FPS: ",960,600,#SPP_WINDOW_NORMAL,320,200,@Callback(),#True,16,@time,#Null,#True)

End


Download Alpha 3:
https://www.dropbox.com/s/d0456l8pzsoqxwp/spp_alpha_3.zip?dl=0


Last edited by Mijikai on Fri Jan 15, 2021 5:41 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: [Library] SPP (SimplePixelProc) - GFX library [Win x64/x
PostPosted: Fri Jan 15, 2021 5:32 pm 
Offline
User
User

Joined: Sun Oct 09, 2011 7:39 am
Posts: 41
Very nice!!!

I got a "division by zero" error in the Procedure MakePoint but it worked well like this:

Code:
Procedure.f MakePoint(x.f,y.f,fx.f,fy.f,sx.f,sy.f)
  Protected xx.f,yy.f
  xx = x + Sin(time * fx) * sx
  yy = y + Cos(time * fy) * sy
  If xx Or yy
     ProcedureReturn 1.0 / Sqr(xx * xx + yy * yy)
  EndIf
EndProcedure


Top
 Profile  
Reply with quote  
 Post subject: Re: [Library] SPP (SimplePixelProc) - GFX library [Win x64/x
PostPosted: Fri Jan 15, 2021 5:43 pm 
Offline
Addict
Addict
User avatar

Joined: Sun Sep 11, 2016 2:17 pm
Posts: 804
Mr.L wrote:
Very nice!!!

I got a "division by zero" error in the Procedure MakePoint but it worked well like this:
...

Thx, i edited the example code to include your fix :D 8)


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye