[Library] SPP (SimplePixelProc) - GFX library [Win x64/x86]

Applications, Games, Tools, User libs and useful stuff coded in PureBasic
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

[Library] SPP (SimplePixelProc) - GFX library [Win x64/x86]

Post by Mijikai »

SPP is a small, experimental gfx library written in PureBasic.

Latest Release Alpha 7: viewtopic.php?p=586772#p586772 (please note the changes!)

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: Select all


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: Select all


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/c2nk3mi0pbu3z ... a.zip?dl=0

Have fun learning & experimenting :D
Last edited by Mijikai on Wed Nov 08, 2023 2:07 pm, edited 1 time in total.
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: [Library] SPP (SimplePixelProc) - GFX library [Win x64/x

Post by Mijikai »

Another example :)

SDF Raymarching
Image

Code:

Code: Select all

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


Mr.L
Enthusiast
Enthusiast
Posts: 104
Joined: Sun Oct 09, 2011 7:39 am

Re: [Library] SPP (SimplePixelProc) - GFX library [Win x64/x

Post by Mr.L »

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

Re: [Library] SPP (SimplePixelProc) - GFX library [Win x64/x

Post by Mijikai »

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)
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: Select all

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

Code: Select all

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/315f9g9n3imc1 ... 2.zip?dl=0

Have fun :D
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: [Library] SPP (SimplePixelProc) - GFX library [Win x64/x

Post by Mijikai »

Update Alpha 3:
- fixed a small bug

Example Blobs:
Image

Code:

Code: Select all

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/d0456l8pzsoqx ... 3.zip?dl=0
Last edited by Mijikai on Fri Jan 15, 2021 5:41 pm, edited 1 time in total.
Mr.L
Enthusiast
Enthusiast
Posts: 104
Joined: Sun Oct 09, 2011 7:39 am

Re: [Library] SPP (SimplePixelProc) - GFX library [Win x64/x

Post by Mr.L »

Very nice!!!

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

Code: Select all

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
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: [Library] SPP (SimplePixelProc) - GFX library [Win x64/x

Post by Mijikai »

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)
Lirin
New User
New User
Posts: 1
Joined: Tue Feb 23, 2021 12:47 am

Re: [Library] SPP (SimplePixelProc) - GFX library [Win x64/x

Post by Lirin »

I love playing with shaders and this is no exception. Nice work, Mijikai!

I love that this runs even on this old, severely underpowered, Windows XP laptop. Maybe 'runs' isn't the most accurate term in this case, though. Perhaps it's more accurate to say it just sort of...hobbles along? :lol:

Image Image

I'll check this out properly later on today once I get back home and have access to my primary machine.

Edit: I reduced the resolution to 106 x 66 and got 10 FPS. 8)
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: [Library] SPP (SimplePixelProc) - GFX library [Win x64/x

Post by Mijikai »

Thank you :)
Raymarching really pushes the CPU but i think your result is pretty good. 8)
omnikam
User
User
Posts: 27
Joined: Sat Apr 15, 2017 10:58 am

Re: [Library] SPP (SimplePixelProc) - GFX library [Win x64/x86]

Post by omnikam »

Wonderful :D , Can we use this with other screen-outputs ?
Can i renter images or sprites over the top? Or is this a special window that cannot have anything draw over it?
Also how would i go about converting from shadertoy to SPP


// Tweak #2 of sben's 'Flow of cells' (https://www.shadertoy.com/view/MlsGWX)
#define FIELD 10.0
#define HEIGHT 0.7
#define ITERATION 2.0
#define TONE vec4(.2,.4,.8,0)
#define SPEED 0.5

float eq(vec2 p,float t){
float x = sin( p.y-t +cos(t+p.x*.8) ) * cos(p.x-t);
x *= acos(x);
return - x * abs(x-.05) * p.x/p.y*4.9;
}

void mainImage( out vec4 O, vec2 U ) {
vec4 X=O;
vec2 p = FIELD*(U / iResolution.xy +.9);
float t = iTime*SPEED,
hs = FIELD*(HEIGHT+cos(t)*1.9),
x = eq(p,t),
y = p.y-x*0.1;

for(float i=0.; i<ITERATION; ++i)
p.x *= 1.5,
X = x + vec4(0, eq(p,t+i+1.), eq(p,t+i+2.) ,0),
x = X.z += X.y,
O += TONE / abs(y-X-hs);
}
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: [Library] SPP (SimplePixelProc) - GFX library [Win x64/x86]

Post by Mijikai »

omnikam wrote: Sat May 15, 2021 1:45 pm Wonderful :D , Can we use this with other screen-outputs ?
That would be difficult (since it is a software renderer).
Probably the only way is to snatch the backbuffer an render it to a different output.
Or maybe a overlay would also work.
omnikam wrote: Sat May 15, 2021 1:45 pm Can i renter images or sprites over the top? Or is this a special window that cannot have anything draw over it?
It is possible however you need to implement your own routines to render images/sprites
either within the "shader" program or outside (through the backbuffer access - like in the old days).
omnikam wrote: Sat May 15, 2021 1:45 pm Also how would i go about converting from shadertoy to SPP
Its not that easy especially if you have no C background like me but it is doable 8)
I just go line by line and look up what each function does if im not sure and replicate it.

Here is the SPP Version of the shader:

Image

Code: Select all

EnableExplicit

;Original created by Sofiane Benchaa - sben/2015 - License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
;https://www.shadertoy.com/view/MlsGWX

Structure VEC2
  x.f
  y.f
EndStructure

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

XIncludeFile "spp.pbi";SPP Version: Alpha 3!

Global time.f

Procedure.i Equalize(*p.VEC2,t.f)
  Protected x.f
  x = Sin(*p\y + Cos(time * *p\x * 0.2)) * Cos(*p\x - t)
  x * ACos(x)
  ProcedureReturn -x * Abs(x - 0.5) * *p\x / *p\y
EndProcedure

Procedure.i Callback(*coord.VEC2,*color.VEC4)
  Protected o.VEC4
  Protected p.VEC2
  Protected t.f
  Protected hs.f
  Protected x.f
  Protected y.f
  Protected i.f
  Protected pos.VEC4
  o\x = -*color\x
  o\y = -*color\y
  o\y = -*color\z
  o\w = -*color\w
  p\x = 20.0 * (*coord\x / 320 + 0.5)
  p\y = 20.0 * (*coord\y / 200 + 0.5)
  t = time
  hs = 20.0 * (0.7 + Cos(t) * 0.1)
  x = Equalize(@p,t)
  y = p\y - x
  p\x * 2.0
  pos\x = x
  pos\y = Equalize(@p,t + 10.0 + 1.0) + x
  pos\z = Equalize(@p,t + 10.0 + 2.0) + x
  pos\w = x
  x = pos\z + pos\y
  pos\x = Abs(y - pos\x - hs)
  pos\y = Abs(y - pos\y - hs)
  pos\z = Abs(y - pos\z - hs)
  pos\w = Abs(y - pos\w - hs)
  *color\x = o\x + 0.5 / pos\x
  *color\y = o\y + 0.2 / pos\y
  *color\z = o\z + 0.3 / pos\z
  *color\w = o\w + 0.0 / pos\w
  ProcedureReturn
EndProcedure

Procedure.i Main()
  If sppVersion() = #SPP_VERSION
    sppWindow("Flow of cells - (Original by Sofiane Benchaa - sben/2015) - FPS: ",640,400,#SPP_WINDOW_SIZEABLE,320,200,@Callback(),#True,16,@time)
  EndIf
  ProcedureReturn
EndProcedure

Main()

End
Its a bit ugly and not complete (i was lazy) but the core effect is running.
Have fun experimenting :D
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: [Library] SPP (SimplePixelProc) - GFX library [Win x64/x86]

Post by Mijikai »

Project status:

This project is not dead, but so far i have not implemented/changed enough to varant a new release.
The last (released) Version runs stable and im really happy with it.

Im more or less waiting for the proposed new C-backend and its performance.
I would like to implement texture and audio functions similar to shadertoy but the perfomance now is a problem.
Its not bad, dont get me wrong! Its good enough to learn and experiment but ofc. it is also slow compared to real shaders.

If the C-backend doesnt help i could probably boost the perfomance with inline assembly but im no assembly crack.
So im debating if i should start diving into assembly or just wait for the new backend.

Processing external buffers would probably be a nice addition.
That would allow the option of the rendering to be completely independent from SPP.
SPP would only be used to do the "shader" calculations.

I will see what i can do when i have more time or the new C-backend is available.
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: [Library] SPP (SimplePixelProc) - GFX library [Win x64/x86]

Post by Mijikai »

I finally had some time and started to implement the texture sampler 8)
The core works but there are some atrefacts when using the wrapping mode.
Probably just some rounding errors when calculating pixel positions - need to figure that out.
If someone wants to help let me know :)
Image
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: [Library] SPP (SimplePixelProc) - GFX library [Win x64/x86]

