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

Вниз

Пример из туториала по 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;
Скачать: CL | DM;

Наверх




Память: 0.6 MB
Время: 0.013 c
1-1205380631
snake-as
2008-03-13 06:57
2009.01.11
Посылка письма


15-1226294001
Design
2008-11-10 08:13
2009.01.11
Как определить работает ХРManifest или нет?


15-1226564342
Нов_и_чок
2008-11-13 11:19
2009.01.11
Справочник Win32 для XP


11-1196621606
Byka (345-824-826)
2007-12-02 21:53
2009.01.11
не получается закрыть форму с 1го раза ???


15-1226772749
leonidus
2008-11-15 21:12
2009.01.11
Что за кодировку использует www.multitran.ru ?