游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2220|回复: 1

??????*?X?????????????????(D9)

[复制链接]

1

主题

2

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2004-4-27 13:59:00 | 显示全部楼层 |阅读模式

program Lightsbb;

uses
  Windows,
  Messages,
  MMSystem,
  Direct3D9,SysUtils,
  D3DX9;

type
  PD3DMaterial9Array = ^TD3DMaterial9Array;
  TD3DMaterial9Array = array[0..0] of TD3DMaterial9;

  PIDirect3DTexture9Array = ^IDirect3DTexture9Array;
  IDirect3DTexture9Array = array[0..0] of IDirect3DTexture9;
//-----------------------------------------------------------------------------
// Global variables
//-----------------------------------------------------------------------------
var
  g_pD3D: IDirect3D9 = nil; // Used to create the D3DDevice
  g_pd3dDevice: IDirect3DDevice9 = nil; // Our rendering device
  g_pVB: IDirect3DVertexBuffer9 = nil; // Buffer to hold vertices
  g_pTexture:    IDirect3DTexture9       = nil; // Our texture
// A structure for our custom vertex type. We added a normal, and omitted the
// color (which is provided by the material)

  g_pMesh:          ID3DXMesh               = nil; // Our mesh object in sysmem
  g_pMeshMaterials: PD3DMaterial9Array      = nil; // Materials for our mesh
  g_pMeshTextures:  PIDirect3DTexture9Array = nil; // Textures for our mesh
  g_dwNumMaterials: DWORD                   = 0;   // Number of mesh materials


type
  PCustomVertex = ^TCustomVertex;
TCustomVertex = packed record
    position: TD3DXVector3; // The position
    normal: TD3DVector;
    color:    TD3DColor;    // The color
{$IFNDEF SHOW_HOW_TO_USE_TCI}
    tu, tv:       Single;   // The texture coordinates
{$ENDIF}
  end;
  PCustomVertexArray = ^TCustomVertexArray;
  TCustomVertexArray = array [0..0] of TCustomVertex;

const
  // Our custom FVF, which describes our custom vertex structure
{$IFDEF SHOW_HOW_TO_USE_TCI}
  D3DFVF_CUSTOMVERTEX = D3DFVF_XYZ or D3DFVF_DIFFUSE or D3DFVF_NORMAL;
  {$ELSE}
  D3DFVF_CUSTOMVERTEX = D3DFVF_XYZ or D3DFVF_NORMAL or D3DFVF_TEX1 or D3DFVF_DIFFUSE ;
  {$ENDIF}


function InitD3D(hWnd: HWND): HRESULT;
var
  d3dpp: TD3DPresentParameters;
begin
  Result:= E_FAIL;

  // Create the D3D object.
  g_pD3D := Direct3DCreate9(D3D_SDK_VERSION);
  if (g_pD3D = nil) then Exit;

  // Set up the structure used to create the D3DDevice. Since we are now
  // using more complex geometry, we will create a device with a zbuffer.
  FillChar(d3dpp, SizeOf(d3dpp), 0);
  d3dpp.Windowed := True;
  d3dpp.SwapEffect := D3DSWAPEFFECT_DISCARD;
  d3dpp.BackBufferFormat := D3DFMT_UNKNOWN;
  d3dpp.EnableAutoDepthStencil := True;
  d3dpp.AutoDepthStencilFormat := D3DFMT_D16;

  // Create the D3DDevice
  Result:= g_pD3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                               D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                               @d3dpp, g_pd3dDevice);
  if FAILED(Result) then
  begin
    Result:= E_FAIL;
    Exit;
  end;

  // Turn off culling
  g_pd3dDevice.SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

  // Turn on the zbuffer
  g_pd3dDevice.SetRenderState(D3DRS_ZENABLE, iTrue);

  g_pd3dDevice.SetRenderState(D3DRS_AMBIENT, $ffffffff);
  Result:= S_OK;
end;


function InitGeometry: HRESULT;
type
  PD3DXMaterialArray = ^TD3DXMaterialArray;
  TD3DXMaterialArray = array[0..0] of TD3DXMaterial;
const
  strPrefix = '..\';
  lenPrefix = Length(strPrefix);
var
  i,r: DWORD;     rr,rr1, y0,y1:real;
  theta,thetb: Single;
  pVertices: PCustomVertexArray;
  pD3DXMtrlBuffer: ID3DXBuffer;
  d3dxMaterials: PD3DXMaterialArray;

  strTexture: array[0..MAX_PATH-1] of Char;
