Форум: "Игры";
Текущий архив: 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