Модератор: Mikle
Public Type rR_Shadow
Vert() As D3DVECTOR
End Type
Public Function CreateShadow(Light As D3DVECTOR, Mesh As D3DXMesh) As rR_Shadow
Dim Vertices() As D3DVERTEX
ReDim Vertices(Mesh.GetNumVertices)
Dim Indexes() As Integer
ReDim Indexes(Mesh.GetNumFaces * 3)
'//Vertices
D3DXMeshVertexBuffer8GetData Mesh, 0, Len(Vertices(0)) * (Mesh.GetNumVertices), 0, Vertices(0)
'//Indexes
D3DXMeshIndexBuffer8GetData Mesh, 0, Len(Indexes(0)) * (Mesh.GetNumFaces * 3), 0, Indexes(0)
Dim pEdges() As Long
ReDim pEdges(Mesh.GetNumFaces * 6)
Dim numEdge As Long
numEdge = 0
Dim n1 As Long, n2 As Long, n0 As Long
Dim v0 As D3DVECTOR, v1 As D3DVECTOR, v2 As D3DVECTOR
Dim vec As D3DVECTOR, vec1 As D3DVECTOR, vec2 As D3DVECTOR
Dim i As Long
For i = 0 To Mesh.GetNumFaces - 1
n0 = Indexes(3 * i + 0)
n1 = Indexes(3 * i + 1)
n2 = Indexes(3 * i + 2)
v0.x = Vertices(n0).x
v0.Y = Vertices(n0).Y
v0.z = Vertices(n0).z
v1.x = Vertices(n1).x
v1.Y = Vertices(n1).Y
v1.z = Vertices(n1).z
v2.x = Vertices(n2).x
v2.Y = Vertices(n2).Y
v2.z = Vertices(n2).z
D3DXVec3Subtract vec1, v2, v1
D3DXVec3Subtract vec2, v1, v0
D3DXVec3Cross vec, vec1, vec2
If D3DXVec3Dot(vec, Light) >= 0 Then
Call AddEdge(pEdges, numEdge, n0, n1)
Call AddEdge(pEdges, numEdge, n1, n2)
Call AddEdge(pEdges, numEdge, n2, n0)
End If
Next i
Dim L As Long
ReDim CreateShadow.Vert(numEdge * 6)
For i = 0 To numEdge - 1
Dim ve1 As D3DVECTOR, ve2 As D3DVECTOR, ve3 As D3DVECTOR, ve4 As D3DVECTOR
ve1.x = Vertices(pEdges(2 * i + 0)).x
ve1.Y = Vertices(pEdges(2 * i + 0)).Y
ve1.z = Vertices(pEdges(2 * i + 0)).z
ve2.x = Vertices(pEdges(2 * i + 1)).x
ve2.Y = Vertices(pEdges(2 * i + 1)).Y
ve2.z = Vertices(pEdges(2 * i + 1)).z
D3DXVec3Subtract ve3, ve1, Light
D3DXVec3Subtract ve4, ve2, Light
With CreateShadow
.Vert(L) = ve1
L = L + 1
.Vert(L) = ve2
L = L + 1
.Vert(L) = ve3
L = L + 1
.Vert(L) = ve2
L = L + 1
.Vert(L) = ve4
L = L + 1
.Vert(L) = ve3
L = L + 1
End With
Next i
End Function
Sub AddEdge(ByRef pEdges() As Long, ByRef numEdges As Long, v0 As Long, v1 As Long)
Dim i As Long
For i = 0 To numEdges - 1
If (pEdges(2 * i + 0) = v0 Or pEdges(2 * i + 1) = v1) And (pEdges(2 * i + 0) = v1 Or pEdges(2 * i + 1) = v0) Then
If numEdges > 0 Then
pEdges(2 * i + 0) = pEdges(2 * (numEdges - 1) + 0)
pEdges(2 * i + 1) = pEdges(2 * (numEdges - 1) + 1)
End If
numEdges = numEdges - 1
Exit Sub
End If
Next
pEdges(2 * numEdges + 0) = v0
pEdges(2 * numEdges + 1) = v1
numEdges = numEdges + 1
End Sub
Private Sub DrawShadow()
D3DDevice.SetRenderState D3DRS_STENCILENABLE, True
'device.SetRenderState D3DRS_FOGENABLE, False
D3DDevice.SetRenderState D3DRS_ALPHABLENDENABLE, True
D3DDevice.SetRenderState D3DRS_SRCBLEND, D3DBLEND_SRCALPHA
D3DDevice.SetRenderState D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA
D3DDevice.SetTextureStageState 0, D3DTSS_COLORARG1, D3DTA_TEXTURE
D3DDevice.SetTextureStageState 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE
D3DDevice.SetTextureStageState 0, D3DTSS_COLOROP, D3DTOP_MODULATE
D3DDevice.SetTextureStageState 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE
D3DDevice.SetTextureStageState 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE
D3DDevice.SetTextureStageState 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE
'renderizza solo dove il valore è >1 (zona d'ombra)
D3DDevice.SetRenderState D3DRS_STENCILREF, &H1
D3DDevice.SetRenderState D3DRS_STENCILFUNC, D3DCMP_LESSEQUAL
D3DDevice.SetRenderState D3DRS_STENCILPASS, D3DSTENCILOP_KEEP
'rendering unico: viene coperta tutta la zona di nera per coprire l'ombra
D3DDevice.SetVertexShader rR_VertexShader_TL
D3DDevice.SetTexture 0, Nothing
D3DDevice.SetTexture 1, Nothing
'D3DDevice.SetMaterial SHMAT
D3DDevice.DrawPrimitiveUP D3DPT_TRIANGLESTRIP, 2, SQUARE(0), Len(SQUARE(0))
'// riporta il device al suo stato normale
'device.SetRenderState D3DRS_ZENABLE, True
D3DDevice.SetRenderState D3DRS_STENCILENABLE, False
'device.SetRenderState D3DRS_FOGENABLE, True
D3DDevice.SetRenderState D3DRS_ALPHABLENDENABLE, False
End Sub
Private Sub RenderShadow()
D3DDevice.SetRenderState D3DRS_ZWRITEENABLE, False
D3DDevice.SetRenderState D3DRS_STENCILENABLE, True
'per risparmiare un pò non usiamo il gouraud mode
D3DDevice.SetRenderState D3DRS_SHADEMODE, D3DSHADE_FLAT
'settaggi per lo stencil
D3DDevice.SetRenderState D3DRS_STENCILFUNC, D3DCMP_ALWAYS
D3DDevice.SetRenderState D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP
D3DDevice.SetRenderState D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP
'// se il test passa allora incrementa
D3DDevice.SetRenderState D3DRS_STENCILREF, &H1
D3DDevice.SetRenderState D3DRS_STENCILMASK, &HFFFFFFFF
D3DDevice.SetRenderState D3DRS_STENCILWRITEMASK, &HFFFFFFFF
D3DDevice.SetRenderState D3DRS_STENCILPASS, D3DSTENCILOP_INCR
'con questo settaggio non viene disegnato niente
'ma viene sporcato lo stencil buffer
D3DDevice.SetRenderState D3DRS_ALPHABLENDENABLE, True
D3DDevice.SetRenderState D3DRS_SRCBLEND, D3DBLEND_ZERO
D3DDevice.SetRenderState D3DRS_DESTBLEND, D3DBLEND_ONE
D3DDevice.SetVertexShader D3DFVF_XYZ
D3DDevice.SetTexture 0, Nothing
' D3DDevice.SetTexture 1, Nothing
D3DDevice.DrawPrimitiveUP D3DPT_TRIANGLELIST, UBound(Sh.Vert) / 3, Sh.Vert(0), Len(Sh.Vert(0))
D3DDevice.SetRenderState D3DRS_CULLMODE, D3DCULL_CW
'decrementa lo stencil buffer
D3DDevice.SetRenderState D3DRS_STENCILPASS, D3DSTENCILOP_DECR
'RENDERING OPPOSTO
'qui vanno renderizzate tutte le ombra degli oggetti
'renderizza
D3DDevice.SetVertexShader D3DFVF_XYZ
D3DDevice.SetTexture 0, Nothing
' D3DDevice.SetTexture 1, Nothing
D3DDevice.DrawPrimitiveUP D3DPT_TRIANGLELIST, UBound(Sh.Vert) / 3, Sh.Vert(0), Len(Sh.Vert(0))
'riporta lo stato alla normalità
D3DDevice.SetRenderState D3DRS_SHADEMODE, D3DSHADE_GOURAUD
D3DDevice.SetRenderState D3DRS_CULLMODE, D3DCULL_CCW
D3DDevice.SetRenderState D3DRS_ZWRITEENABLE, True
D3DDevice.SetRenderState D3DRS_STENCILENABLE, False
D3DDevice.SetRenderState D3DRS_ALPHABLENDENABLE, False
End Sub
Sub InitSquare()
SQUARE(0).SX = -99999: SQUARE(0).sy = -99999
SQUARE(1).SX = 99999: SQUARE(1).sy = -99999
SQUARE(2).SX = -99999: SQUARE(2).sy = 99999
SQUARE(3).SX = 99999: SQUARE(3).sy = 99999
SQUARE(0).color = &H7F000000 'colore nero con alfa trasparente
SQUARE(1).color = &H7F000000
SQUARE(2).color = &H7F000000
SQUARE(3).color = &H7F000000
SQUARE(0).rhw = 1
SQUARE(1).rhw = 1
SQUARE(2).rhw = 1
SQUARE(3).rhw = 1
End Sub
Ktulhu писал(а):Трабла с примером stencil shadows, о котором шла речь выше:
Как его рационально модифицировать, чтобы тень перепроэцировалась после поворота обьекта???
StimorolD3DX писал(а):Я не пробовал но, наверное нужно вызывать функцию CreateShadow при каждом перемещении обьектов.
А что, проблемы применить матрицу мира к тени??? А вызывать ф-цию придется, т.к. ты же хочешь динамические тени, либо просто оптимизировать ф-цию.. Только вот какKtulhu писал(а):StimorolD3DX писал(а):Я не пробовал но, наверное нужно вызывать функцию CreateShadow при каждом перемещении обьектов.
Дело в том, что эта функция строит тень из буфера вершин мэша, но она не учитывает матрицу мира этого мэша. Да и выхывать эту в-цию каждый кадр сильно скажется на фпс
Vovik писал(а): А что, проблемы применить матрицу мира к тени??? А вызывать ф-цию придется, т.к. ты же хочешь динамические тени, либо просто оптимизировать ф-цию.. Только вот как
DirectXManiac писал(а):Эти тени не рациональны... Сколько пытался нормально не получается. В любом случае надо юзать теневые карты. Примеров не находил, но сейчас хочу вспомнить как использовать DX(уже давно не разбирался ни с чем, все делаю по памяти) и сесть за них...
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 51