begin
  Result:= E_FAIL;

  // Use D3DX to create a texture from a file based image
  if FAILED(D3DXCreateTextureFromFile(g_pd3dDevice, 'banana.bmp', g_pTexture)) then
  begin
    // If texture is not in current folder, try parent folder
    if FAILED(D3DXCreateTextureFromFile(g_pd3dDevice, '..\banana.bmp', g_pTexture)) then
    begin
      MessageBox(0, 'Could not find banana.bmp', 'Textures.exe', MB_OK);
      Exit;
    end;
  end;

  // Create the vertex buffer.
  if FAILED(g_pd3dDevice.CreateVertexBuffer((2500)*2*SizeOf(TCustomVertex),
                                            0, D3DFVF_CUSTOMVERTEX,
                                            D3DPOOL_DEFAULT, g_pVB, nil))
  then Exit;

  if FAILED(g_pVB.Lock(0, 0, Pointer(pVertices), 0))
  then Exit;
   theta := (D3DX_PI)/(50-1);
   thetb := (2*D3DX_PI)/(50-1);
   for i:=0 to 48 do
  begin
   rr:= 0.2*sin((i+0) * theta );
                 rr1 :=0.2* sin((i+1) * theta);
                 y0 := cos((i+0) * theta );
                 y1 := cos((i+1) * theta );


    for r:=0 to 49 do
    begin

    pVertices[2*(50*i+r)+0].position := D3DXVector3(rr*sin((r)*thetb),y0, rr*cos((r)*thetb));
    pVertices[2*(50*i+r)+0].normal := D3DXVector3(rr*sin((r)*thetb),y0, rr*cos((r)*thetb));

    pVertices[2*(50*i+r)+0].color    := $ff000080;
{$IFNDEF SHOW_HOW_TO_USE_TCI}
    pVertices[2*(50*i+r)+0].tu       :=(r)/50;
    pVertices[2*(50*i+r)+0].tv       := 1-(i)/50;
{$ENDIF}

    pVertices[2*(50*i+r)+1].position := D3DXVector3(rr1*sin((r)*thetb),y1, rr1*cos((r)*thetb));
    pVertices[2*(50*i+r)+1].normal := D3DXVector3(rr1*sin((r)*thetb),y1, rr1*cos((r)*thetb));
    pVertices[2*(50*i+r)+1].color    := $ff000080;
{$IFNDEF SHOW_HOW_TO_USE_TCI}
    pVertices[2*(50*i+r)+1].tu       := ((r)/50);
    pVertices[2*(50*i+r)+1].tv       := 1-((i+1)/50);
{$ENDIF}
    end;
    end;

  g_pVB.Unlock;
   if FAILED(D3DXLoadMeshFromX('Tiger.x', D3DXMESH_SYSTEMMEM,
                              g_pd3dDevice, nil,
                              @pD3DXMtrlBuffer, nil, @g_dwNumMaterials,
                              g_pMesh)) then
  begin
    // If model is not in current folder, try parent folder
    if FAILED(D3DXLoadMeshFromX('..\Tiger.x', D3DXMESH_SYSTEMMEM,
                                g_pd3dDevice, nil,
                                @pD3DXMtrlBuffer, nil, @g_dwNumMaterials,
                                g_pMesh)) then
    begin
      MessageBox(0, 'Could not find tiger.x', 'Meshes.exe', MB_OK);
      Exit;
    end;
  end;

  // We need to extract the material properties and texture names from the
  // pD3DXMtrlBuffer
  d3dxMaterials := pD3DXMtrlBuffer.GetBufferPointer;
  GetMem(g_pMeshMaterials, SizeOf(TD3DMaterial9)*g_dwNumMaterials);
  GetMem(g_pMeshTextures, SizeOf(IDirect3DTexture9)*g_dwNumMaterials);
  ZeroMemory(g_pMeshTextures, SizeOf(IDirect3DTexture9)*g_dwNumMaterials);

  i:= 0;
  while (i < g_dwNumMaterials) do
  begin
    // Copy the material
    g_pMeshMaterials := d3dxMaterials.MatD3D;

    // Set the ambient color for the material (D3DX does not do this)
    g_pMeshMaterials.Ambient := g_pMeshMaterials.Diffuse;

    g_pMeshTextures := nil;
    if (d3dxMaterials.pTextureFilename <> nil) and
       (StrLen(d3dxMaterials.pTextureFilename) > 0) then
    begin
      if FAILED(D3DXCreateTextureFromFile(g_pd3dDevice,
                                          d3dxMaterials.pTextureFilename,
                                          g_pMeshTextures)) then
      begin
        // If texture is not in current folder, try parent folder
        StrLCopy(strTexture, strPrefix, MAX_PATH);
        StrLCopy(strTexture + lenPrefix, d3dxMaterials.pTextureFilename, MAX_PATH - lenPrefix);
        // If texture is not in current folder, try parent folder
        if FAILED(D3DXCreateTextureFromFile(g_pd3dDevice,
                                            strTexture,
                                            g_pMeshTextures)) then
        begin
            MessageBox(0, 'Could not find texture map', 'Meshes.exe', MB_OK);
        end;
      end;
    end;
    Inc(i);
  end;

  // Done with the material buffer
  pD3DXMtrlBuffer:= nil;

  Result:= S_OK;
