Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Игры";
Текущий архив: 2009.01.11;
Скачать: [xml.tar.bz2];

Вниз

Пример из туториала по Direct3D   Найти похожие ветки 

 
Piroxyline ©   (2007-04-15 13:47) [0]

Читаю туториал по Direct3D от мелкомягкого. Чтобы не дай Бог чего-нибудь наперекосяк не пошло (с этим зверем никогда не работал), делаю все так, как там сказано. Ну, иногда переписываю часть кода из примеров, чтобы все работало, где-то экспериментирую, сравниваю с OpenGL, но это мелочи. Пользуюсь джедаевскими заголовками. В-общем, кто-нибудь может мне объяснить, почему эти прямоугольники не могут вращаться как им положено?

program Project1;

uses
 Windows,
 Messages,
 Direct3D9,
 D3DX9;

const
 D3DFVF_CUSTOMVERTEX = D3DFVF_XYZ or D3DFVF_DIFFUSE;

type
 HINST = Cardinal;
 Float = Single;

 CUSTOMVERTEX = record
   x, y, z: Float;
   color: DWord;
 end;

var
 g_hInst: HINST = 0;
 g_hWnd: HWND = 0;
 g_pD3D: IDirect3D9;
 g_pd3dDevice: IDirect3DDevice9;

 g_pVB: IDirect3DVertexBuffer9;

 vertices: Array[0..11] of CUSTOMVERTEX =
                                   ((x: 0.0; y: 0.0; z: 0.0; color: $ffff0000),
                                    (x: 1.0; y: 0.0; z: 0.0; color: $ff0000ff),
                                    (x: 1.0; y: 1.0; z: 0.0; color: $ffffffff),

                                    (x: 1.0; y: 1.0; z: 0.0; color: $ffff0000),
                                    (x: 0.0; y: 1.0; z: 0.0; color: $ff0000ff),
                                    (x: 0.0; y: 0.0; z: 0.0; color: $ffffffff),

                                    (x: 0.0; y: 0.0; z: 1.0; color: $ffff0000),
                                    (x: 1.0; y: 0.0; z: 1.0; color: $ff0000ff),
                                    (x: 1.0; y: 1.0; z: 1.0; color: $ffffffff),

                                    (x: 1.0; y: 1.0; z: 1.0; color: $ffff0000),
                                    (x: 0.0; y: 1.0; z: 1.0; color: $ff0000ff),
                                    (x: 0.0; y: 0.0; z: 1.0; color: $ffffffff));

procedure Render;
var
 matWorld: TD3DXMATRIXA16;
 matView: TD3DXMATRIXA16;
 matProj: TD3DXMATRIXA16;
 iTime: Integer;
 fAngle: Float;
 vEyePt, vLookatPt, vUpVec: TD3DXVECTOR3;
begin
 g_pd3dDevice.Clear(0, 0, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0, 0);
 g_pd3dDevice.BeginScene;

 iTime  := GetTickCount();
 fAngle := iTime * (1.0 * D3DX_PI) / 1000.0;
 D3DXMatrixRotationY( matWorld, fAngle );
 g_pd3dDevice.SetTransform( D3DTS_WORLD, matWorld );

 vEyePt := D3DXVECTOR3( 0.0, 3.0,-5.0 );
 vLookatPt := D3DXVECTOR3( 0.0, 0.0, 0.0 );
 vUpVec := D3DXVECTOR3( 0.0, 1.0, 0.0 );
 D3DXMatrixLookAtLH( matView, vEyePt, vLookatPt, vUpVec );
 g_pd3dDevice.SetTransform( D3DTS_VIEW, matView );

 D3DXMatrixPerspectiveFovLH( matProj, D3DX_PI/4, 1.0, 1.0, 100.0 );
 g_pd3dDevice.SetTransform( D3DTS_PROJECTION, matProj );

 g_pd3dDevice.SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) );
 g_pd3dDevice.SetFVF( D3DFVF_CUSTOMVERTEX );
 g_pd3dDevice.DrawPrimitive( D3DPT_TRIANGLELIST, 0, Length(vertices) div 3 );

 g_pd3dDevice.EndScene;
 g_pd3dDevice.Present(nil, nil, 0, nil);
end;

procedure Cleanup;
begin
 if g_pVB <> nil then begin
   g_pVB._Release;
   g_pVB := nil;
 end;
 if g_pd3dDevice <> nil then begin
   g_pd3dDevice._Release;
   g_pd3dDevice := nil;
 end;
 if g_pD3D <> nil then begin
   g_pD3D._Release;
   g_pD3D := nil;
 end;
end;

function WndProc(hWnd: HWND; Message: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
 case Message of
   WM_PAINT: begin
     Render;
   end;
   WM_DESTROY: begin
     PostQuitMessage(0);
     Cleanup;
   end;
   else begin
     Result := DefWindowProc(hWnd, message, wParam, lParam);
     Exit;
   end;
 end;

 Result := 0;
end;

function InitWindow(hInstance: HINST; nCmdShow: Integer): HRESULT;
var
 wcex: WNDCLASSEX;
 rc: TRect;
begin
 Result := E_FAIL;

 wcex.cbSize := sizeof(WNDCLASSEX);
 wcex.style          := CS_HREDRAW or CS_VREDRAW;
 wcex.lpfnWndProc    := @WndProc;
 wcex.cbClsExtra     := 0;
 wcex.cbWndExtra     := 0;
 wcex.hInstance      := hInstance;
 wcex.hIcon          := LoadIcon(0, IDI_APPLICATION);
 wcex.hCursor        := LoadCursor(0, IDC_ARROW);
 wcex.hbrBackground  := COLOR_WINDOW+1;
 wcex.lpszMenuName   := 0;
 wcex.lpszClassName  := "TutorialWindowClass";
 wcex.hIconSm        := LoadIcon(0, IDI_APPLICATION);
 if RegisterClassEx(wcex) = 0 then Exit;

 g_hInst := hInstance;
 rc.Left := 0;
 rc.Top := 0;
 rc.Right := 640;
 rc.Bottom := 480;

 AdjustWindowRect( rc, WS_OVERLAPPEDWINDOW, FALSE );
 g_hWnd := CreateWindow( "TutorialWindowClass", "Direct3D 10 Tutorial 0: Setting Up Window", WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, 0, 0, hInstance, 0);
 if g_hWnd = 0 then Exit;

 ShowWindow( g_hWnd, nCmdShow );

 Result := S_OK;
end;

function InitD3D: HRESULT;
var
 d3dpp: D3DPRESENT_PARAMETERS;
 pVertices: Pointer;
begin
 Result := E_FAIL;

 g_pD3D := Direct3DCreate9(D3D_SDK_VERSION);

 if g_pD3D = nil then Exit;

 ZeroMemory(@d3dpp, SizeOf(d3dpp));

 d3dpp.Windowed := TRUE;
 d3dpp.SwapEffect := D3DSWAPEFFECT_DISCARD;
 d3dpp.BackBufferFormat := D3DFMT_UNKNOWN;

 if( FAILED( g_pD3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd,
                                 D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                 @d3dpp, g_pd3dDevice ) ) ) then Exit;

 g_pd3dDevice.SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
 g_pd3dDevice.SetRenderState( D3DRS_LIGHTING, iFalse );

 if FAILED( g_pd3dDevice.CreateVertexBuffer( sizeof(vertices),
        0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, g_pVB, 0 ) ) then Exit;

 if FAILED( g_pVB.Lock( 0, sizeof(vertices), pVertices, 0 ) ) then Exit;

 CopyMemory(pVertices, @vertices, sizeof(vertices));

 g_pVB.Unlock;

 Result := S_OK;
end;

function wWinMain(hInstance, hPrevInstance: HINST; lpCmdLine: PChar; nCmdShow: Integer): Integer; stdcall;
var
 msg: tagMSG;
begin
 Result := 0;
 if FAILED( InitWindow( hInstance, nCmdShow ) ) then Exit;
 if FAILED( InitD3D ) then Exit;
 while( GetMessage( msg, 0, 0, 0 ) ) do begin
   TranslateMessage( msg );
   DispatchMessage( msg );
 end;
 Result := msg.wParam;
end;

begin
 wWinMain(hInstance, hPrevInst, CmdLine, CmdShow);
end.


 
Sapersky   (2007-04-16 13:00) [1]

Если нужно, чтобы они вращались симметрично - вычесть 0.5 из всех координат, т.к. матрица трансформации поворачивает относительно центра (0,0,0). Можно включить перемещение в саму матрицу.


 
Мистер Т   (2007-04-19 07:56) [2]

Если Сишный код не проблема - много хороших туториалов тут:
http://www.codesampler.com/dx9src.htm

Но
> почему эти прямоугольники не могут вращаться как им положено?
А как положено ? =)
То есть - как они должны вращаться ?

З.Ы.
g_pd3dDevice._Release; и вообще _Release вызывать не надо.


 
Мистер Т   (2007-04-19 07:59) [3]

Пара примеров:
//-----------------------------------------------------------------------------
//           Name: dx9_vertex_data.dpr
//         Author: Kevin Harris (kevin@codesampler.com)
//     Translator: Egor Konovalov
//  Last Modified: 28.08.2005
//    Description: This sample demonstrates how to create 3D geometry with
//                 Direct3D by loading vertex data into a Vertex Buffer.
//-----------------------------------------------------------------------------

program dx9_vertex_data;

{$R *.res}

{$IFDEF FPC}
 {$MODE DELPHI}
 {$APPTYPE GUI}
{$ENDIF}

// {$DEFINE RELEASED}

uses
 Windows,
 Messages,
 MMSystem,
 Direct3D9,
 D3DX9;

//-----------------------------------------------------------------------------
// GLOBALS
//-----------------------------------------------------------------------------
type
 TVertex = record
   x,  y,  z : Single;
   tu, tv    : Single
 end;

const
 FVF_Flags = D3DFVF_XYZ or D3DFVF_TEX1;

var
 g_hWnd                : THandle                 = 0;
 g_pD3D                : IDirect3D9              = nil;
 g_pd3dDevice          : IDirect3DDevice9        = nil;
 g_pVertexBuffer       : IDirect3DVertexBuffer9  = nil;
 g_pTexture            : IDirect3DTexture9       = nil;

 g_fElapsedTime        : Single                  = 0;
 g_dCurrentTime        : Double                  = 0;
 g_dLastTime           : Double                  = 0;

 g_fXrot               : Single                  = 0.0;
 g_fYrot               : Single                  = 0.0;
 g_fZrot               : Single                  = 0.0;

 winClass              : WNDCLASSEX;
 uMsg                  : MSG;

 g_cubeVertices        : array[0..23] of TVertex =
 ((x:-1.0; y: 1.0; z:-1.0; tu: 0.0; tv: 0.0),
  (x: 1.0; y: 1.0; z:-1.0; tu: 1.0; tv: 0.0),
  (x:-1.0; y:-1.0; z:-1.0; tu: 0.0; tv: 1.0),
  (x: 1.0; y:-1.0; z:-1.0; tu: 1.0; tv: 1.0),

  (x:-1.0; y: 1.0; z: 1.0; tu: 1.0; tv: 0.0),
  (x:-1.0; y:-1.0; z: 1.0; tu: 1.0; tv: 1.0),
  (x: 1.0; y: 1.0; z: 1.0; tu: 0.0; tv: 0.0),
  (x: 1.0; y:-1.0; z: 1.0; tu: 0.0; tv: 1.0),

  (x:-1.0; y: 1.0; z: 1.0; tu: 0.0; tv: 0.0),
  (x: 1.0; y: 1.0; z: 1.0; tu: 1.0; tv: 0.0),
  (x:-1.0; y: 1.0; z:-1.0; tu: 0.0; tv: 1.0),
  (x: 1.0; y: 1.0; z:-1.0; tu: 1.0; tv: 1.0),

  (x:-1.0; y:-1.0; z: 1.0; tu: 0.0; tv: 0.0),
  (x:-1.0; y:-1.0; z:-1.0; tu: 1.0; tv: 0.0),
  (x: 1.0; y:-1.0; z: 1.0; tu: 0.0; tv: 1.0),
  (x: 1.0; y:-1.0; z:-1.0; tu: 1.0; tv: 1.0),

  (x: 1.0; y: 1.0; z:-1.0; tu: 0.0; tv: 0.0),
  (x: 1.0; y: 1.0; z: 1.0; tu: 1.0; tv: 0.0),
  (x: 1.0; y:-1.0; z:-1.0; tu: 0.0; tv: 1.0),
  (x: 1.0; y:-1.0; z: 1.0; tu: 1.0; tv: 1.0),

  (x:-1.0; y: 1.0; z:-1.0; tu: 1.0; tv: 0.0),
  (x:-1.0; y:-1.0; z:-1.0; tu: 1.0; tv: 1.0),
  (x:-1.0; y: 1.0; z: 1.0; tu: 0.0; tv: 0.0),
  (x:-1.0; y:-1.0; z: 1.0; tu: 0.0; tv: 1.0));

