-
Плиз, помогите перевести нижеприведённый класс тени с 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++; }
-
-
Переделал под 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 - уже загруженная и готовая модель.
-
Удалено модератором Примечание: Создание пустых сообщений
|