Post by Mijikai »

Mandelbrot example :)

Code: Select all

EnableExplicit

;Mandelbrot set based on code by STARGATE
;Original by STARGATE: https://www.purebasic.fr/english/viewtopic.php?p=577849#p577849

;I really like the original so i gave it a try :>
;Unfinished but the core effect works... just wanted to share it ^.^

Structure INT2
  x.i
  y.i
EndStructure

Structure VEC2
  x.f
  y.f
EndStructure

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

Structure PAL
  color.VEC4[12]
EndStructure

XIncludeFile "spp.pbi"

Global time.f

Macro Mix(_x_,_y_,_a_)
  (_x_ * (1 - _a_) + _y_ * _a_)
EndMacro

Procedure.i Rotate(x.f,y.f,angle.f,*out.VEC2)
  Protected vs.f
  Protected vc.f
  angle = Radian(angle)
  vs = Sin(angle)
  vc = Cos(angle)
  *out\x = x * vc - y * vs
  *out\y = x * vs + y * vc
  ProcedureReturn
EndProcedure

Procedure.i Gradient(value.f,*color.VEC4)
  Protected *palette.PAL
  Protected index.i
  Protected rest.f
  *palette = ?palette
  For index = 1 To 11
    If value < *palette\color[index]\w
      Break
    EndIf
  Next
  rest = (value - *palette\color[index - 1]\w) / (*palette\color[index]\w - *palette\color[index - 1]\w)
  *color\x = mix(*palette\color[index - 1]\x,*palette\color[index]\x,rest)
  *color\y = mix(*palette\color[index - 1]\y,*palette\color[index]\y,rest)
  *color\z = mix(*palette\color[index - 1]\z,*palette\color[index]\z,rest)
  *color\w = 1.0
  ProcedureReturn