//-----------------------------------------------------------------------------
// Name: WindowProc()
// Desc: The window"s message handler
//-----------------------------------------------------------------------------  
function WindowProc(ihwnd: THandle; uMsg: Longword; wParam: Longint; lParam: Longint): Longint; stdcall;
begin
 WindowProc := 0;
 case uMsg of
   WM_KEYDOWN:     begin
                     if wParam = VK_ESCAPE then PostQuitMessage(0);
                   end;
   WM_CLOSE:       PostQuitMessage(0);
   WM_DESTROY:     PostQuitMessage(0);
   else WindowProc := DefWindowProc(ihwnd, uMsg, wParam, lParam);
   end;
end;

//-----------------------------------------------------------------------------
// Name: LoadTexture()
// Desc:
//-----------------------------------------------------------------------------
procedure LoadTexture;
begin
 g_pTexture := nil;

 D3DXCreateTextureFromFile(g_pd3dDevice, "test.bmp", g_pTexture);

 g_pd3dDevice.SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
 g_pd3dDevice.SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
end;

//-----------------------------------------------------------------------------
// Name: Init()
// Desc:
//-----------------------------------------------------------------------------
procedure Init;
var
 d3ddm     : TD3DDisplayMode;
 d3dpp     : TD3DPresentParameters;
 matProj   : TD3DMatrix;
 pVertices : Pointer;
begin
 g_pD3D := Direct3DCreate9(D3D_SDK_VERSION);

 g_pD3D.GetAdapterDisplayMode(D3DADAPTER_DEFAULT,
                              d3ddm);

 ZeroMemory(@d3dpp, SizeOf(TD3DPresentParameters));

 with d3dpp do
   begin
     Windowed                := True;
     SwapEffect              := D3DSWAPEFFECT_DISCARD;
     BackBufferFormat        := d3ddm.Format;
     EnableAutoDepthStencil  := True;
     AutoDepthStencilFormat  := D3DFMT_D16;
     PresentationInterval    := D3DPRESENT_INTERVAL_IMMEDIATE;
   end;

 g_pD3D.CreateDevice(D3DADAPTER_DEFAULT,
                     D3DDEVTYPE_HAL,
                     g_hWnd,
                     D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                     @d3dpp,
                     g_pd3dDevice);

 LoadTexture;

 g_pd3dDevice.CreateVertexBuffer(24 * SizeOf(TVertex),
                                 0,
                                 FVF_Flags,
                                 D3DPOOL_DEFAULT,
                                 g_pVertexBuffer,
                                 nil);

 pVertices := nil;

 g_pVertexBuffer.Lock(0, SizeOf(g_cubeVertices), pVertices, 0);
   Move(g_cubeVertices, pVertices^, SizeOf(g_cubeVertices));
 g_pVertexBuffer.Unlock;

 g_pd3dDevice.SetRenderState(D3DRS_LIGHTING, iFalse);
 g_pd3dDevice.SetRenderState(D3DRS_ZENABLE, iTrue);

 D3DXMatrixPerspectiveFovLH(matProj,
                            D3DXToRadian(45.0),
                            (640 / 480),
                            0.1,
                            100.0);

 g_pd3dDevice.SetTransform(D3DTS_PROJECTION, matProj);
end;

//-----------------------------------------------------------------------------
// Name: ShutDown()
// Desc:
//-----------------------------------------------------------------------------
procedure ShutDown;
begin
 if Assigned(g_pTexture) then
   begin
     {$IFDEF RELEASED}
     g_pTexture._Release;
     {$ENDIF}
     g_pTexture := nil;
   end;

 if Assigned(g_pVertexBuffer) then
   begin
     {$IFDEF RELEASED}
     g_pVertexBuffer._Release;
     {$ENDIF}
     g_pVertexBuffer := nil;
   end;

 if Assigned(g_pd3dDevice) then
   begin
     {$IFDEF RELEASED}
     g_pd3dDevice._Release;
     {$ENDIF}
     g_pd3dDevice := nil;
   end;

 if Assigned(g_pD3D) then
   begin
     {$IFDEF RELEASED}
     g_pD3D._Release;
     {$ENDIF}
     g_pD3D := nil;
   end;
   
end;


 
Мистер Т   (2007-04-19 08:00) [4]

продолжение кода...


//-----------------------------------------------------------------------------
// Name: Render()
// Desc:
//-----------------------------------------------------------------------------
procedure Render;
var
 matWorld  : TD3DMatrix;
 matTrans  : TD3DMatrix;
 matRot    : TD3DMatrix;
