UPDATE FOR PARALLEL LIGHT:DevilShadowSystem.bbInclude "Includes\ShadowVolumes.bb"
Include "Includes\DX7Const.bb"
Type ShadowMesh
Field ent, casting
End Type
Type ShadowLight
Field ent, parallel
End Type
Global ShadowCam, ShadowPlane
Global Debug_TimeRender, Debug_TimeInitVolumes, Debug_TimeVolumesBuilt, Debug_ShadowPolys
Function InitShadows(Cam)
ShadowCam = Cam
;ShadowPlane
ShadowPlane = CreateSprite()
ScaleSprite ShadowPlane, 10, 10
EntityParent ShadowPlane, ShadowCam, 0
MoveEntity ShadowPlane, 0, 0, GetCamRangeStart(ShadowCam) + .001
;Volumes
InitVolumes()
;Init DirectX7
If DX7_SetSystemProperties(SystemProperty$("Direct3D7"), SystemProperty$("Direct3DDevice7"), SystemProperty$("DirectDraw7"), SystemProperty$("AppHWND"), SystemProperty$("AppHINSTANCE")) Then RuntimeError "Error initializing dx7."
If DX7_GetStencilBitDepth() < 8 Then
DX7_CreateStencilBuffer()
If DX7_GetStencilBitDepth() < 8 Then RuntimeError "Graphic card does not support stencil buffers."
End If
;Misc
Debug_TimeInitVolumes = 0
SetShadowColors(.5, 0, 0, 0)
End Function
Function FreeShadows()
DX7_RemoveSystemProperties()
FreeVolumes()
Delete Each ShadowMesh
Delete Each ShadowLight
End Function
Function SetShadowColors(alpha#, r = 0, g = 0, b = 0)
If alpha# < 0 Then alpha# = 0
If alpha# > .99 Then alpha# = .99
EntityAlpha ShadowPlane, alpha#
If r < 0 Then r = 0 ElseIf r > 255 Then r = 255
If g < 0 Then g = 0 ElseIf g > 255 Then g = 255
If b < 0 Then b = 0 ElseIf b > 255 Then b = 255
EntityColor ShadowPlane, r, g, b
End Function
Function SetShadowLight(ent, parallel = False)
Delete Each ShadowLight
sl.ShadowLight = New ShadowLight
sl\ent = ent
sl\parallel = parallel
End Function
Function SetShadowMesh(ent, casting = True, path$ = "***")
If casting Then
ms = MilliSecs()
RecursiveShadowCaster(ent, path$)
Debug_TimeInitVolumes = Debug_TimeInitVolumes + MilliSecs() - ms
Else
sm.ShadowMesh = New ShadowMesh
sm\ent = ent
EndIf
End Function
Function RecursiveShadowCaster(ent, path$, file = -1)
If FileType(path$) = 1 Then
LoadVolumeCaster(ent, path$)
Else
If file = -1 And path$ <> "***" Then file = WriteFile(path$)
sm.ShadowMesh = New ShadowMesh
sm\ent = ent
sm\casting = True
InitVolumeCaster(sm\ent)
If file <> - 1 Then
For etem.ETE_Mesh = Each ETE_Mesh
If etem\ent = sm\ent Then
cnt_tris = etem\cnt_tris
WriteInt file, cnt_tris
For v = 0 To cnt_tris
tri.ETE_Triangle = etem\tri[v]
v1.Point3D = tri\v1
v2.Point3D = tri\v2
v3.Point3D = tri\v3
WriteFloat file, v1\x#
WriteFloat file, v1\y#
WriteFloat file, v1\z#
WriteFloat file, v2\x#
WriteFloat file, v2\y#
WriteFloat file, v2\z#
WriteFloat file, v3\x#
WriteFloat file, v3\y#
WriteFloat file, v3\z#
WriteFloat file, tri\nx#
WriteFloat file, tri\ny#
WriteFloat file, tri\nz#
WriteInt file, tri\tri
WriteInt file, tri\ta
WriteInt file, tri\tb
WriteInt file, tri\tc
Next
EndIf
Next
EndIf
cnt_children = CountChildren(ent)
If cnt_children = 0 Then Return
For i = 1 To cnt_children
RecursiveShadowCaster(GetChild(ent, i), "***", file)
Next
EndIf
End Function
Function Render(mode = 0, tween# = 1)
Select mode
Case 0, 2
ClearSurface VolumeSurf
If mode = 2 Then
BuildVolumes()
ShowEntity VolumeMesh
EntityFX VolumeMesh, 17
EntityAlpha VolumeMesh, .5
EndIf
For sm.ShadowMesh = Each ShadowMesh
ShowEntity sm\ent
Next
HideEntity ShadowPlane
CameraClsMode ShadowCam, True, True
ms = MilliSecs()
UpdateWorld
RenderWorld tween#
Debug_TimeRender = MilliSecs() - ms
If mode = 0 Then
Debug_TimeVolumesBuilt = 0
Debug_ShadowPolys = 0
EndIf
Case 1
EntityFX VolumeMesh, 0
EntityAlpha VolumeMesh, .0001
ms = MilliSecs()
RenderShadows(tween#)
Debug_TimeRender = MilliSecs() - ms - Debug_TimeVolumesBuilt
Default
RuntimeError "Wrong render mode."
End Select
End Function
Function RenderShadows(tween#)
HideEntity ShadowPlane
HideEntity VolumeMesh
For sm.ShadowMesh = Each ShadowMesh
ShowEntity sm\ent
Next
DX7_SetRenderState(D3DRS_ZWRITEENABLE, True)
DX7_SetRenderState(D3DRS_STENCILENABLE, False)
DX7_SetRenderState(D3DRS_ALPHABLENDENABLE, False)
DX7_DeviceClear(7, $00008080, 1, 0)
CameraClsMode ShadowCam, True, True
UpdateWorld
RenderWorld tween#
CameraClsMode ShadowCam, False, False
BuildVolumes()
For sm.ShadowMesh = Each ShadowMesh
HideEntity sm\ent
Next
ShowEntity VolumeMesh
DX7_SetRenderState(D3DRS_ZWRITEENABLE, False)
DX7_SetRenderState(D3DRS_STENCILENABLE, True)
DX7_SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS)
DX7_SetRenderState(D3DRS_STENCILREF, 1)
DX7_SetRenderState(D3DRS_STENCILMASK, $FFFFFFFF)
DX7_SetRenderState(D3DRS_STENCILWRITEMASK, $FFFFFFFF)
DX7_SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW)
DX7_SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP)
DX7_SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP)
DX7_SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR)
DX7_SetRenderState(D3DRS_ALPHABLENDENABLE, True)
DX7_SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO)
DX7_SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE)
RenderWorld tween#
DX7_SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_DECR)
DX7_SetRenderState(D3DRS_CULLMODE, D3DCULL_CW)
RenderWorld tween#
DX7_SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW)
HideEntity VolumeMesh
DX7_SetRenderState(D3DRS_ZWRITEENABLE, True)
DX7_SetRenderState(D3DRS_STENCILENABLE, False)
DX7_SetRenderState(D3DRS_ALPHABLENDENABLE, False)
DX7_SetRenderState(D3DRS_ZENABLE, False)
DX7_SetRenderState(D3DRS_STENCILENABLE, True)
DX7_SetRenderState(D3DRS_ALPHABLENDENABLE, True)
DX7_SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA)
DX7_SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA)
DX7_SetRenderState(D3DRS_STENCILREF, 1)
DX7_SetRenderState(D3DRS_STENCILFUNC, D3DCMP_LESSEQUAL)
DX7_SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE)
ShowEntity ShadowPlane
RenderWorld tween#
DX7_SetRenderState(D3DRS_ZENABLE, True)
DX7_SetRenderState(D3DRS_STENCILENABLE, False)
DX7_SetRenderState(D3DRS_ALPHABLENDENABLE, True)
HideEntity ShadowPlane
DX7_SetRenderState(D3DRS_ALPHABLENDENABLE, False)
End Function
Function BuildVolumes()
ms = MilliSecs()
sl.ShadowLight = First ShadowLight
ClearSurface VolumeSurf
CreateVolume(sl\ent, sl\parallel)
Debug_ShadowPolys = CountTriangles(VolumeSurf)
Debug_TimeVolumesBuilt = MilliSecs() - ms
End FunctionShadowVolumes.bbType ETE_Mesh
Field ent
Field cnt_tris, tri.ETE_Triangle[ETE_MaxTriang]
End Type
Type ETE_Triangle
Field v1.Point3D, v2.Point3D, v3.Point3D, nx#, ny#, nz#
Field tri, ta, tb, tc
End Type
Type Point3D
Field x#, y#, z#
End Type
Const ETE_MaxTriang = 65000
Global VolumeMesh, VolumeSurf
Dim TriangleClone.ETE_Triangle(ETE_MaxTriang)
Function InitVolumes()
For i = 0 To ETE_MaxTriang
TriangleClone.ETE_Triangle(i) = New ETE_Triangle
TriangleClone(i)\v1 = New Point3D
TriangleClone(i)\v2 = New Point3D
TriangleClone(i)\v3 = New Point3D
Next
VolumeMesh = CreateMesh()
VolumeSurf = CreateSurface(VolumeMesh)
EntityColor VolumeMesh, 255, 0, 0
EntityAlpha VolumeMesh, .5
EntityFX VolumeMesh, 17
End Function
Function FreeVolumes()
Delete Each ETE_Mesh
Delete Each ETE_Triangle
Delete Each Point3D
If VolumeMesh Then FreeEntity VolumeMesh
End Function
Function InitVolumeCaster(ent, file = -1)
Local ad1[ETE_MaxTriang], ad2[ETE_MaxTriang], ad3[ETE_MaxTriang]
copy = SingleSurfaceMesh(ent)
etem.ETE_Mesh = New ETE_Mesh
etem\ent = ent
surf = GetSurface(copy, 1)
cnt_tris = CountTriangles(surf) - 1
etem\cnt_tris = cnt_tris
For v = 0 To cnt_tris
etem\tri[v] = New ETE_Triangle
etet.ETE_Triangle = etem\tri[v]
etet\v1 = New Point3D
etet\v2 = New Point3D
etet\v3 = New Point3D
v1.Point3D = etet\v1
v2.Point3D = etet\v2
v3.Point3D = etet\v3
vert0 = TriangleVertex(surf, v, 0)
vert1 = TriangleVertex(surf, v, 1)
vert2 = TriangleVertex(surf, v, 2)
v1\x# = VertexX(surf, vert0)
v1\y# = VertexY(surf, vert0)
v1\z# = VertexZ(surf, vert0)
v2\x# = VertexX(surf, vert1)
v2\y# = VertexY(surf, vert1)
v2\z# = VertexZ(surf, vert1)
v3\x# = VertexX(surf, vert2)
v3\y# = VertexY(surf, vert2)
v3\z# = VertexZ(surf, vert2)
e0x# = v3\x# - v2\x#
e0y# = v3\y# - v2\y#
e0z# = v3\z# - v2\z#
e1x# = v2\x# - v1\x#
e1y# = v2\y# - v1\y#
e1z# = v2\z# - v1\z#
etet\nx# = e0y# * e1z# - e0z# * e1y#
etet\ny# = e0z# * e1x# - e0x# * e1z#
etet\nz# = e0x# * e1y# - e0y# * e1x#
etet\tri = v
etet\ta = -1
etet\tb = -1
etet\tc = -1
ad1[v] = True
ad2[v] = True
ad3[v] = True
Next
For a = 0 To cnt_tris
ATriang.ETE_Triangle = etem\tri[a]
v1 = ATriang\v1
v2 = ATriang\v2
v3 = ATriang\v3
For b = a + 1 To cnt_tris
state1 = ad1<b>
state2 = ad2[b]
state3 = ad3[b]
If a <> b And (state1 Or state2 Or state3) Then
BTriang.ETE_Triangle = etem\tri[b]
v2A.Point3D = BTriang\v1
v2B.Point3D = BTriang\v2
v2C.Point3D = BTriang\v3
If state1 Then
If CheckLine(v1, v2A, v2, v2B) Then
ATriang\ta = b
BTriang\ta = a
ad1[b] = False
Goto SIDEA
EndIf
EndIf
If state2 Then
If CheckLine(v1, v2B, v2, v2C) Then
ATriang\ta = b
BTriang\tb = a
ad2[b] = False
Goto SIDEA
EndIf
EndIf
If state3 Then
If CheckLine(v1, v2C, v2, v2A) Then
ATriang\ta = b
BTriang\tc = a
ad3[b] = False
EndIf
EndIf
.SIDEA
If state1 Then
If CheckLine(v2, v2A, v3, v2B) Then
ATriang\tb = b
BTriang\ta = a
ad1[b] = False
Goto SIDEB
EndIf
EndIf
If state2 Then
If CheckLine(v2, v2B, v3, v2C) Then
ATriang\tb = b
BTriang\tb = a
ad2[b] = False
Goto SIDEB
EndIf
EndIf
If state3 Then
If CheckLine(v2, v2C, v3, v2A) Then
ATriang\tb = b
BTriang\tc = a
ad3[b] = False
EndIf
EndIf
.SIDEB
If state1 Then
If CheckLine(v3, v2A, v1, v2B) Then
ATriang\tc = b
BTriang\ta = a
ad1[b] = False
Goto SIDEC
EndIf
EndIf
If state2 Then
If CheckLine(v3, v2B, v1, v2C) Then
ATriang\tc = b
BTriang\tb = a
ad2[b] = False
Goto SIDEC
EndIf
EndIf
If state3 Then
If CheckLine(v3, v2C, v1, v2A) Then
ATriang\tc = b
BTriang\tc = a
ad3[b] = False
EndIf
EndIf
.SIDEC
EndIf
Next
Next
FreeEntity copy
End Function
Function LoadVolumeCaster(ent, path$, file = -1)
If file = -1 Then file = ReadFile(path$)
sm.ShadowMesh = New ShadowMesh
sm\ent = ent
sm\casting = True
etem.ETE_Mesh = New ETE_Mesh
etem\ent = sm\ent
etem\cnt_tris = ReadInt(file)
For v = 0 To etem\cnt_tris
etem\tri[v] = New ETE_Triangle
etet.ETE_Triangle = etem\tri[v]
tri.ETE_Triangle = etem\tri[v]
tri\v1 = New Point3D
tri\v2 = New Point3D
tri\v3 = New Point3D
v1.Point3D = tri\v1
v2.Point3D = tri\v2
v3.Point3D = tri\v3
v1\x# = ReadFloat(file)
v1\y# = ReadFloat(file)
v1\z# = ReadFloat(file)
v2\x# = ReadFloat(file)
v2\y# = ReadFloat(file)
v2\z# = ReadFloat(file)
v3\x# = ReadFloat(file)
v3\y# = ReadFloat(file)
v3\z# = ReadFloat(file)
tri\nx# = ReadFloat(file)
tri\ny# = ReadFloat(file)
tri\nz# = ReadFloat(file)
tri\tri = ReadInt(file)
tri\ta = ReadInt(file)
tri\tb = ReadInt(file)
tri\tc = ReadInt(file)
Next
cnt_children = CountChildren(ent)
For i = 1 To cnt_children
LoadVolumeCaster(GetChild(ent, i), "", file)
Next
End Function
Function CreateVolume(light, parallel = False)
light_x# = EntityX(light, True) * (1 + parallel * 1000000)
light_y# = EntityY(light, True) * (1 + parallel * 1000000)
light_z# = EntityZ(light, True) * (1 + parallel * 1000000)
volume_lenght = 1000
For etem.ETE_Mesh = Each ETE_Mesh
cnt_tris = etem\cnt_tris
For v = 0 To cnt_tris
etet.ETE_Triangle = TriangleClone(v)
CloneTriangle(etet, etem\tri[v])
v1.Point3D = etet\v1
v2.Point3D = etet\v2
v3.Point3D = etet\v3
TFormPoint v1\x#, v1\y#, v1\z#, etem\ent, 0
v1\x# = TFormedX()
v1\y# = TFormedY()
v1\z# = TFormedZ()
TFormPoint v2\x#, v2\y#, v2\z#, etem\ent, 0
v2\x# = TFormedX()
v2\y# = TFormedY()
v2\z# = TFormedZ()
TFormPoint v3\x#, v3\y#, v3\z#, etem\ent, 0
v3\x# = TFormedX()
v3\y# = TFormedY()
v3\z# = TFormedZ()
TFormNormal etet\nx#, etet\ny#, etet\nz#, etem\ent, 0
normlight_x# = (v1\x# + v2\x# + v3\x#) / 3.0 - light_x#
normlight_y# = (v1\y# + v2\y# + v3\y#) / 3.0 - light_y#
normlight_z# = (v1\z# + v2\z# + v3\z#) / 3.0 - light_z#
If TFormedX() * normlight_x# + TFormedY() * normlight_y# + TFormedZ() * normlight_z# < 0 Then etet\tri = -1
Next
For v = 0 To cnt_tris
etet = TriangleClone(v)
If etet\tri => 0 Then
ta = etet\ta
tb = etet\tb
tc = etet\tc
If ta > -1 Then check1 = TriangleClone(ta)\tri Else check1 = -1
If tb > -1 Then check2 = TriangleClone(tb)\tri Else check2 = -1
If tc > -1 Then check3 = TriangleClone(tc)\tri Else check3 = -1
If check1 < 0 Or check2 < 0 Or check3 < 0 Then
v1 = etet\v1
v2 = etet\v2
v3 = etet\v3
If check1 < 0 Then
rax# = v1\x# + (v1\x# - light_x#) * volume_lenght
ray# = v1\y# + (v1\y# - light_y#) * volume_lenght
raz# = v1\z# + (v1\z# - light_z#) * volume_lenght
rbx# = v2\x# + (v2\x# - light_x#) * volume_lenght
rby# = v2\y# + (v2\y# - light_y#) * volume_lenght
rbz# = v2\z# + (v2\z# - light_z#) * volume_lenght
vert1 = AddVertex(VolumeSurf, v1\x#, v1\y#, v1\z#)
vert2 = AddVertex(VolumeSurf, rax#, ray#, raz#)
vert3 = AddVertex(VolumeSurf, rbx#, rby#, rbz#)
vert4 = AddVertex(VolumeSurf, v2\x#, v2\y#, v2\z#)
AddTriangle(VolumeSurf, vert1, vert2, vert3)
AddTriangle(VolumeSurf, vert1, vert3, vert4)
EndIf
If check2 < 0 Then
rbx# = v2\x# + (v2\x# - light_x#) * volume_lenght
rby# = v2\y# + (v2\y# - light_y#) * volume_lenght
rbz# = v2\z# + (v2\z# - light_z#) * volume_lenght
rcx# = v3\x# + (v3\x# - light_x#) * volume_lenght
rcy# = v3\y# + (v3\y# - light_y#) * volume_lenght
rcz# = v3\z# + (v3\z# - light_z#) * volume_lenght
vert1 = AddVertex(VolumeSurf, v2\x#, v2\y#, v2\z#)
vert2 = AddVertex(VolumeSurf, rbx#, rby#, rbz#)
vert3 = AddVertex(VolumeSurf, rcx#, rcy#, rcz#)
vert4 = AddVertex(VolumeSurf, v3\x#, v3\y#, v3\z#)
AddTriangle(VolumeSurf, vert1, vert2, vert3)
AddTriangle(VolumeSurf, vert1, vert3, vert4)
EndIf
If check3 < 0 Then
rax# = v1\x# + (v1\x# - light_x#) * volume_lenght
ray# = v1\y# + (v1\y# - light_y#) * volume_lenght
raz# = v1\z# + (v1\z# - light_z#) * volume_lenght
rcx# = v3\x# + (v3\x# - light_x#) * volume_lenght
rcy# = v3\y# + (v3\y# - light_y#) * volume_lenght
rcz# = v3\z# + (v3\z# - light_z#) * volume_lenght
vert1 = AddVertex(VolumeSurf, v1\x#, v1\y#, v1\z#)
vert2 = AddVertex(VolumeSurf, rax#, ray#, raz#)
vert3 = AddVertex(VolumeSurf, rcx#, rcy#, rcz#)
vert4 = AddVertex(VolumeSurf, v3\x#, v3\y#, v3\z#)
AddTriangle(VolumeSurf, vert1, vert3, vert2)
AddTriangle(VolumeSurf, vert1, vert4, vert3)
EndIf
EndIf
EndIf
Next
Next
End Function
Function SingleSurfaceMesh(ent)
ret = CopyMesh(ent)
If CountSurfaces(ret) = 1 Then
Return ret
Else
FreeEntity ret
ret = CreateMesh()
new_surf = CreateSurface(ret)
For s = 1 To CountSurfaces(ent)
surf = GetSurface(ent, s)
For t = 0 To CountTriangles(surf) - 1
v0 = TriangleVertex(surf, t, 0)
v1 = TriangleVertex(surf, t, 1)
v2 = TriangleVertex(surf, t, 2)
new_v1 = AddVertex(new_surf, VertexX(surf, v0), VertexY(surf, v0), VertexZ(surf, v0))
new_v2 = AddVertex(new_surf, VertexX(surf, v1), VertexY(surf, v1), VertexZ(surf, v1))
new_v3 = AddVertex(new_surf, VertexX(surf, v2), VertexY(surf, v2), VertexZ(surf, v2))
AddTriangle new_surf, new_v1, new_v2, new_v3
Next
Next
Return ret
EndIf
End Function
Function CloneTriangle(dst.ETE_Triangle, src.ETE_Triangle)
dst\v1\x# = src\v1\x#
dst\v1\y# = src\v1\y#
dst\v1\z# = src\v1\z#
dst\v2\x# = src\v2\x#
dst\v2\y# = src\v2\y#
dst\v2\z# = src\v2\z#
dst\v3\x# = src\v3\x#
dst\v3\y# = src\v3\y#
dst\v3\z# = src\v3\z#
dst\nx# = src\nx#
dst\ny# = src\ny#
dst\nz# = src\nz#
dst\tri = src\tri
dst\ta = src\ta
dst\tb = src\tb
dst\tc = src\tc
End Function
Function CheckLine(a1.Point3D, b1.Point3D, a2.Point3D, b2.Point3D)
c1 = (a1\x# = a2\x# And a1\y# = a2\y# And a1\z# = a2\z#)
c2 = (b1\x# = b2\x# And b1\y# = b2\y# And b1\z# = b2\z#)
c3 = (a1\x# = b2\x# And a1\y# = b2\y# And a1\z# = b2\z#)
c4 = (b1\x# = a2\x# And b1\y# = a2\y# And b1\z# = a2\z#)
If (c1 And c2) Or (c3 And c4) Then Return True Else Return False
End Function
[b]DX7Const.bb
Const D3DCULL_NONE = 1
Const D3DCULL_CW = 2
Const D3DCULL_CCW = 3
Const D3DSTENCILOP_KEEP = 1
Const D3DSTENCILOP_ZERO = 2
Const D3DSTENCILOP_REPLACE = 3
Const D3DSTENCILOP_INCRSAT = 4
Const D3DSTENCILOP_DECRSAT = 5
Const D3DSTENCILOP_INVERT = 6
Const D3DSTENCILOP_INCR = 7
Const D3DSTENCILOP_DECR = 8
Const D3DSTENCILOP_FORCE_DWORD = $7FFFFFFF
Const D3DCMP_NEVER = 1
Const D3DCMP_LESS = 2
Const D3DCMP_EQUAL = 3
Const D3DCMP_LESSEQUAL = 4
Const D3DCMP_GREATER = 5
Const D3DCMP_NOTEQUAL = 6
Const D3DCMP_GREATEREQUAL = 7
Const D3DCMP_ALWAYS = 8
Const D3DCMP_FORCE_DWORD = $7FFFFFFF
Const D3DBLEND_ZERO = 1
Const D3DBLEND_ONE = 2
Const D3DBLEND_SRCCOLOR = 3
Const D3DBLEND_INVSRCCOLOR = 4
Const D3DBLEND_SRCALPHA = 5
Const D3DBLEND_INVSRCALPHA = 6
Const D3DBLEND_DESTALPHA = 7
Const D3DBLEND_INVDESTALPHA = 8
Const D3DBLEND_DESTCOLOR = 9
Const D3DBLEND_INVDESTCOLOR = 10
Const D3DBLEND_SRCALPHASAT = 11
Const D3DBLEND_BOTHSRCALPHA = 12
Const D3DBLEND_BOTHINVSRCALPHA = 13
Const D3DBLEND_FORCE_DWORD = $7FFFFFFF
Const D3DRS_ANTIALIAS= 2
Const D3DRS_TEXTUREPERSPECTIVE = 4
Const D3DRS_ZENABLE = 7
Const D3DRS_FILLMODE = 8
Const D3DRS_SHADEMODE = 9
Const D3DRS_LINEPATTERN = 10
Const D3DRS_ZWRITEENABLE = 14
Const D3DRS_ALPHATESTENABLE = 15
Const D3DRS_LASTPIXEL = 16
Const D3DRS_SRCBLEND = 19
Const D3DRS_DESTBLEND = 20
Const D3DRS_CULLMODE = 22
Const D3DRS_ZFUNC = 23
Const D3DRS_ALPHAREF = 24
Const D3DRS_ALPHAFUNC = 25
Const D3DRS_DITHERENABLE = 26
Const D3DRS_ALPHABLENDENABLE = 27
Const D3DRS_FOGENABLE = 28
Const D3DRS_SPECULARENABLE = 29
Const D3DRS_ZVISIBLE = 30
Const D3DRS_STIPPLEDALPHA = 33
Const D3DRS_FOGCOLOR = 34
Const D3DRS_FOGTABLEMODE = 35
Const D3DRS_FOGSTART = 36
Const D3DRS_FOGEND = 37
Const D3DRS_FOGDENSITY = 38
Const D3DRS_EDGEANTIALIAS = 40
Const D3DRS_COLORKEYENABLE = 41
Const D3DRS_ZBIAS = 47
Const D3DRS_RANGEFOGENABLE = 48
Const D3DRS_STENCILENABLE = 52
Const D3DRS_STENCILFAIL = 53
Const D3DRS_STENCILZFAIL = 54
Const D3DRS_STENCILPASS = 55
Const D3DRS_STENCILFUNC = 56
Const D3DRS_STENCILREF = 57
Const D3DRS_STENCILMASK = 58
Const D3DRS_STENCILWRITEMASK = 59
Const D3DRS_TEXTUREFACTOR = 60
Const D3DCLEAR_TARGET = $00000001
Const D3DCLEAR_ZBUFFER = $00000002
Const D3DCLEAR_STENCIL = $00000004