Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.02.22;
Скачать: CL | DM;

Вниз

Класс тени в 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;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.017 c
15-1230279407
Andy BitOff
2008-12-26 11:16
2009.02.22
Поделитесь идей иконки и/или иконкой


2-1231614795
Б
2009-01-10 22:13
2009.02.22
Как убрать зазубринки при поворе растра?


3-1215425858
Александр В Б
2008-07-07 14:17
2009.02.22
Как работать с типом поля VARBYTES


15-1229958038
БарЛог
2008-12-22 18:00
2009.02.22
Форматы даты/времени


6-1199280101
Venkin
2008-01-02 16:21
2009.02.22
отправить картинку на radikal.ru (INDY)