begin
 if g_pd3dDevice = nil then Exit;

 g_pd3dDevice.Clear(0,
                    nil,
                    D3DCLEAR_TARGET or D3DCLEAR_ZBUFFER,
                    D3DCOLOR_COLORVALUE(0.0, 0.0, 0.0, 1.0),
                    1.0,
                    0);

 g_fXrot := g_fXrot + (10.1 * g_fElapsedTime);
 g_fYrot := g_fYrot + (10.2 * g_fElapsedTime);
 g_fZrot := g_fZrot + (10.3 * g_fElapsedTime);

 D3DXMatrixTranslation(matTrans, 0.0, 0.0, 5.0);
 D3DXMatrixRotationYawPitchRoll(matRot,
                                D3DXToRadian(g_fXrot),
                                D3DXToRadian(g_fYrot),
                                D3DXToRadian(g_fZrot));
 D3DXMatrixMultiply(matWorld, matRot, matTrans);

 g_pd3dDevice.SetTransform(D3DTS_WORLD, matWorld);

 g_pd3dDevice.BeginScene;

   g_pd3dDevice.SetTexture(0, g_pTexture);
   g_pd3dDevice.SetStreamSource(0, g_pVertexBuffer, 0, SizeOf(TVertex));
   g_pd3dDevice.SetFVF(FVF_Flags);

  g_pd3dDevice.DrawPrimitive(D3DPT_TRIANGLESTRIP,  0, 2 );
  g_pd3dDevice.DrawPrimitive(D3DPT_TRIANGLESTRIP,  4, 2 );
  g_pd3dDevice.DrawPrimitive(D3DPT_TRIANGLESTRIP,  8, 2 );
  g_pd3dDevice.DrawPrimitive(D3DPT_TRIANGLESTRIP, 12, 2 );
  g_pd3dDevice.DrawPrimitive(D3DPT_TRIANGLESTRIP, 16, 2 );
  g_pd3dDevice.DrawPrimitive(D3DPT_TRIANGLESTRIP, 20, 2 );

 g_pd3dDevice.EndScene;

 g_pd3dDevice.Present(nil, nil, 0, nil);
end;

//-----------------------------------------------------------------------------
// Name:
// Desc: The application"s entry point
//-----------------------------------------------------------------------------
begin
 ZeroMemory(@uMsg, SizeOf(MSG));
 ZeroMemory(@winClass, SizeOf(WNDCLASSEX));

 with winClass do
   begin
     lpszClassName := "MY_WINDOWS_CLASS";
     cbSize        := SizeOf(WNDCLASSEX);
     style         := CS_HREDRAW or CS_VREDRAW;
     lpfnWndProc   := @WindowProc;
     hInstance     := hInstance;
     hIcon         := LoadIcon(hInstance, IDI_APPLICATION);
     hIconSm       := LoadIcon(hInstance, IDI_APPLICATION);
     hCursor       := LoadCursor(0, IDC_ARROW);
     hbrBackground := $000000;
     lpszMenuName  := nil;
     cbClsExtra    := 0;
     cbWndExtra    := 0;
   end;

 if (RegisterClassEx(winClass) = 0) then
   Halt(0);

 g_hWnd := CreateWindowEx(0,
                            winClass.lpszClassName,
                            "Direct3D (DX9) - Vertex Data",
                            WS_OVERLAPPEDWINDOW or WS_VISIBLE,
                            0,
                            0,
                            640,
                            480,
                            0,
                            0,
                            winClass.hInstance,
                            nil);

 if g_hWnd = 0 then
   Halt(0);

 ShowWindow(g_hWnd, SW_SHOW);
 UpdateWindow(g_hWnd);

 Init;

 while (uMsg.message <> WM_QUIT) do
   begin
     if PeekMessage(uMsg, 0, 0, 0, PM_REMOVE) then
       begin
         TranslateMessage(uMsg);
         DispatchMessage(uMsg);
       end
     else
       begin
         g_dCurrentTime := timeGetTime;
         g_fElapsedTime := ((g_dCurrentTime - g_dLastTime) * 0.001);
         g_dLastTime := g_dCurrentTime;

         Render;
       end;
   end;

 ShutDown;

 UnregisterClass(winClass.lpszClassName, winClass.hInstance);
end.


 
Мистер Т   (2007-04-19 08:04) [5]

Второй пример:
//---
//           Name: dx9_transforms.dpr
//         Author: Kevin Harris (kevin@codesampler.com)
//     Translator: Egor Konovalov (tujh@ru66.ru)
//  Last Modified: 30.08.2005
//    Description: Demonstrates how to use translation, rotation, and scaling
//                 matrices to create a simulated solar system.
//
//   Control Keys: F1    - Speed up rotations
//                 F2    - Slow down rotations
//                 Space - Toggle orbiting on/off
//---

program dx9_transforms;

{$R *.res}

{$IFDEF FPC}
 {$MODE DELPHI}
 {$APPTYPE GUI}
{$ENDIF}

// {$DEFINE RELEASED}

uses
 Windows,
 Messages,
 MMSystem,
 Direct3D9,
 D3DX9;

//---
// GLOBALS
//---
type
 TVertex = record
   x, y, z : Single;
   diffuse : Longword;
 end;

const
 D3DFVF_MY_VERTEX = D3DFVF_XYZ or D3DFVF_DIFFUSE;

var
 g_hWnd                  : THandle                 = 0;
 g_pD3D                  : IDirect3D9              = nil;
 g_pd3dDevice            : IDirect3DDevice9        = nil;
 g_pSunMesh              : ID3DXMesh               = nil;
 g_pEarthMesh            : ID3DXMesh               = nil;
 g_pMoonMesh             : ID3DXMesh               = nil;
 g_matrixStack           : ID3DXMatrixStack        = nil;

 g_fElpasedTime          : Single;
 g_dCurrentTime          : Longword;
 g_dLastTime             : Longword;

 g_fSpeedmodifier        : Single                  = 1.0;
 g_bOrbitOn              : Boolean                 = True;

 g_fSunSpin              : Single                  = 0.0;
 g_fEarthSpin            : Single                  = 0.0;
 g_fEarthOrbit           : Single                  = 0.0;
 g_fMoonSpin             : Single                  = 0.0;
 g_fMoonOrbit            : Single                  = 0.0;

 winClass              : WNDCLASSEX;
 uMsg                  : MSG;

//---
// Name: WindowProc()
// Desc: The window"s message handler
//---
function WindowProc(ihwnd: THandle; uMsg: Longword; wParam: Longint; lParam: Longint): Longint; stdcall;
begin
 WindowProc := 0;
 case uMsg of
   WM_KEYDOWN:     begin
                     case wParam of
                       VK_ESCAPE   : PostQuitMessage(0);
                       VK_F1       : g_fSpeedmodifier := g_fSpeedmodifier + 1.0;
                       VK_F2       : g_fSpeedmodifier := g_fSpeedmodifier - 1.0;
                       VK_SPACE    : g_bOrbitOn := not(g_bOrbitOn);
                     end;
                   end;
   WM_CLOSE:       PostQuitMessage(0);
   WM_DESTROY:     PostQuitMessage(0);
   else WindowProc := DefWindowProc(ihwnd, uMsg, wParam, lParam);
   end;
end;

//---
// Name: Init()
// Desc:
//---
procedure Init;
var
 d3ddm             : TD3DDisplayMode;
 d3dpp             : TD3DPresentParameters;
 matProj           : TD3DMatrix;
 pTempEarthMesh    : ID3DXMesh;
 pTempSunMesh      : ID3DXMesh;
 pTempVertexBuffer : IDirect3DVertexBuffer9;
 nNumVerts         : Longword;
 i                 : Longword;
 pVertex           : Pointer;
 Vertex            : array of TVertex;
begin
 g_pD3D := Direct3DCreate9(D3D_SDK_VERSION);

 g_pD3D.GetAdapterDisplayMode(D3DADAPTER_DEFAULT,
                              d3ddm);

 ZeroMemory(@d3dpp, SizeOf(TD3DPresentParameters));

 with d3dpp do
   begin
     Windowed                := True;
     SwapEffect              := D3DSWAPEFFECT_DISCARD;
     BackBufferFormat        := d3ddm.Format;
     EnableAutoDepthStencil  := True;
     AutoDepthStencilFormat  := D3DFMT_D16;
     PresentationInterval    := D3DPRESENT_INTERVAL_IMMEDIATE;
   end;

 g_pD3D.CreateDevice(D3DADAPTER_DEFAULT,
                     D3DDEVTYPE_HAL,
                     g_hWnd,
                     D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                     @d3dpp,
                     g_pd3dDevice);

 g_pd3dDevice.SetRenderState(D3DRS_LIGHTING, iFalse);
 g_pd3dDevice.SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
 g_pd3dDevice.SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);

 D3DXMatrixPerspectiveFovLH(matProj,
                            D3DXToRadian(45.0),
                            (640 / 480),
                            0.1,
                            100.0);

 g_pd3dDevice.SetTransform(D3DTS_PROJECTION, matProj);

 // We"ll use the D3DXCreateSphere utility function to create three simple
 // sphere meshes to experiment with.

 D3DXCreateSphere(g_pd3dDevice, 1.0, 20, 20, pTempSunMesh,   nil);
 D3DXCreateSphere(g_pd3dDevice, 1.0, 10, 10, pTempEarthMesh, nil);
 D3DXCreateSphere(g_pd3dDevice, 0.5, 8,   8, g_pMoonMesh,    nil);

 // Unfortunately, the D3DXCreateSphere utility function creates a mesh
 // with no color, so we"ll need to make a clone of the original meshes
 // using a FVF code that does include color so we can set up the Earth
 // and Sun with color.
 //
 // Once that"s been done, we"ll need to set the color values to something
 // appropriate for our solar system model.

 // Clone the original Earth mesh and make it blue...

 pTempVertexBuffer := nil;

 pTempEarthMesh.CloneMeshFVF(0, D3DFVF_MY_VERTEX, g_pd3dDevice, g_pEarthMesh);

 if Succeeded(g_pEarthMesh.GetVertexBuffer(pTempVertexBuffer)) then
   begin
     nNumVerts := g_pEarthMesh.GetNumVertices;
     pVertex := nil;
     SetLength(Vertex, nNumVerts);
     pTempVertexBuffer.Lock(0, 0, pVertex, 0);
       Move(pVertex^, Vertex[0], nNumVerts * SizeOf(TVertex));

       for i := 0 to (nNumVerts - 1) do
         Vertex[i].diffuse := D3DCOLOR_COLORVALUE(0.0, 0.0, 1.0, 1.0);

       Move(Vertex[0], pVertex^, nNumVerts * SizeOf(TVertex));
     pTempVertexBuffer.Unlock;

     {$IFDEF RELEASED}
     pTempVertexBuffer._Release
     {$ENDIF}
     pTempVertexBuffer := nil;

     SetLength(Vertex, 0);
   end;

 // Clone the original Sun mesh and make it yellow...

 pTempSunMesh.CloneMeshFVF(0, D3DFVF_MY_VERTEX, g_pd3dDevice, g_pSunMesh);
 if Succeeded(g_pSunMesh.GetVertexBuffer(pTempVertexBuffer)) then
   begin
     nNumVerts := g_pSunMesh.GetNumVertices;
     pVertex := nil;
     SetLength(Vertex, nNumVerts);
     pTempVertexBuffer.Lock(0, 0, pVertex, 0);
       Move(pVertex^, Vertex[0], nNumVerts * SizeOf(TVertex));

       for i := 0 to (nNumVerts - 1) do
         Vertex[i].diffuse := D3DCOLOR_COLORVALUE(1.0, 1.0, 0.0, 1.0);

       Move(Vertex[0], pVertex^, nNumVerts * SizeOf(TVertex));
     pTempVertexBuffer.Unlock;

     {$IFDEF RELEASED}
     pTempVertexBuffer._Release
     {$ENDIF}
     pTempVertexBuffer := nil;

   end;

 {$IFDEF RELEASED}
 pTempEarthMesh._Release;
 {$ENDIF}
 pTempEarthMesh := nil;
 {$IFDEF RELEASED}
 pTempSunMesh._Release;
 {$ENDIF}
 pTempSunMesh := nil;

 D3DXCreateMatrixStack(0, g_matrixStack);

end;


 
Мистер Т   (2007-04-19 08:05) [6]

