Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Игры";
Текущий архив: 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
2-1231518350
happynewyear
2009-01-09 19:25
2009.02.22
как корректно закрыть программу если отсоед родительский диск?


2-1228673231
dr_creigan
2008-12-07 21:07
2009.02.22
Excel


15-1230014400
Германн
2008-12-23 09:40
2009.02.22
Глюки обоняния


4-1206045437
i
2008-03-20 23:37
2009.02.22
Novell netware login name...


15-1230012779
Slider007
2008-12-23 09:12
2009.02.22
С днем рождения ! 23 декабря 2008 вторник





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский