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':
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
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
https://www.dropbox.com/s/c2nk3mi0pbu3z ... a.zip?dl=0
Have fun learning & experimenting