end;


procedure Cleanup;
var
  i: DWORD;
begin
  if (g_pMeshMaterials <> nil) then
    FreeMem(g_pMeshMaterials);

  if (g_pMeshTextures <> nil)  then
  begin
    i:= 0;
    while(i < g_dwNumMaterials) do
    begin
      if (g_pMeshTextures <> nil) then
        g_pMeshTextures:= nil;

      Inc(i);
    end;
    FreeMem(g_pMeshTextures);
  end;

  if (g_pMesh <> nil) then
    g_pMesh:= nil;

  if (g_pVB <> nil) then
    g_pVB:= nil;

  if (g_pd3dDevice <> nil) then
    g_pd3dDevice:= nil;

  if (g_pD3D <> nil) then
    g_pD3D:= nil;
end;

procedure SetupMatrices;
var
  matWorld, matView, matProj: TD3DMatrix;
  vEyePt, vLookatPt, vUpVec: TD3DVector;
begin


   D3DXMatrixIdentity(matWorld);
   D3DXMatrixRotationAxis(matWorld, D3DXVector3(2.0, 3.0,-1.0), timeGetTime/1000.0);
  D3DXMatrixRotationy(matWorld, timeGetTime/500.0);
  g_pd3dDevice.SetTransform(D3DTS_WORLD, matWorld);

  vEyePt:=    D3DXVector3(0.0, 0.0,-8.0);
  vLookatPt:= D3DXVector3Zero;
  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);
end;

procedure SetupLights;
var
  mtrl: TD3DMaterial9;
  vecDir: TD3DXVector3;
  light,light1: TD3DLight9;
begin

  ZeroMemory(@mtrl, SizeOf(TD3DMaterial9));
  mtrl.Diffuse.r := 255.0; mtrl.Ambient.r := 55.0;
  mtrl.Diffuse.g := 255.0; mtrl.Ambient.g := 255.0;
  mtrl.Diffuse.b := 0.0; mtrl.Ambient.b := 0.0;
  mtrl.Diffuse.a := 1.0; mtrl.Ambient.a := 1.0;
  g_pd3dDevice.SetMaterial(mtrl);


  ZeroMemory(@light, SizeOf(TD3DLight9));
  light._Type      := D3DLIGHT_SPOT;
  light.Diffuse.r  := 255.0;
  light.Diffuse.g  := 255.0;
  light.Diffuse.b  := 10.0;
  vecDir:= D3DXVector3(Cos(timeGetTime/1000.0),
                       -1.0,
                       Sin(timeGetTime/1000.0) );
  D3DXVec3Normalize(light.Direction, vecDir);
  light.Range := 1000.0;
  g_pd3dDevice.SetLight(0, light);
  g_pd3dDevice.LightEnable(0, True);
  g_pd3dDevice.SetRenderState(D3DRS_LIGHTING, iTrue);

   ZeroMemory(@light1, SizeOf(TD3DLight9));
  light1._Type      := D3DLIGHT_DIRECTIONAL;
  light1.Diffuse.r  := 1.0;
  light1.Diffuse.g  := 1.0;
  light1.Diffuse.b  := 1.0;
  vecDir:= D3DXVector3(-5,
                       5.0,
                       0 );
  D3DXVec3Normalize(light1.Direction, vecDir);
  light1.Range := 1000.0;
  g_pd3dDevice.SetLight(1, light1);
  g_pd3dDevice.LightEnable(1, True);
  g_pd3dDevice.SetRenderState(D3DRS_LIGHTING, iTrue);
  // Finally, turn on some ambient light.
g_pd3dDevice.SetRenderState(D3DRS_AMBIENT, $ffffffff);
end;


procedure Render;
var
  i: DWORD;
