Форум: "Игры";
Текущий архив: 2009.02.22;
Скачать: [xml.tar.bz2];
ВнизКласс тени в DirectX Найти похожие ветки
← →
ElectriC © (2007-04-22 21:56) [0]Плиз, помогите перевести нижеприведённый класс тени с C++ на Pascal(Delphi).
class ShadowVolume
{
public:
void reset() { m_dwNumVertices = 0L; }
HRESULT buildShadowVolume( LPD3DXMESH pObject, D3DXVECTOR3 vLight );
HRESULT render( LPDIRECT3DDEVICE9 pd3dDevice );
private:
void addEdge( WORD* pEdges, DWORD& dwNumEdges, WORD v0, WORD v1 );
D3DXVECTOR3 m_pVertices[32000];
DWORD m_dwNumVertices;
};
struct ShadowVertex
{
D3DXVECTOR4 p;
D3DCOLOR color;
enum FVF
{
FVF_Flags = D3DFVF_XYZRHW | D3DFVF_DIFFUSE
};
};
HRESULT ShadowVolume::render( LPDIRECT3DDEVICE9 pd3dDevice )
{
pd3dDevice->SetFVF( D3DFVF_XYZ );
return pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLELIST, m_dwNumVertices/3,
m_pVertices, sizeof(D3DXVECTOR3) );
}
HRESULT ShadowVolume::buildShadowVolume( LPD3DXMESH pMesh, D3DXVECTOR3 vLight )
{
struct MeshVertex { D3DXVECTOR3 p, n; };
MeshVertex *pVertices;
WORD *pIndices;
pMesh->LockVertexBuffer( 0L, (LPVOID*)&pVertices );
pMesh->LockIndexBuffer( 0L, (LPVOID*)&pIndices );
DWORD dwNumFaces = pMesh->GetNumFaces();
WORD *pEdges = new WORD[dwNumFaces*6];
if( pEdges == NULL )
{
pMesh->UnlockVertexBuffer();
pMesh->UnlockIndexBuffer();
return E_OUTOFMEMORY;
}
DWORD dwNumEdges = 0;
for( DWORD i = 0; i < dwNumFaces; ++i )
{
WORD wFace0 = pIndices[3*i+0];
WORD wFace1 = pIndices[3*i+1];
WORD wFace2 = pIndices[3*i+2];
D3DXVECTOR3 v0 = pVertices[wFace0].p;
D3DXVECTOR3 v1 = pVertices[wFace1].p;
D3DXVECTOR3 v2 = pVertices[wFace2].p;
D3DXVECTOR3 vCross1(v2-v1);
D3DXVECTOR3 vCross2(v1-v0);
D3DXVECTOR3 vNormal;
D3DXVec3Cross( &vNormal, &vCross1, &vCross2 );
if( D3DXVec3Dot( &vNormal, &vLight ) >= 0.0f )
{
addEdge( pEdges, dwNumEdges, wFace0, wFace1 );
addEdge( pEdges, dwNumEdges, wFace1, wFace2 );
addEdge( pEdges, dwNumEdges, wFace2, wFace0 );
}
}
for( i = 0; i < dwNumEdges; ++i )
{
D3DXVECTOR3 v1 = pVertices[pEdges[2*i+0]].p;
D3DXVECTOR3 v2 = pVertices[pEdges[2*i+1]].p;
D3DXVECTOR3 v3 = v1 - vLight*10;
D3DXVECTOR3 v4 = v2 - vLight*10;
m_pVertices[m_dwNumVertices++] = v1;
m_pVertices[m_dwNumVertices++] = v2;
m_pVertices[m_dwNumVertices++] = v3;
m_pVertices[m_dwNumVertices++] = v2;
m_pVertices[m_dwNumVertices++] = v4;
m_pVertices[m_dwNumVertices++] = v3;
}
delete[] pEdges;
pMesh->UnlockVertexBuffer();
pMesh->UnlockIndexBuffer();
return S_OK;
}
void ShadowVolume::addEdge( WORD* pEdges, DWORD& dwNumEdges, WORD v0, WORD v1 )
{
for( DWORD i = 0; i < dwNumEdges; ++i )
{
if( ( pEdges[2*i+0] == v0 && pEdges[2*i+1] == v1 ) ||
( pEdges[2*i+0] == v1 && pEdges[2*i+1] == v0 ) )
{
if( dwNumEdges > 1 )
{
pEdges[2*i+0] = pEdges[2*(dwNumEdges-1)+0];
pEdges[2*i+1] = pEdges[2*(dwNumEdges-1)+1];
}
--dwNumEdges;
return;
}
}
pEdges[2*dwNumEdges+0] = v0;
pEdges[2*dwNumEdges+1] = v1;
dwNumEdges++;
}
← →
Sapersky (2007-04-23 13:05) [1]См. пример ShadowVolume из SDK 8 ( http://www.clootie.ru ).
← →
ElectriC © (2007-04-23 19:43) [2]Переделал под DirectX 9, всё равно не выходит.
Пишет: ошибка доступа 0x040545c: не могу прочитать по адресу 0xd92d48e8.
Переключаюсь в asm(окно CPU):
Указатель стоит на строке mov [eax*4+m_pVertices], edx.
Возможно ошибка в строке: MeshObj.LockVertexBuffer(0, Pointer(pVertices));
Не подскажите, в чём, может быть, ошибка?
Код модуля:
...
type
TVertex = packed record
p: TD3DXVector3;
n: TD3DXVector3;
tu, tv: Single;
end;
PVertexArray = ^TVertexArray;
TVertexArray = array [0..0] of TVertex;
TShadowVertex = packed record
p: TD3DXVector4;
color: TD3DColor;
end;
PShadowVertexArray = ^TShadowVertexArray;
TShadowVertexArray = array [0..MaxInt div SizeOf(TShadowVertex) - 1] of TShadowVertex;
const
D3DFVF_VERTEX = D3DFVF_XYZ or D3DFVF_NORMAL or D3DFVF_TEX1;
D3DFVF_SHADOWVERTEX = D3DFVF_XYZRHW or D3DFVF_DIFFUSE;
var
m_pVertices : array [0..32000-1] of TD3DXVector3;
m_dwNumVertices: DWORD;
implementation
procedure Render;
begin
with SLEngine.SLD3DDevice do
begin
SetFVF(D3DFVF_XYZ);
DrawPrimitiveUP(D3DPT_TRIANGLELIST, m_dwNumVertices div 3, m_pVertices,
SizeOf(TD3DXVector3));
end;
end;
procedure AddEdge(var pEdges : array of Word; var dwNumEdges : DWORD; v0, v1 : Word);
var i : Integer;
begin
for i := 0 to (dwNumEdges - 1) do
begin
If ((pEdges[2 * i + 0] = v0) and (pEdges[2 * i + 1] = v1)) or
((pEdges[2 * i + 0] = v1) and (pEdges[2 * i + 1] = v0)) then
begin
If dwNumEdges > 1 then
begin
pEdges[2 * i + 0] := pEdges[2 * (dwNumEdges - 1) + 0];
pEdges[2 * i + 1] := pEdges[2 * (dwNumEdges - 1) + 1];
end;
Dec(dwNumEdges); Exit;
end;
end;
pEdges[2 * dwNumEdges + 0] := v0;
pEdges[2 * dwNumEdges + 1] := v1;
Inc(dwNumEdges);
end;
function BuildFromMesh(vLight: TD3DXVector3) : HRESULT;
type
PMeshVertex = ^TMeshVertex;
TMeshVertex = packed record
p, n : TD3DXVector3;
tu, tv : Single;
end;
PMeshVertexArray = ^TMeshVertexArray;
TMeshVertexArray = array [0..0] of TMeshVertex;
var
// dwFVF: DWORD;
pVertices : PMeshVertexArray;
pIndices : PWordArray;
// dwNumVertices: DWORD;
dwNumFaces : DWORD;
pEdges : array of Word;
dwNumEdges : DWord;
i : Integer;
wFace0, wFace1, wFace2 : Word;
v0, v1, v2, v3, v4 : TD3DXVector3;
v001, v002 : TD3DXVector3;
vNormal : TD3DXVector3;
begin
// Note: the MESHVERTEX format depends on the FVF of the mesh
// dwFVF := pMesh.GetFVF;
// Lock the geometry buffers
MeshObj.LockVertexBuffer(0, Pointer(pVertices));
MeshObj.LockIndexBuffer (0, Pointer(pIndices));
// dwNumVertices := pMesh.GetNumVertices;
dwNumFaces := MeshObj.GetNumFaces;
// Allocate a temporary edge list
SetLength(pEdges, dwNumFaces * 6);
dwNumEdges:= 0;
// For each face
for i:= 0 to (dwNumFaces - 1) do
begin
wFace0 := pIndices[3 * i + 0];
wFace1 := pIndices[3 * i + 1];
wFace2 := pIndices[3 * i + 2];
v0 := pVertices[wFace0].p;
v1 := pVertices[wFace1].p;
v2 := pVertices[wFace2].p;
// Transform vertices or transform light?
D3DXVec3Cross(vNormal, D3DXVec3Subtract(v001, v2, v1)^,
D3DXVec3Subtract(v002, v1, v0)^);
If (D3DXVec3Dot(vNormal, vLight) >= 0.0) then
begin
AddEdge(pEdges, dwNumEdges, wFace0, wFace1);
AddEdge(pEdges, dwNumEdges, wFace1, wFace2);
AddEdge(pEdges, dwNumEdges, wFace2, wFace0);
end;
end;
for i := 0 to (dwNumEdges - 1) do
begin
v1 := pVertices[pEdges[2 * i + 0]].p;
v2 := pVertices[pEdges[2 * i + 1]].p;
D3DXVec3Scale(v001, vLight, 10);
// D3DXVECTOR3 v3 = v1 - vLight*10;
D3DXVec3Subtract(v3, v1, v001);
// D3DXVECTOR3 v4 = v2 - vLight*10;
D3DXVec3Subtract(v4, v2, v001);
// Add a quad (two triangles) to the vertex list
m_pVertices[m_dwNumVertices] := v1; Inc(m_dwNumVertices);
m_pVertices[m_dwNumVertices] := v2; Inc(m_dwNumVertices);
m_pVertices[m_dwNumVertices] := v3; Inc(m_dwNumVertices);
m_pVertices[m_dwNumVertices] := v2; Inc(m_dwNumVertices);
m_pVertices[m_dwNumVertices] := v4; Inc(m_dwNumVertices);
m_pVertices[m_dwNumVertices] := v3; Inc(m_dwNumVertices);
end;
// Delete the temporary edge list
SetLength(pEdges, 0);
// Unlock the geometry buffers
MeshObj.UnlockVertexBuffer;
MeshObj.UnlockIndexBuffer;
Result := S_OK;
end;
P.S. MeshObj : ID3DXMesh - уже загруженная и готовая модель.
← →
ElectriC © (2007-04-24 13:29) [3]Удалено модератором
Примечание: Создание пустых сообщений
Страницы: 1 вся ветка
Форум: "Игры";
Текущий архив: 2009.02.22;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.005 c