Продолжение кода:
//-----------------------------------------------------------------------------
// Name: ShutDown()
// Desc:
//-----------------------------------------------------------------------------
procedure ShutDown;
begin
 if Assigned(g_matrixStack) then
   begin
     {$IFDEF RELEASED}
     g_matrixStack._Release;
     {$ENDIF}
     g_matrixStack := nil;
   end;

 if Assigned(g_pSunMesh) then
   begin
     {$IFDEF RELEASED}
     g_pSunMesh._Release;
     {$ENDIF}
     g_pSunMesh := nil;
   end;

 if Assigned(g_pEarthMesh) then
   begin
     {$IFDEF RELEASED}
     g_pEarthMesh._Release;
     {$ENDIF}
     g_pEarthMesh := nil;
   end;

 if Assigned(g_pMoonMesh) then
   begin
     {$IFDEF RELEASED}
     g_pMoonMesh._Release;
     {$ENDIF}
     g_pMoonMesh := nil;
   end;

 if Assigned(g_pd3dDevice) then
   begin
     {$IFDEF RELEASED}
     g_pd3dDevice._Release;
     {$ENDIF}
     g_pd3dDevice := nil;
   end;

 if Assigned(g_pD3D) then
   begin
     {$IFDEF RELEASED}
     g_pD3D._Release;
     {$ENDIF}
     g_pD3D := nil;
   end;
   
end;

//-----------------------------------------------------------------------------
// Name: Render()
// Desc:
//-----------------------------------------------------------------------------
procedure Render;
var
 matView                   : TD3DMatrix;

 mSunScale                 : TD3DMatrix;
 mSunSpinRotation          : TD3DMatrix;
 mSunMatrix                : TD3DMatrix;

 mEarthTranslationToOrbit  : TD3DMatrix;
 mEarthSpinRotation        : TD3DMatrix;
 mEarthOrbitRotation       : TD3DMatrix;
 mEarthMatrix              : TD3DMatrix;

 mMoonTranslationToOrbit   : TD3DMatrix;
 mMoonSpinRotation         : TD3DMatrix;
 mMoonOrbitRotation        : TD3DMatrix;
 mMoonMatrix               : TD3DMatrix;
begin
 if g_pd3dDevice = nil then Exit;

 g_pd3dDevice.Clear(0,
                    nil,
                    D3DCLEAR_TARGET or D3DCLEAR_ZBUFFER,
                    D3DCOLOR_COLORVALUE(0.0, 0.0, 0.0, 1.0),
                    1.0,
                    0);

 g_pd3dDevice.BeginScene;

   //
   // Have the view matrix move the view move us to a good vantage point so
   // we can see the Sun sitting at the origin while the Earth orbits it.
   //

   D3DXMatrixLookAtLH(matView,
                      D3DXVector3(0.0, 2.0, -25.0),  // Camera position
                      D3DXVector3(0.0, 0.0,   0.0),  // Look-at point
                      D3DXVector3(0.0, 1.0,   0.0)); // Up vector

   g_pd3dDevice.SetTransform(D3DTS_VIEW, matView);

   //
   // Cache rotational positions between frames...
   //

   if g_bOrbitOn then
     begin
       g_fSunSpin    := g_fSunSpin     + (g_fSpeedmodifier * (g_fElpasedTime * 10.0));

       g_fEarthSpin  := g_fEarthSpin   + (g_fSpeedmodifier * (g_fElpasedTime * 100.0));
       g_fEarthOrbit := g_fEarthOrbit  + (g_fSpeedmodifier * (g_fElpasedTime * 20.0));

       g_fMoonSpin   := g_fMoonSpin    + (g_fSpeedmodifier * (g_fElpasedTime * 50.0));
       g_fMoonOrbit  := g_fMoonOrbit   + (g_fSpeedmodifier * (g_fElpasedTime * 200.0));
     end;

   //
   // The Sun is easy because the mesh for it is initially created centered
   // at origin. All we have to do is spin it by rotating it about the Y axis
   // and scale it by 5.0f.
   //

   D3DXMatrixRotationY(mSunSpinRotation, D3DXToRadian(g_fSunSpin));
   D3DXMatrixScaling(mSunScale, 5.0, 5.0, 5.0);

   //
   // Now, concatenate them together...
   // 1. Uniformly scale the Sun up in size
   // 2. and then spin it on its axis.
   //

   D3DXMatrixMultiply(mSunMatrix, mSunScale, mSunSpinRotation);

   g_pd3dDevice.SetTransform(D3DTS_WORLD, mSunMatrix);
   g_pSunMesh.DrawSubset(0);

   //
   // The Earth is a little more complicated since it needs to spin as well
   // as orbit the Sun. This can be done by combining three transformations
   // together.
   //

   D3DXMatrixRotationY(mEarthSpinRotation, D3DXToRadian(g_fEarthSpin));
   D3DXMatrixTranslation(mEarthTranslationToOrbit, 0.0, 0.0, 12.0);
   D3DXMatrixRotationY(mEarthOrbitRotation, D3DXToRadian(g_fEarthOrbit));

   //
   // Now, concatenate them together...
   // 1. Spin the Earth on its own axis.
   // 2. Then translate it away from the origin (where the Sun"s at)
   // 3. and rotate it again to make it orbit the origin (or the Sun).
   //

   D3DXMatrixMultiply(mEarthMatrix, mEarthSpinRotation, mEarthTranslationToOrbit);
   D3DXMatrixMultiply(mEarthMatrix, mEarthMatrix,       mEarthOrbitRotation);

   g_pd3dDevice.SetTransform(D3DTS_WORLD, mEarthMatrix);
   g_pEarthMesh.DrawSubset(0);

   //
   // The Moon is the hardest to understand since it needs to not only spin on
   // its own axis and orbit the Earth, but needs to follow the Earth,
   // which is orbiting the Sun.
   //
   // This can be done by combining five transformations together with the last
   // two being borrowed from the Earth"s transformation.
   //

   D3DXMatrixRotationY(mMoonSpinRotation, D3DXToRadian(g_fMoonSpin));
   D3DXMatrixRotationY(mMoonOrbitRotation, D3DXToRadian(g_fMoonOrbit));
   D3DXMatrixTranslation(mMoonTranslationToOrbit, 0.0, 0.0, 2.0);

   //
   // The key to understanding the first three transforms is to pretend that
   // the Earth is located at the origin. We know it"s not, but if we pretend
   // that it is, we can set up the Moon just like the we did the Earth since
   // the Moon orbits the Earth just like the Earth orbits the Sun.
   //
   // Once the Moon"s transforms are set up we simply reuse the Earth"s
   // translation and rotation matrix, which placed it in orbit, to offset
   // the Moon out to where it should be... following the Earth.
   //

   //
   // Now, concatenate them together...
   // 1. Spin the Moon on its own axis.
   // 2. Then translate it away from the origin (pretending that the Earth is there)
   // 3. and rotate it again to make it orbit the origin (or the pretend Earth).
   // 4. Now, translate out to where the Earth is really at
   // 5. and move with it by matching its orbit of the Earth.
   //

   D3DXMatrixMultiply(mMoonMatrix, mMoonSpinRotation, mMoonTranslationToOrbit);
   D3DXMatrixMultiply(mMoonMatrix, mMoonMatrix, mMoonOrbitRotation);
   D3DXMatrixMultiply(mMoonMatrix, mMoonMatrix, mEarthTranslationToOrbit);
   D3DXMatrixMultiply(mMoonMatrix, mMoonMatrix, mEarthOrbitRotation);

   g_pd3dDevice.SetTransform(D3DTS_WORLD, mMoonMatrix);
   g_pMoonMesh.DrawSubset(0);

 g_pd3dDevice.EndScene;

 g_pd3dDevice.Present(nil, nil, 0, nil);