begin

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

  // Begin the scene
    if SUCCEEDED(g_pd3dDevice.BeginScene) then
  begin
    // Setup the world, view, and projection matrices
    SetupMatrices;

    // Meshes are divided into subsets, one for each material. Render them in
    // a loop
    i:= 0;
    while(i < g_dwNumMaterials) do
    begin
      // Set the material and texture for this subset
      g_pd3dDevice.SetMaterial(g_pMeshMaterials);
      g_pd3dDevice.SetTexture(0, g_pMeshTextures);

      // Draw the mesh subset
      g_pMesh.DrawSubset(i);

      Inc(i);
    end;

    // End the scene
    g_pd3dDevice.EndScene;
  end;
    if SUCCEEDED(g_pd3dDevice.BeginScene) then
  begin
    // Setup the lights and materials
    SetupLights;

    // Setup the world, view, and projection matrices
    SetupMatrices;
   g_pd3dDevice.SetTexture(0, g_pTexture);

    // Set up the default texture states.
    g_pd3dDevice.SetTextureStageState(0, D3DTSS_COLOROP,   D3DTOP_MODULATE);
    g_pd3dDevice.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    g_pd3dDevice.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
    g_pd3dDevice.SetTextureStageState(0, D3DTSS_ALPHAOP,   D3DTOP_DISABLE);

    // Set up the default sampler states.
    g_pd3dDevice.SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
    g_pd3dDevice.SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
    g_pd3dDevice.SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR );
    g_pd3dDevice.SetSamplerState(0, D3DSAMP_ADDRESSU,  D3DTADDRESS_CLAMP );
    g_pd3dDevice.SetSamplerState(0, D3DSAMP_ADDRESSV,  D3DTADDRESS_CLAMP );

{$IFDEF SHOW_HOW_TO_USE_TCI}

    //    tu =  0.5*x + 0.5
    //    tv = -0.5*y + 0.5
    mat._11 := 0.25; mat._12 := 0.00; mat._13 := 0.00; mat._14 := 0.00;
    mat._21 := 0.00; mat._22 :=-0.25; mat._23 := 0.00; mat._24 := 0.00;
    mat._31 := 0.00; mat._32 := 0.00; mat._33 := 1.00; mat._34 := 0.00;
    mat._41 := 0.50; mat._42 := 0.50; mat._43 := 0.00; mat._44 := 1.00;

    g_pd3dDevice.SetTransform(D3DTS_TEXTURE0, mat);
    g_pd3dDevice.SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
    g_pd3dDevice.SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
{$ENDIF}

    // Render the vertex buffer contents
    g_pd3dDevice.SetStreamSource(0, g_pVB, 0, SizeOf(TCustomVertex));
    g_pd3dDevice.SetFVF(D3DFVF_CUSTOMVERTEX);
    g_pd3dDevice.DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2*2500-2);


    // End the scene
    g_pd3dDevice.EndScene;
end;


  // Present the backbuffer contents to the display
  g_pd3dDevice.Present(nil, nil, 0, nil);
end;

function MsgProc(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
  case uMsg of
    WM_DESTROY:
    begin
      Cleanup;
      PostQuitMessage(0);
      Result:= 0;
      Exit;
    end;
  end;

  Result:= DefWindowProc(hWnd, uMsg, wParam, lParam);
end;


var
  wc: TWndClassEx = (
    cbSize: SizeOf(TWndClassEx);
    style: CS_CLASSDC;
    lpfnWndProc: @MsgProc;
    cbClsExtra: 0;
    cbWndExtra: 0;
    hInstance: 0; // - filled later
    hIcon: 0;
    hCursor: 0;
    hbrBackground: 0;
    lpszMenuName: nil;
    lpszClassName: 'D3D Tutorial';
    hIconSm: 0);
var
  hWindow: HWND;
  msg: TMsg;
begin

  wc.hInstance:= GetModuleHandle(nil);
  RegisterClassEx(wc);

  // Create the application's window
  hWindow := CreateWindow('D3D Tutorial', 'D3D Tutorial 04: Lights',
                          WS_OVERLAPPEDWINDOW, 100, 100, 800, 800,
                          GetDesktopWindow, 0, wc.hInstance, nil);

  // Initialize Direct3D
  if SUCCEEDED(InitD3D(hWindow)) then
  begin
    // Create the scene geometry
    if SUCCEEDED(InitGeometry) then
    begin
      // Show the window
      ShowWindow(hWindow, SW_SHOWDEFAULT);
      UpdateWindow(hWindow);

      // Enter the message loop
      FillChar(msg, SizeOf(msg), 0);
      while (msg.message <> WM_QUIT) do
      begin
        if PeekMessage(msg, 0, 0, 0, PM_REMOVE) then
        begin
          TranslateMessage(msg);
          DispatchMessage(msg);
        end else
          Render;
      end;
    end;
  end;

  UnregisterClass('D3D Tutorial', wc.hInstance);
end.

5

主题

255

帖子

255

积分

中级会员

Rank: 3Rank: 3

积分
255
发表于 2004-4-27 21:23:00 | 显示全部楼层

Re:??????*?X????????????????

???
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-8-1 22:36

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表