EndProcedure

Procedure.i Callback(*coord.VEC2,*color.VEC4)
  Protected x.f
  Protected c.VEC2
  Protected z.VEC2
  Protected s.VEC2
  Protected index.i
  Rotate(*coord\x - 400.0,*coord\y - 200.0,0.0,@c)
  c\x = (c\x / 300) - 2.0
  c\y = (c\y / 300) - 0.65
  z\x = 0.0
  z\y = 0.0
  For index = 1 To 16
    s\x = z\x * z\x
    s\y = z\y * z\y
    If (s\x + s\y) > 64
      x = (index - Log(Log(s\x + s\y) * 0.5 * 1.44269502162933) * 1.44269502162933)   
      x = Log(x + 1.0) * Sqr(x) / 50.0
    EndIf
    z\y = 2.0 * z\x * z\y + c\y
    z\x = s\x - s\y + c\x
  Next
  Gradient(Mod(x,1.0),*color)
  ProcedureReturn
EndProcedure

Procedure.i Main()
  If sppVersion() = #SPP_VERSION
    sppWindow("Mandelbrot - FPS: ",1600,800,#SPP_WINDOW_SIZEABLE,1600,800,@Callback(),#True,16,@time)
  EndIf
  ProcedureReturn
EndProcedure

Main()

End

DataSection
  palette:
  !dd 0.000, 0.000, 0.000, 0.00000
  !dd 0.125, 0.000, 0.250, 0.06250
  !dd 0.500, 0.125, 0.250, 0.15625
  !dd 0.875, 0.250, 0.000, 0.25000
  !dd 1.000, 0.500, 0.000, 0.34375
  !dd 1.000, 0.750, 0.000, 0.40625
  !dd 1.000, 1.000, 1.000, 0.50000
  !dd 0.625, 0.875, 0.000, 0.59375
  !dd 0.250, 0.750, 0.000, 0.68750
  !dd 0.000, 0.500, 0.625, 0.78125
  !dd 0.000, 0.250, 0.500, 0.87500
  !dd 0.000, 0.000, 0.000, 1.00000
EndDataSection
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: [Library] SPP (SimplePixelProc) - GFX library [Win x64/x86]

Post by Mijikai »

Update Alpha 7

After quite some time due to serious RL issues im happy to announce the next version.
All code is now compiled with the (PB v.6.00) C-Backend which makes everything faster :)

Other changes:
- Removed the interface now its just one function.
- Improved the timer code and fixed a small bug.
- Changed and improved the window creation and fullscreen routine.

Download Alpha 7:
https://www.dropbox.com/s/6xxppe9v6183m ... 7.zip?dl=0
Post Reply