end;


 
Мистер Т   (2007-04-19 08:06) [7]

Продолжение, второй вариант процедуры рендера:
(*
//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Render a solar system using the D3DXMATRIX utility class and a matrix
//       stack similar to OpenGL"s. See the note below for details.
//      
// Note:
//
// Direct3D uses the world and view matrices that we set to configure several
// internal data structures. Each time we set a new world or view matrix, the
// system is forced to recalculate these internal structures. Therefore,
// setting these matrices frequently, which is the case for applications that
// require a high frame-rate, is computationally expensive. We can minimize
// the number of required calculations by concatenating our world and view
// matrices into a combined world-view matrix that we set as the world matrix.
//
// With the view matrix combined in with each world matrix that we set, we no
// longer have to set the view matrix separately and incur its overhead.
// Instead, we simply set the view matrix to the identity once and leave it
// untouched during all calculations.
//
// For clarity, Direct3D samples rarely employ this optimization since it
// confuses beginners.
//
//-----------------------------------------------------------------------------
procedure Render;
var
 matView                   : TD3DMatrix;

 mSunScale                 : TD3DMatrix;
 mSunSpinRotation          : TD3DMatrix;
 mSunMatrix                : TD3DMatrix;

 mEarthTranslationToOrbit  : TD3DMatrix;
 mEarthSpinRotation        : TD3DMatrix;
 mEarthOrbitRotation       : TD3DMatrix;
 mEarthMatrix              : TD3DMatrix;

 mMoonTranslationToOrbit   : TD3DMatrix;
 mMoonSpinRotation         : TD3DMatrix;
 mMoonOrbitRotation        : TD3DMatrix;
 mMoonMatrix               : TD3DMatrix;
begin
 if g_pd3dDevice = nil then Exit;

 g_pd3dDevice.Clear(0,
                    nil,
                    D3DCLEAR_TARGET or D3DCLEAR_ZBUFFER,
                    D3DCOLOR_COLORVALUE(0.0, 0.0, 0.0, 1.0),
                    1.0,
                    0);

 g_pd3dDevice.BeginScene;

   //
   // Have the view matrix move the view move us to a good vantage point so
   // we can see the Sun sitting at the origin while the Earth orbits it.
   //

   D3DXMatrixLookAtLH(matView,
                      D3DXVector3(0.0, 2.0, -25.0),  // Camera position
                      D3DXVector3(0.0, 0.0,   0.0),  // Look-at point
                      D3DXVector3(0.0, 1.0,   0.0)); // Up vector

   g_matrixStack.LoadIdentity;
   g_matrixStack.LoadMatrix(matView);

   //
   // Cache rotational positions between frames...
   //

   if g_bOrbitOn then
     begin
       g_fSunSpin    := g_fSunSpin     + (g_fSpeedmodifier * (g_fElpasedTime * 10.0));

       g_fEarthSpin  := g_fEarthSpin   + (g_fSpeedmodifier * (g_fElpasedTime * 100.0));
       g_fEarthOrbit := g_fEarthOrbit  + (g_fSpeedmodifier * (g_fElpasedTime * 20.0));

       g_fMoonSpin   := g_fMoonSpin    + (g_fSpeedmodifier * (g_fElpasedTime * 50.0));
       g_fMoonOrbit  := g_fMoonOrbit   + (g_fSpeedmodifier * (g_fElpasedTime * 200.0));
     end;

   //
   // The Sun is easy because the mesh for it is initially created centered
   // at origin. All we have to do is spin it by rotating it about the Y axis
   // and scale it by 5.0f.
   //

   D3DXMatrixRotationY(mSunSpinRotation, D3DXToRadian(g_fSunSpin));
   D3DXMatrixScaling(mSunScale, 5.0, 5.0, 5.0);

   //
   // Now, concatenate them together...
   // 1. Uniformly scale the Sun up in size
   // 2. and then spin it on its axis.
   //

   D3DXMatrixMultiply(mSunMatrix, mSunScale, mSunSpinRotation);

   g_matrixStack.Push;
     g_matrixStack.MultMatrixLocal(mSunMatrix);
     g_pd3dDevice.SetTransform(D3DTS_WORLD, g_matrixStack.GetTop^);
     g_pSunMesh.DrawSubset(0);
   g_matrixStack.Pop;

   //
   // The Earth is a little more complicated since it needs to spin as well
   // as orbit the Sun. This can be done by combining three transformations
   // together.
   //

   D3DXMatrixRotationY(mEarthSpinRotation, D3DXToRadian(g_fEarthSpin));
   D3DXMatrixTranslation(mEarthTranslationToOrbit, 0.0, 0.0, 12.0);
   D3DXMatrixRotationY(mEarthOrbitRotation, D3DXToRadian(g_fEarthOrbit));

   //
   // Now, concatenate them together...
   // 1. Spin the Earth on its own axis.
   // 2. Then translate it away from the origin (where the Sun"s at)
   // 3. and rotate it again to make it orbit the origin (or the Sun).
   //

   D3DXMatrixMultiply(mEarthMatrix, mEarthSpinRotation, mEarthTranslationToOrbit);
   D3DXMatrixMultiply(mEarthMatrix, mEarthMatrix,       mEarthOrbitRotation);

   g_matrixStack.Push;
     g_matrixStack.MultMatrixLocal(mEarthMatrix);
     g_pd3dDevice.SetTransform(D3DTS_WORLD, g_matrixStack.GetTop^);
     g_pEarthMesh.DrawSubset(0);
   g_matrixStack.Pop;

   //
   // The Moon is the hardest to understand since it needs to not only spin on
   // its own axis and orbit the Earth, but needs to follow the Earth,
   // which is orbiting the Sun.
   //
   // This can be done by combining five transformations together with the last
   // two being borrowed from the Earth"s transformation.
   //

   D3DXMatrixRotationY(mMoonSpinRotation, D3DXToRadian(g_fMoonSpin));
   D3DXMatrixRotationY(mMoonOrbitRotation, D3DXToRadian(g_fMoonOrbit));
   D3DXMatrixTranslation(mMoonTranslationToOrbit, 0.0, 0.0, 2.0);

   //
   // The key to understanding the first three transforms is to pretend that
   // the Earth is located at the origin. We know it"s not, but if we pretend
   // that it is, we can set up the Moon just like the we did the Earth since
   // the Moon orbits the Earth just like the Earth orbits the Sun.
   //
   // Once the Moon"s transforms are set up we simply reuse the Earth"s
   // translation and rotation matrix, which placed it in orbit, to offset
   // the Moon out to where it should be... following the Earth.
   //

   //
   // Now, concatenate them together...
   // 1. Spin the Moon on its own axis.
   // 2. Then translate it away from the origin (pretending that the Earth is there)
   // 3. and rotate it again to make it orbit the origin (or the pretend Earth).
   // 4. Now, translate out to where the Earth is really at
   // 5. and move with it by matching its orbit of the Earth.
   //

   D3DXMatrixMultiply(mMoonMatrix, mMoonSpinRotation, mMoonTranslationToOrbit);
   D3DXMatrixMultiply(mMoonMatrix, mMoonMatrix, mMoonOrbitRotation);
   D3DXMatrixMultiply(mMoonMatrix, mMoonMatrix, mEarthTranslationToOrbit);
   D3DXMatrixMultiply(mMoonMatrix, mMoonMatrix, mEarthOrbitRotation);

   g_matrixStack.Push;
     g_matrixStack.MultMatrixLocal(mMoonMatrix);
     g_pd3dDevice.SetTransform(D3DTS_WORLD, g_matrixStack.GetTop^);
     g_pMoonMesh.DrawSubset(0);
   g_matrixStack.Pop;

 g_pd3dDevice.EndScene;

 g_pd3dDevice.Present(nil, nil, 0, nil);

end;
*)


 
Мистер Т   (2007-04-19 08:07) [8]

