After the success of the first shaders lib, I rewrote the DLL. The commands are now fewer, and it's completely open-ended. There will be no more additions or changes to the commands, because the system is now flexible enough that new shaders can be added.
You now have two main commands. CreateShader(texture,style) creates a shader. Use ShaderSet() to set various parameters. Call UpdateShaders() before any RenderWorld call.
Shader.decls:
.lib "dlls\shaders.dll"
ShaderNames$()
CreateShader%(texture,style)
ShaderSet(shader,param,value#)
ShaderGet#(shader,param)
FindShader%(texture)
FreeShader(shader)
UpdateShaders()
Shaders.dll source:
Global SHADERBUFFER
Global COUNTSHADERS
Global svar.s
#ALLOWEDPARAMS=4
Procedure TextureFlags(texture)
ProcedureReturn PeekL(texture+32)
EndProcedure
Procedure.l GetTextureBlend(texture)
texture=PeekL(texture)
ProcedureReturn PeekL(texture+24)
EndProcedure
Procedure GetTextureCoords(texture)
ProcedureReturn PeekL(texture+52)
EndProcedure
Procedure.f TextureU(texture)
texture=PeekL(texture)
ProcedureReturn -PeekF(texture+44)
EndProcedure
Procedure.f TextureV(texture)
texture=PeekL(texture)
ProcedureReturn -PeekF(texture+48)
EndProcedure
Procedure.f TextureScaleU(texture)
texture=PeekL(texture)
ProcedureReturn (1.0/PeekF(texture+36))
EndProcedure
Procedure.f TextureScaleV(texture)
texture=PeekL(texture)
ProcedureReturn (1.0/PeekF(texture+40))
EndProcedure
Procedure.f TextureAngle(texture)
texture=PeekL(texture)
ProcedureReturn ((-360.0*PeekF(texture+52))/2.0/3.14159265)
EndProcedure
Procedure PositionTexture(texture,u.f,v.f)
texture=PeekL(texture)
PokeF(texture+44,-u.f)
PokeF(texture+48,-v.f)
PokeL(texture+56,11337729)
EndProcedure
Procedure ScaleTexture(texture,u.f,v.f)
texture=PeekL(texture)
PokeF(texture+36,1.0/u.f)
PokeF(texture+40,1.0/v.f)
PokeL(texture+56,11337729)
EndProcedure
Procedure RotateTexture(texture,a.f)
texture=PeekL(texture)
PokeF(texture+52,-a.f*3.14159265/180.0)
PokeL(texture+56,11337729)
EndProcedure
Procedure TextureBlend(texture,blend)
texture=PeekL(texture)
PokeL(texture+24,blend)
EndProcedure
Procedure.f Mod(numerator.f,divider.f)
Repeat
numerator.f=numerator.f-divider.f
Until numerator.f<divider.f
ProcedureReturn numerator.f
EndProcedure
Procedure.f SawTooth(angle.f)
angle=mod(angle,360.0)
If angle<90.0
ProcedureReturn (angle/90.0)
EndIf
If angle<180.0
ProcedureReturn (1.0-(angle-90.0)/90.0)
EndIf
If angle<270.0
ProcedureReturn (-(angle-180.0)/90.0)
EndIf
If angle<360.0
ProcedureReturn (-1.0+(angle-270.0)/90.0)
EndIf
EndProcedure
ProcedureDLL CreateShader(texture,style)
shader=AllocateMemory(24+#ALLOWEDPARAMS*4)
PokeL(shader,texture)
PokeL(shader+4,style)
PokeF(shader+8,TextureU(texture))
PokeF(shader+12,TextureV(texture))
PokeF(shader+16,TextureScaleU(texture))
PokeF(shader+20,TextureScaleV(texture))
PokeF(shader+24,TextureAngle(texture))
If COUNTSHADERS=0
SHADERBUFFER=AllocateMemory(4)
Else
SHADERBUFFER=ReAllocateMemory(SHADERBUFFER,COUNTSHADERS*4+4)
EndIf
PokeL(SHADERBUFFER+COUNTSHADERS*4,shader)
COUNTSHADERS=COUNTSHADERS+1
ProcedureReturn shader
EndProcedure
ProcedureDLL.l ShaderNames()
svar="Scroll|Sway|Spin|Pulse|Random|Sawtooth"
ProcedureReturn @svar
EndProcedure
ProcedureDLL ShaderSet(shader,param,value.f)
If param=>0 And param<#ALLOWEDPARAMS
PokeF(shader+param*4+24,value.f)
EndIf
EndProcedure
ProcedureDLL.f ShaderGet(shader,param)
If param=>0 And param<#ALLOWEDPARAMS
ProcedureReturn PeekF(shader+param*4+24)
Else
ProcedureReturn 0.0
EndIf
EndProcedure
ProcedureDLL.l FindShader(texture)
time.f=GetTickCount_()
For n=0 To COUNTSHADERS-1
shader=PeekL(SHADERBUFFER+n*4)
If texture=PeekL(shader)
ProcedureReturn shader
EndIf
Next
EndProcedure
ProcedureDLL FreeShader(shader)
FreeMemory(shader)
For n=0 To COUNTSHADERS-1
If shader=PeekL(SHADERBUFFER+n*4)
For m=n To COUNTSHADERS-2
PokeL(SHADERBUFFER+m*4,PeekL(SHADERBUFFER+m*4+4))
Next
COUNTSHADERS=COUNTSHADERS-1
SHADERBUFFER=ReAllocateMemory(SHADERBUFFER,COUNTSHADERS*4+4)
EndIf
Next
EndProcedure
ProcedureDLL UpdateShaders()
time.f=GetTickCount_()
For n=0 To COUNTSHADERS-1
shader=PeekL(SHADERBUFFER+n*4)
texture=PeekL(shader)
Select PeekL(shader+4)
;Scroll
Case 0
PositionTexture(texture,time.f/1000.0*ShaderGet(shader,0),time.f/1000.0*ShaderGet(shader,1))
;Sway
Case 1
a.f=time.f/1000.0*360.0*ShaderGet(shader,2)
a.f=(a.f*3.14159265)/180.0
PositionTexture(texture,Sin(a)*ShaderGet(shader,0),Cos(a)*ShaderGet(shader,1))
;Spin
Case 2
a.f=time.f/1000.0*360.0*ShaderGet(shader,0)
rotatetexture(texture,a.f)
a.f=(a.f*3.14159265)/180.0
u.f=Cos(a.f)/2.0
v.f=Sin(a.f)/2.0
PositionTexture(texture,(u.f-0.5)-v.f,(v.f-0.5)+u.f)
;Pulse
Case 3
a.f=(360.0*time.f/1000.0)*ShaderGet(shader,0)
a.f=(a.f*3.14159265)/180.0
scale.f=Sin(a)*ShaderGet(shader,1)
scaletexture(texture,1.0+scale,1.0+scale)
u.f=(1.0-scale)/2.0-0.5
v.f=(1.0-scale)/2.0-0.5
;offsetu.f=PeekF(shader+16)
;offsetv.f=PeekF(shader+20)
;PokeF(shader+16,u)
;PokeF(shader+20,v)
;u=u+textureu(texture)-offsetu
;v=v+texturev(texture)-offsetv
positiontexture(texture,u,v)
;Random
Case 4
u.f=Random(1000)
u.f=u.f/1000.0
v.f=Random(1000)
v.f=v.f/1000.0
positiontexture(texture,u,v)
;Sawtooth
Case 5
u.f=time.f/1000.0*ShaderGet(shader,0)
v.f=sawtooth((u*360.0)/ShaderGet(shader,0)/4.0/ShaderGet(shader,1))*ShaderGet(shader,1)
positiontexture(texture,u,v)
;Case 7
; If mod(time*ShaderGet(shader,1),2000)>1000
; textureblend(texture,0);PeekL(shader+16))
; Else
; textureblend(texture,ShaderGet(shader,0))
; EndIf
EndSelect
Next
EndProcedure
|