Завершение второго примера:
//-----------------------------------------------------------------------------
// Name:
// Desc: The application"s entry point
//-----------------------------------------------------------------------------
begin
 ZeroMemory(@uMsg, SizeOf(MSG));
 ZeroMemory(@winClass, SizeOf(WNDCLASSEX));

 with winClass do
   begin
     lpszClassName := "MY_WINDOWS_CLASS";
     cbSize        := SizeOf(WNDCLASSEX);
     style         := CS_HREDRAW or CS_VREDRAW;
     lpfnWndProc   := @WindowProc;
     hInstance     := hInstance;
     hIcon         := LoadIcon(hInstance, IDI_APPLICATION);
     hIconSm       := LoadIcon(hInstance, IDI_APPLICATION);
     hCursor       := LoadCursor(0, IDC_ARROW);
     hbrBackground := $000000;
     lpszMenuName  := nil;
     cbClsExtra    := 0;
     cbWndExtra    := 0;
   end;

 if (RegisterClassEx(winClass) = 0) then
   Halt(0);

 g_hWnd := CreateWindowEx(0,
                            winClass.lpszClassName,
                            "Direct3D (DX9) - Transforms",
                            WS_OVERLAPPEDWINDOW or WS_VISIBLE,
                            0,
                            0,
                            640,
                            480,
                            0,
                            0,
                            winClass.hInstance,
                            nil);

 if g_hWnd = 0 then
   Halt(0);

 ShowWindow(g_hWnd, SW_SHOW);
 UpdateWindow(g_hWnd);

 Init;

 g_dLastTime := timeGetTime;

 while (uMsg.message <> WM_QUIT) do
   begin
     if PeekMessage(uMsg, 0, 0, 0, PM_REMOVE) then
       begin
         TranslateMessage(uMsg);
         DispatchMessage(uMsg);
       end
     else
       begin
         g_dCurrentTime := timeGetTime;
         g_fElpasedTime := ((g_dCurrentTime - g_dLastTime) * 0.001);
         g_dLastTime    := g_dCurrentTime;

         Render;
       end;
   end;

 ShutDown;

 UnregisterClass(winClass.lpszClassName, winClass.hInstance);
end.


 
Piroxyline ©   (2007-04-21 17:53) [9]

Должны были вращаться так, чтобы первый (который вначале ближе к нам) перекрывался потом вторым. Решение оказалось простым, когда я посмотрел другие примеры и сравнил с этим кодом: надо было Z-буффер поставить :) Так привый к OpenGL"ю, в котором это делается не задумываясь, что забыл совсем



Страницы: 1 вся ветка

Форум: "Игры";
Текущий архив: 2009.01.11;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.6 MB
Время: 0.006 c
2-1227856798
Андрей Алекс.
2008-11-28 10:19
2009.01.11
Сохдать Pages в PageControl


2-1227880896
olegIvan
2008-11-28 17:01
2009.01.11
TreeView


4-1203014467
AlexeyShestchenko
2008-02-14 21:41
2009.01.11
порядок нахождения


15-1226403445
Kolan
2008-11-11 14:37
2009.01.11
Управление сбрками.


1-1205742601
Thrasher
2008-03-17 11:30
2009.01.11
Word и Delphi





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский