home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / directx / pplane / pplane.cpp < prev    next >
C/C++ Source or Header  |  1997-07-14  |  26KB  |  923 lines

  1. /*
  2. **-----------------------------------------------------------------------------
  3. **  File:       PPlane.cpp
  4. **  Purpose:    Paper plane demo
  5. **  Notes:        Sample demonstrating D3DLVERTEX's, DrawPrimitive, 
  6. **                and SetTransform
  7. **
  8. ** Copyright (c) 1995 - 1997 by Microsoft, all rights reserved
  9. **-----------------------------------------------------------------------------
  10. */
  11.  
  12. /*
  13. **-----------------------------------------------------------------------------
  14. **    Include files
  15. **-----------------------------------------------------------------------------
  16. */
  17.  
  18. #include "Common.h"
  19. #include "Debug.h"
  20. #include "D3DScene.h"
  21. #include <time.h>
  22. #include "d3dutils.h"
  23. #include "pplane.h"
  24.  
  25.  
  26.  
  27. /*
  28. **-----------------------------------------------------------------------------
  29. **    Local variables
  30. **-----------------------------------------------------------------------------
  31. */
  32.  
  33. LPDIRECT3DMATERIAL2 g_lpmatBackground, g_lpMat;
  34.  
  35. extern const float pi;
  36.  
  37. //#define POINT_LINE_TEST
  38. #define GROUND_GRID
  39. DWORD        g_hBackTex;
  40. DWORD        g_hTex;
  41. DWORD        g_hBackMat;
  42. DWORD        g_hMat;
  43.  
  44. #define NUM_PLANES        42
  45. Plane    planes[NUM_PLANES];
  46.  
  47. #define PPLANE_VERTICES    36
  48. #define PPLANE_INDICES    60
  49. D3DVERTEX    pplane[PPLANE_VERTICES];
  50. WORD        pplane_indices[PPLANE_INDICES];
  51.  
  52. #ifdef GROUND_GRID
  53.     #define NUM_GRID    22
  54.     #define GRID_WIDTH    800.0f
  55.     D3DVERTEX    grid[NUM_GRID*NUM_GRID];
  56. #endif
  57.  
  58. #ifdef POINT_LINE_TEST
  59.     #define LOTS_OF_POINTS    (222)
  60.     D3DVERTEX    points[LOTS_OF_POINTS];
  61. #endif
  62.  
  63.  
  64. D3DMATRIX        g_proj, g_view, g_world;    // Matrices
  65.  
  66. D3DLIGHT        g_light;        // Structure defining the light
  67. LPDIRECT3DLIGHT    g_lpD3DLight;    // Object pointer for the light
  68.  
  69.  
  70.                                 
  71. /*
  72. **-----------------------------------------------------------------------------
  73. **    Local prototypes
  74. **-----------------------------------------------------------------------------
  75. */
  76.  
  77.  
  78.  
  79.  
  80. /*
  81. **-----------------------------------------------------------------------------
  82. **    D3DScene Methods
  83. **-----------------------------------------------------------------------------
  84. */
  85.  
  86. /*
  87. **----------------------------------------------------------------------------
  88. ** Name:        D3DScene::D3DScene
  89. ** Purpose:        Default Constructor
  90. **----------------------------------------------------------------------------
  91. */
  92.  
  93. D3DScene::D3DScene (void)
  94. {
  95.     lpd3dWindow = NULL;
  96. } // End D3DScene::D3DScene
  97.  
  98.  
  99.   
  100. /*
  101. **----------------------------------------------------------------------------
  102. ** Name:        D3DScene::~D3DScene
  103. ** Purpose:        Default Destructor
  104. **----------------------------------------------------------------------------
  105. */
  106.  
  107. D3DScene::~D3DScene (void)
  108. {
  109.     Fini ();
  110.     lpd3dWindow = NULL;
  111. } // End D3DScene::~D3DScene
  112.  
  113.  
  114.                             
  115. /*
  116. **-----------------------------------------------------------------------------
  117. **  Name:       DrawPPlane
  118. **  Purpose:    Draws a single Paper plane
  119. **-----------------------------------------------------------------------------
  120. */
  121.  
  122. HRESULT
  123. DrawPPlane (LPDIRECT3DDEVICE2 lpDev)
  124. {
  125.     HRESULT hResult;
  126.  
  127. #ifdef POINT_LINE_TEST
  128.         hResult = lpDev->DrawPrimitive (D3DPT_LINESTRIP, D3DVT_VERTEX, (LPVOID)points, LOTS_OF_POINTS, D3DDP_WAIT);
  129.     if (FAILED (hResult))
  130.     {
  131.         REPORTERR (hResult);
  132.         return hResult;
  133.     }
  134. #endif
  135.  
  136.         hResult =lpDev->DrawIndexedPrimitive (D3DPT_TRIANGLELIST, D3DVT_VERTEX, (LPVOID)pplane, PPLANE_VERTICES, pplane_indices, PPLANE_INDICES, D3DDP_WAIT);
  137.     if (FAILED (hResult))
  138.     {
  139.         REPORTERR (hResult);
  140.         return hResult;
  141.     }
  142.  
  143.     // Success
  144.     return hResult;
  145. }
  146.  
  147.  
  148. /*
  149. **-----------------------------------------------------------------------------
  150. **  Name:       D3DWindow::Init
  151. **  Purpose:    Initialize scene objects
  152. **-----------------------------------------------------------------------------
  153. */
  154.  
  155. HRESULT D3DScene::Init (LPD3DWindow lpd3dWin)
  156. {
  157.     HRESULT hResult;
  158.  
  159.     // Check Parameters
  160.     if (! lpd3dWin)
  161.     {
  162.         REPORTERR (DDERR_INVALIDPARAMS);
  163.         return DDERR_INVALIDPARAMS;
  164.     }
  165.  
  166.     // Save pointer to D3D Window
  167.     lpd3dWindow = lpd3dWin;
  168.  
  169.  
  170.     //
  171.     // generate the paper plane data
  172.     //
  173.  
  174.     // right wing top
  175.     pplane[ 0] = D3DVERTEX(D3DVECTOR(0.125f, 0.03125f, 3.5f), Normalize(D3DVECTOR(-0.25f, 1.0f, 0.0f)), rnd(), rnd());
  176.     pplane[ 1] = D3DVERTEX(D3DVECTOR(0.75f, 0.1875f, 3.25f), Normalize(D3DVECTOR(-0.25f, 1.0f, 0.0f)), rnd(), rnd());
  177.     pplane[ 2] = D3DVERTEX(D3DVECTOR(2.75f, 0.6875f, -2.0f), Normalize(D3DVECTOR(-0.25f, 1.0f, 0.0f)), rnd(), rnd());
  178.     pplane[ 3] = D3DVERTEX(D3DVECTOR(2.0f, 0.5f, -4.25f), Normalize(D3DVECTOR(-0.25f, 1.0f, 0.0f)), rnd(), rnd());
  179.     pplane[ 4] = D3DVERTEX(D3DVECTOR(0.5f, 0.125f, -3.5f), Normalize(D3DVECTOR(-0.25f, 1.0f, 0.0f)), rnd(), rnd());
  180.  
  181.     // right wing bottom
  182.     pplane[ 5] = D3DVERTEX(D3DVECTOR(0.125f, 0.03125f, 3.5f), Normalize(D3DVECTOR(0.25f, -1.0f, 0.0f)), rnd(), rnd());
  183.     pplane[ 6] = D3DVERTEX(D3DVECTOR(0.75f, 0.1875f, 3.25f), Normalize(D3DVECTOR(0.25f, -1.0f, 0.0f)), rnd(), rnd());
  184.     pplane[ 7] = D3DVERTEX(D3DVECTOR(2.75f, 0.6875f, -2.0f), Normalize(D3DVECTOR(0.25f, -1.0f, 0.0f)), rnd(), rnd());
  185.     pplane[ 8] = D3DVERTEX(D3DVECTOR(2.0f, 0.5f, -4.25f), Normalize(D3DVECTOR(0.25f, -1.0f, 0.0f)), rnd(), rnd());
  186.     pplane[ 9] = D3DVERTEX(D3DVECTOR(0.5f, 0.125f, -3.5f), Normalize(D3DVECTOR(0.25f, -1.0f, 0.0f)), rnd(), rnd());
  187.  
  188.     // left wing bottom
  189.     pplane[10] = D3DVERTEX(D3DVECTOR(-0.125f, 0.03125f, 3.5f), Normalize(D3DVECTOR(-0.25f, -1.0f, 0.0f)), rnd(), rnd());
  190.     pplane[11] = D3DVERTEX(D3DVECTOR(-0.75f, 0.1875f, 3.25f), Normalize(D3DVECTOR(-0.25f, -1.0f, 0.0f)), rnd(), rnd());
  191.     pplane[12] = D3DVERTEX(D3DVECTOR(-2.75f, 0.6875f, -2.0f), Normalize(D3DVECTOR(-0.25f, -1.0f, 0.0f)), rnd(), rnd());
  192.     pplane[13] = D3DVERTEX(D3DVECTOR(-2.0f, 0.5f, -4.25f), Normalize(D3DVECTOR(-0.25f, -1.0f, 0.0f)), rnd(), rnd());
  193.     pplane[14] = D3DVERTEX(D3DVECTOR(-0.5f, 0.125f, -3.5f), Normalize(D3DVECTOR(-0.25f, -1.0f, 0.0f)), rnd(), rnd());
  194.  
  195.     // left wing top
  196.     pplane[15] = D3DVERTEX(D3DVECTOR(-0.125f, 0.03125f, 3.5f), Normalize(D3DVECTOR(0.25f, 1.0f, 0.0f)), rnd(), rnd());
  197.     pplane[16] = D3DVERTEX(D3DVECTOR(-0.75f, 0.1875f, 3.25f), Normalize(D3DVECTOR(0.25f, 1.0f, 0.0f)), rnd(), rnd());
  198.     pplane[17] = D3DVERTEX(D3DVECTOR(-2.75f, 0.6875f, -2.0f), Normalize(D3DVECTOR(0.25f, 1.0f, 0.0f)), rnd(), rnd());
  199.     pplane[18] = D3DVERTEX(D3DVECTOR(-2.0f, 0.5f, -4.25f), Normalize(D3DVECTOR(0.25f, 1.0f, 0.0f)), rnd(), rnd());
  200.     pplane[19] = D3DVERTEX(D3DVECTOR(-0.5f, 0.125f, -3.5f), Normalize(D3DVECTOR(0.25f, 1.0f, 0.0f)), rnd(), rnd());
  201.     
  202.     // right body outside
  203.     pplane[20] = D3DVERTEX(D3DVECTOR(0.125f, 0.03125f, 3.5f), Normalize(D3DVECTOR(1.0f, -0.1f, 0.0f)), rnd(), rnd());
  204.     pplane[21] = D3DVERTEX(D3DVECTOR(0.5f, 0.125f, -3.5f), Normalize(D3DVECTOR(1.0f, -0.1f, 0.0f)), rnd(), rnd());
  205.     pplane[22] = D3DVERTEX(D3DVECTOR(0.0f, -2.25f, -2.75f), Normalize(D3DVECTOR(1.0f, -0.1f, 0.0f)), rnd(), rnd());
  206.     pplane[23] = D3DVERTEX(D3DVECTOR(0.0f, -0.5f, 3.625f), Normalize(D3DVECTOR(1.0f, -0.1f, 0.0f)), rnd(), rnd());
  207.  
  208.     // right body inside
  209.     pplane[24] = D3DVERTEX(D3DVECTOR(0.125f, 0.03125f, 3.5f), Normalize(D3DVECTOR(-1.0f, 0.1f, 0.0f)), rnd(), rnd());
  210.     pplane[25] = D3DVERTEX(D3DVECTOR(0.5f, 0.125f, -3.5f), Normalize(D3DVECTOR(-1.0f, 0.1f, 0.0f)), rnd(), rnd());
  211.     pplane[26] = D3DVERTEX(D3DVECTOR(0.0f, -2.25f, -2.75f), Normalize(D3DVECTOR(-1.0f, 0.1f, 0.0f)), rnd(), rnd());
  212.     pplane[27] = D3DVERTEX(D3DVECTOR(0.0f, -0.5f, 3.625f), Normalize(D3DVECTOR(-1.0f, 0.1f, 0.0f)), rnd(), rnd());
  213.  
  214.     // left body outside
  215.     pplane[28] = D3DVERTEX(D3DVECTOR(-0.125f, 0.03125f, 3.5f), Normalize(D3DVECTOR(-1.0f, -0.1f, 0.0f)), rnd(), rnd());
  216.     pplane[29] = D3DVERTEX(D3DVECTOR(-0.5f, 0.125f, -3.5f), Normalize(D3DVECTOR(-1.0f, -0.1f, 0.0f)), rnd(), rnd());
  217.     pplane[30] = D3DVERTEX(D3DVECTOR(0.0f, -2.25f, -2.75f), Normalize(D3DVECTOR(-1.0f, -0.1f, 0.0f)), rnd(), rnd());
  218.     pplane[31] = D3DVERTEX(D3DVECTOR(0.0f, -0.5f, 3.625f), Normalize(D3DVECTOR(-1.0f, -0.1f, 0.0f)), rnd(), rnd());
  219.  
  220.     // left body inside
  221.     pplane[32] = D3DVERTEX(D3DVECTOR(-0.125f, 0.03125f, 3.5f), Normalize(D3DVECTOR(1.0f, 0.1f, 0.0f)), rnd(), rnd());
  222.     pplane[33] = D3DVERTEX(D3DVECTOR(-0.5f, 0.125f, -3.5f), Normalize(D3DVECTOR(1.0f, 0.1f, 0.0f)), rnd(), rnd());
  223.     pplane[34] = D3DVERTEX(D3DVECTOR(0.0f, -2.25f, -2.75f), Normalize(D3DVECTOR(1.0f, 0.1f, 0.0f)), rnd(), rnd());
  224.     pplane[35] = D3DVERTEX(D3DVECTOR(0.0f, -0.5f, 3.625f), Normalize(D3DVECTOR(1.0f, 0.1f, 0.0f)), rnd(), rnd());
  225.  
  226.     // right wing top
  227.     pplane_indices[ 0] = 0;
  228.     pplane_indices[ 1] = 1;
  229.     pplane_indices[ 2] = 4;
  230.     pplane_indices[ 3] = 1;
  231.     pplane_indices[ 4] = 2;
  232.     pplane_indices[ 5] = 4;
  233.     pplane_indices[ 6] = 4;
  234.     pplane_indices[ 7] = 2;
  235.     pplane_indices[ 8] = 3;
  236.  
  237.     // right wing bottom
  238.     pplane_indices[ 9] = 5;
  239.     pplane_indices[10] = 9;
  240.     pplane_indices[11] = 6;
  241.     pplane_indices[12] = 6;
  242.     pplane_indices[13] = 9;
  243.     pplane_indices[14] = 7;
  244.     pplane_indices[15] = 7;
  245.     pplane_indices[16] = 9;
  246.     pplane_indices[17] = 8;
  247.  
  248.     // left wing top
  249.     pplane_indices[18] = 10;
  250.     pplane_indices[19] = 11;
  251.     pplane_indices[20] = 14;
  252.     pplane_indices[21] = 11;
  253.     pplane_indices[22] = 12;
  254.     pplane_indices[23] = 14;
  255.     pplane_indices[24] = 14;
  256.     pplane_indices[25] = 12;
  257.     pplane_indices[26] = 13;
  258.  
  259.     // left wing bottom
  260.     pplane_indices[27] = 15;
  261.     pplane_indices[28] = 19;
  262.     pplane_indices[29] = 16;
  263.     pplane_indices[30] = 16;
  264.     pplane_indices[31] = 19;
  265.     pplane_indices[32] = 17;
  266.     pplane_indices[33] = 17;
  267.     pplane_indices[34] = 19;
  268.     pplane_indices[35] = 18;
  269.  
  270.     // right body outside
  271.     pplane_indices[36] = 20;
  272.     pplane_indices[37] = 23;
  273.     pplane_indices[38] = 21;
  274.     pplane_indices[39] = 21;
  275.     pplane_indices[40] = 23;
  276.     pplane_indices[41] = 22;
  277.  
  278.     // right body inside
  279.     pplane_indices[42] = 24;
  280.     pplane_indices[43] = 25;
  281.     pplane_indices[44] = 27;
  282.     pplane_indices[45] = 25;
  283.     pplane_indices[46] = 26;
  284.     pplane_indices[47] = 27;
  285.  
  286.     // left body outside
  287.     pplane_indices[48] = 28;
  288.     pplane_indices[49] = 29;
  289.     pplane_indices[50] = 31;
  290.     pplane_indices[51] = 29;
  291.     pplane_indices[52] = 30;
  292.     pplane_indices[53] = 31;
  293.  
  294.     // left body inside
  295.     pplane_indices[54] = 32;
  296.     pplane_indices[55] = 35;
  297.     pplane_indices[56] = 33;
  298.     pplane_indices[57] = 33;
  299.     pplane_indices[58] = 35;
  300.     pplane_indices[59] = 34;
  301.  
  302.     // seed the random number generator
  303.     srand (time (0));
  304.  
  305.     for (int i=0; i<NUM_PLANES; i++) 
  306.     {
  307.         planes[i].loc = D3DVECTOR(0.0f, 0.0f, 0.0f);
  308.         planes[i].goal = D3DVECTOR(10.0f*(rnd()-rnd()), 10.0f*(rnd()-rnd()), 10.0f*(rnd()-rnd()));
  309.         planes[i].delta = D3DVECTOR(0.0f, 0.0f, 1.0f);
  310.         planes[i].yaw = 0.0f;
  311.         planes[i].pitch = 0.0f;
  312.         planes[i].roll = 0.0f;
  313.         planes[i].dyaw = 0.0f;
  314.     }
  315.  
  316.  
  317. #ifdef POINT_LINE_TEST
  318.     for (i=0; i<LOTS_OF_POINTS; i++) 
  319.     {
  320.         float y = cos(pi*(double)i/LOTS_OF_POINTS);
  321.         float x = (float)sin (pi*20.0*(double)i/LOTS_OF_POINTS) * (1.0f-y*y);
  322.         float z = (float)cos (pi*20.0*(double)i/LOTS_OF_POINTS) * (1.0f-y*y);
  323.         D3DVECTOR    p(x, y, z);
  324.  
  325.         p = Normalize (p);
  326.         points[i] = _D3DVERTEX(10.0*p, p, rnd(), rnd());
  327.     }
  328. #endif
  329.  
  330. #ifdef GROUND_GRID
  331.     float    size = GRID_WIDTH/(NUM_GRID-1.0f);
  332.     float    offset = GRID_WIDTH/2.0f;
  333.     for (i=0; i<NUM_GRID; i++) 
  334.     {
  335.         for (int j=0; j<NUM_GRID; j++) 
  336.         {
  337.             grid[j+i*NUM_GRID] = D3DVERTEX(D3DVECTOR(i*size-offset, 0.0f, j*size-offset), Normalize(D3DVECTOR(0.0f, 1.0f, 0.0f)), 0.0f, 0.0f);
  338.         }
  339.     }
  340. #endif
  341.  
  342.     // Initialize Viewport
  343.     hResult = InitViewport ();
  344.     if (FAILED (hResult))
  345.         return hResult;
  346.  
  347.     return DD_OK;
  348. } // End D3DScene::Init
  349.  
  350.  
  351.  
  352. /*
  353. **-----------------------------------------------------------------------------
  354. **  Name:       D3DScene::Fini
  355. **  Purpose:    Cleanup scene objects
  356. **-----------------------------------------------------------------------------
  357. */
  358.  
  359. HRESULT D3DScene::Fini (void)
  360. {
  361.     FiniViewport ();
  362.  
  363.     // Success
  364.     return DD_OK;
  365. } // End D3DScene::Fini
  366.  
  367.  
  368.   
  369. /*
  370. **-----------------------------------------------------------------------------
  371. **  Name:       D3DScene::Render
  372. **  Purpose:    Draws scene
  373. **-----------------------------------------------------------------------------
  374. */
  375.  
  376. HRESULT D3DScene::Render (void)
  377. {
  378.     LPDIRECT3DDEVICE2    lpDev;
  379.     LPDIRECT3DVIEWPORT2 lpView;     
  380.     RECT                rSrc;
  381.     LPD3DRECT            lpExtent = NULL;
  382.     D3DRECT                d3dRect;
  383.     D3DCLIPSTATUS        status;
  384.     HRESULT                hResult;
  385.  
  386.     // Check Initialization
  387.     if ((! lpd3dWindow) || (! lpd3dWindow->isValid ()))
  388.     {
  389.         // Error,
  390.         REPORTERR (DDERR_GENERIC);
  391.         return DDERR_GENERIC;
  392.     }
  393.  
  394.     lpDev    = lpd3dWindow->lpd3dDevice;
  395.     lpView  = lpd3dWindow->lpd3dViewport;
  396.     lpd3dWindow->GetSrcRect (rSrc);
  397.  
  398.     
  399.     //
  400.     // Clear both back and z-buffer.
  401.     //
  402.     // NOTE: Its safe to specify the z-buffer clear flag even if we
  403.     // don't have an attached z-buffer. Direct3D will simply discard
  404.     // the flag if no z-buffer is being used.
  405.     //
  406.     // NOTE: For maximum efficiency we only want to clear those
  407.     // regions of the device surface and z-buffer which we actually
  408.     // rendered to in the last frame. This is the purpose of the
  409.     // array of rectangles and count passed to this function. It is
  410.     // possible to query Direct3D for the regions of the device
  411.     // surface that were rendered to by that execute. The application
  412.     // can then accumulate those rectangles and clear only those
  413.     // regions. However this is a very simple sample and so, for
  414.     // simplicity, we will just clear the entire device surface and
  415.     // z-buffer. Probably not something you wan't to do in a real
  416.     // application.
  417.     ///
  418.     d3dRect.lX1 = rSrc.left;
  419.     d3dRect.lX2 = rSrc.right;
  420.     d3dRect.lY1 = rSrc.top;
  421.     d3dRect.lY2 = rSrc.bottom;
  422.     hResult = lpView->Clear (1UL, &d3dRect,
  423.                              D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER);
  424.     if (FAILED (hResult))
  425.     {
  426.         REPORTERR (hResult);
  427.         return hResult;
  428.     }
  429.  
  430.     // Calculate exclude region
  431.     if (lpExtent)
  432.     {
  433.         status.dwFlags = D3DCLIPSTATUS_EXTENTS2;
  434.         status.dwStatus = 0;
  435.         status.minx = (float)lpExtent->x1;
  436.         status.maxx = (float)lpExtent->x2;
  437.         status.miny = (float)lpExtent->y1;
  438.         status.maxy = (float)lpExtent->y2;
  439.         status.minz = 0.0f;
  440.         status.maxz = 0.0f;
  441.     }
  442.  
  443.     hResult = lpDev->BeginScene ();
  444.     if (FAILED (hResult))
  445.     {
  446.         REPORTERR (hResult);
  447.         return hResult;
  448.     }
  449.  
  450.     // Exclude text region
  451.     if (lpExtent)
  452.     {
  453.         hResult = lpDev->SetClipStatus (&status);
  454.         if (FAILED (hResult))
  455.         {
  456.             REPORTERR (hResult);
  457.             return hResult;
  458.         }
  459.     }
  460.  
  461.     hResult = lpDev->SetLightState (D3DLIGHTSTATE_MATERIAL, g_hMat);
  462.     if (FAILED (hResult))
  463.     {
  464.         REPORTERR (hResult);
  465.         return hResult;
  466.     }
  467.  
  468.     hResult = lpDev->SetRenderState (D3DRENDERSTATE_ZENABLE, 1);
  469.     if (FAILED (hResult))
  470.     {
  471.         REPORTERR (hResult);
  472.         return hResult;
  473.     }
  474.  
  475.     hResult = lpDev->SetRenderState (D3DRENDERSTATE_TEXTUREHANDLE, 0);
  476.     if (FAILED (hResult))
  477.     {
  478.         REPORTERR (hResult);
  479.         return hResult;
  480.     }
  481.  
  482.     // turn on some ambient light
  483.     hResult = lpDev->SetLightState (D3DLIGHTSTATE_AMBIENT, RGBA_MAKE(60, 60, 60, 60));
  484.     if (FAILED (hResult))
  485.     {
  486.         REPORTERR (hResult);
  487.         return hResult;
  488.     }
  489.  
  490.     // set the projection matrix
  491.     g_proj = ProjectionMatrix (10.0f, 500.0f, pi/2.0f);
  492.     hResult = lpDev->SetTransform (D3DTRANSFORMSTATE_PROJECTION, &g_proj);
  493.     if (FAILED (hResult))
  494.     {
  495.         REPORTERR (hResult);
  496.         return hResult;
  497.     }
  498.     
  499.     // play with planes
  500.     static float        tic = 0.0f;
  501.     static float        speed=2.0f;
  502.     static float        angle_tweak = 0.02f;
  503.     static D3DVECTOR    z_ward(0.0f, 0.0f, 1.0f);
  504.  
  505.     for (int i=0; i<NUM_PLANES; i++) 
  506.     {
  507.         D3DVECTOR    offset;
  508.  
  509.         // tweek orientation based on last position and goal
  510.         offset = planes[i].goal - planes[i].loc;
  511.  
  512.         // first, tweak the pitch
  513.         if (offset.y > 1.0) {            // we're too low
  514.             planes[i].pitch += angle_tweak;
  515.             if (planes[i].pitch > 0.8f)
  516.                 planes[i].pitch = 0.8f;
  517.         } else if (offset.y < -1.0) {    // we're too high
  518.             planes[i].pitch -= angle_tweak;
  519.             if (planes[i].pitch < -0.8f)
  520.                 planes[i].pitch = -0.8f;
  521.         } else {
  522.             // add damping
  523.             planes[i].pitch *= 0.95f;
  524.         }
  525.  
  526.         // now figure out yaw changes
  527.         offset.y = 0.0f;  planes[i].delta.y = 0.0f;
  528.         planes[i].delta = Normalize (planes[i].delta);
  529.         offset = Normalize (offset);
  530.         float    dot = DotProduct (offset, planes[i].delta);
  531.         offset = CrossProduct (offset, planes[i].delta);
  532.         dot = (1.0f-dot)/2.0f * angle_tweak * 10.0f;
  533.         if (offset.y > 0.01) {
  534.             planes[i].dyaw = (planes[i].dyaw*9.0f + dot) * 0.1f;
  535.         } else if (offset.y < 0.01) {
  536.             planes[i].dyaw = (planes[i].dyaw*9.0f - dot) * 0.1f;
  537.         }
  538.         planes[i].yaw += planes[i].dyaw;
  539.         planes[i].roll = -planes[i].dyaw * 9.0f;
  540.  
  541.         if (rnd() < 0.03) 
  542.         {
  543.             planes[i].goal = D3DVECTOR(60.0f*(rnd()-rnd()), 60.0f*(rnd()-rnd()), rnd()*300.0f - 100.0f);
  544.         }
  545.  
  546.         // build the world matrix for the pplane
  547.         g_world = MatrixMult (MatrixMult (RotateYMatrix (planes[i].yaw), RotateXMatrix (planes[i].pitch)), RotateZMatrix (planes[i].roll));
  548.         
  549.         // get delta buy grabbing the z axis out of the transform
  550.         planes[i].delta[0] = g_world(2, 0);
  551.         planes[i].delta[1] = g_world(2, 1);
  552.         planes[i].delta[2] = g_world(2, 2);
  553.         // update position
  554.         planes[i].loc += speed * planes[i].delta;
  555.  
  556.         // before we draw the first plane use it's position to update the camera
  557.         if (i==0) 
  558.         {
  559.             D3DVECTOR    from, at, local_up;
  560.             D3DVECTOR    up(0.0f, 1.0f, 0.0f);
  561.  
  562.             local_up[0] = g_world(1, 0);
  563.             local_up[1] = g_world(1, 1);
  564.             local_up[2] = g_world(1, 2);
  565.             from = planes[0].loc - 20.0f * planes[0].delta + 6.0f * local_up;
  566.             at = planes[0].loc + planes[0].delta;
  567.  
  568.             g_view = ViewMatrix (from, at, up, planes[0].roll);
  569.             hResult = lpDev->SetTransform (D3DTRANSFORMSTATE_VIEW, &g_view);
  570.             if (FAILED (hResult))
  571.             {
  572.                 REPORTERR (hResult);
  573.                 return hResult;
  574.             }
  575.         }
  576.  
  577.         // first translate into place, then set orientation, then scale
  578.         g_world = TranslateMatrix (planes[i].loc);
  579.         g_world = MatrixMult (g_world, MatrixMult (MatrixMult (RotateYMatrix (planes[i].yaw), RotateXMatrix (planes[i].pitch)), RotateZMatrix (planes[i].roll)));
  580.         //g_world = MatrixMult (g_world, Scale(5.0f));
  581.         
  582.         // apply the world matrix
  583.         hResult = lpDev->SetTransform (D3DTRANSFORMSTATE_WORLD, &g_world);
  584.         if (FAILED (hResult))
  585.         {
  586.             REPORTERR (hResult);
  587.             return hResult;
  588.         }
  589.  
  590.         // display the pplane
  591.         DrawPPlane (lpDev);
  592.     }    // end of loop for each pplane
  593.  
  594. #ifdef GROUND_GRID
  595.     g_world = TranslateMatrix (0.0f, -60.0f, 0.0f);
  596.     hResult = lpDev->SetTransform (D3DTRANSFORMSTATE_WORLD, &g_world);
  597.     if (FAILED (hResult))
  598.     {
  599.         REPORTERR (hResult);
  600.         return hResult;
  601.     }
  602.  
  603.         hResult = lpDev->DrawPrimitive (D3DPT_LINELIST, D3DVT_VERTEX, (LPVOID)grid, NUM_GRID*NUM_GRID, D3DDP_WAIT);
  604.     if (FAILED (hResult))
  605.     {
  606.         REPORTERR (hResult);
  607.         return hResult;
  608.     }
  609.  
  610.     g_world = MatrixMult (g_world, RotateYMatrix (pi/2.0f));
  611.     hResult = lpDev->SetTransform (D3DTRANSFORMSTATE_WORLD, &g_world);
  612.     if (FAILED (hResult))
  613.     {
  614.         REPORTERR (hResult);
  615.         return hResult;
  616.     }
  617.  
  618.         hResult = lpDev->DrawPrimitive (D3DPT_LINELIST, D3DVT_VERTEX, (LPVOID)grid, NUM_GRID*NUM_GRID, D3DDP_WAIT);
  619.     if (FAILED (hResult))
  620.     {
  621.         REPORTERR (hResult);
  622.         return hResult;
  623.     }
  624. #endif
  625.  
  626.     tic += 0.01f;
  627.  
  628.     if (lpExtent)
  629.     {
  630.         hResult = lpDev->GetClipStatus (&status);
  631.         if (FAILED (hResult))
  632.         {
  633.             REPORTERR (hResult);
  634.             return hResult;
  635.         }
  636.     }
  637.  
  638.     hResult = lpDev->EndScene ();
  639.     if (FAILED (hResult))
  640.     {
  641.         REPORTERR (hResult);
  642.         return hResult;
  643.     }
  644.  
  645.     if (lpExtent)
  646.     {
  647.         // return clip status in extent struct
  648.         if (status.dwFlags & D3DCLIPSTATUS_EXTENTS2)
  649.         {
  650.             lpExtent->x1 = (long)floor ((double)status.minx);
  651.             lpExtent->x2 = (long)ceil ((double)status.maxx);
  652.             lpExtent->y1 = (long)floor ((double)status.miny);
  653.             lpExtent->y2 = (long)ceil ((double)status.maxy);
  654.         }
  655.     }
  656.  
  657.     // Success
  658.     return DD_OK;
  659. } // End D3DScene::Render
  660.  
  661.  
  662.   
  663. /*
  664. **----------------------------------------------------------------------------
  665. ** Name:        D3DScene::Restore
  666. ** Purpose:     Restore any scene specific surfaces that might have been
  667. **                lost on a DDERR_LOSTSURFACE message
  668. **----------------------------------------------------------------------------
  669. */
  670.  
  671. HRESULT D3DScene::Restore (void)
  672. {
  673.     // Nothing to do for now
  674.  
  675.     // Success
  676.     return DD_OK;
  677. } // End D3DScene::Restore
  678.  
  679.  
  680.  
  681. /*
  682. **-----------------------------------------------------------------------------
  683. **  Name:       D3DScene::InitViewport
  684. **  Purpose:    Initialize Viewport
  685. **-----------------------------------------------------------------------------
  686. */
  687.  
  688. HRESULT D3DScene::InitViewport (void)
  689. {
  690.     LPDIRECT3D2            lpD3D;
  691.     LPDIRECT3DDEVICE2   lpDev;
  692.     LPDIRECT3DVIEWPORT2 lpViewport;
  693.     HRESULT                hResult;
  694.     D3DMATERIAL            matBackground, mat;
  695.     D3DMATERIALHANDLE    hBackMat, hMat;
  696.  
  697.     // Check Initialization
  698.     if ((! lpd3dWindow) || (! lpd3dWindow->isValid ()))
  699.     {
  700.         // Error,
  701.         REPORTERR (DDERR_GENERIC);
  702.         return DDERR_GENERIC;
  703.     }
  704.  
  705.     lpD3D  = lpd3dWindow->lpD3D;
  706.     lpDev  = lpd3dWindow->lpd3dDevice;
  707.     lpViewport = lpd3dWindow->lpd3dViewport;
  708.  
  709.     if ((! lpD3D) || (! lpDev) || (! lpViewport))
  710.     {
  711.         REPORTERR (DDERR_GENERIC);
  712.         return DDERR_GENERIC;
  713.     }
  714.    
  715.     // Create and set up the background material
  716.     hResult = lpD3D->CreateMaterial (&g_lpmatBackground, NULL);
  717.     if (FAILED (hResult))
  718.     {
  719.         REPORTERR (hResult);
  720.         return hResult;
  721.     }
  722.  
  723.     memset (&matBackground, 0, sizeof(D3DMATERIAL));
  724.     matBackground.dwSize = sizeof(D3DMATERIAL);
  725.     matBackground.diffuse.r = (D3DVALUE)0.2;
  726.     matBackground.diffuse.g = (D3DVALUE)0.6;
  727.     matBackground.diffuse.b = (D3DVALUE)1.0;
  728.     matBackground.ambient.r = (D3DVALUE)1.0;
  729.     matBackground.ambient.g = (D3DVALUE)1.0;
  730.     matBackground.ambient.b = (D3DVALUE)1.0;
  731. //    matBackground.hTexture = hBackTex;
  732.     matBackground.dwRampSize = 1;
  733.     
  734.     hResult = g_lpmatBackground->SetMaterial (&matBackground);
  735.     if (FAILED (hResult))
  736.     {
  737.         REPORTERR (hResult);
  738.         return hResult;
  739.     }
  740.     
  741.     hResult = g_lpmatBackground->GetHandle (lpDev, &hBackMat);
  742.     if (FAILED (hResult))
  743.     {
  744.         REPORTERR (hResult);
  745.         return hResult;
  746.     }
  747.  
  748.     hResult = lpViewport->SetBackground (hBackMat);
  749.     if (FAILED (hResult))
  750.     {
  751.         REPORTERR (hResult);
  752.         return hResult;
  753.     }
  754.  
  755.     g_hBackMat = hBackMat;
  756.  
  757.     // create and set up the plane material
  758.     hResult = lpD3D->CreateMaterial (&g_lpMat, NULL);
  759.     if (FAILED (hResult))
  760.     {
  761.         REPORTERR (hResult);
  762.         return hResult;
  763.     }
  764.  
  765.     memset(&mat, 0, sizeof(D3DMATERIAL));
  766.     mat.dwSize = sizeof(D3DMATERIAL);
  767.     mat.diffuse.r = (D3DVALUE)1.0;
  768.     mat.diffuse.g = (D3DVALUE)1.0;
  769.     mat.diffuse.b = (D3DVALUE)1.0;
  770.     mat.ambient.r = (D3DVALUE)1.0;
  771.     mat.ambient.g = (D3DVALUE)1.0;
  772.     mat.ambient.b = (D3DVALUE)1.0;
  773. #define SPECULAR
  774. #ifdef SPECULAR
  775.     mat.specular.r = (D3DVALUE)1.0;
  776.     mat.specular.g = (D3DVALUE)1.0;
  777.     mat.specular.b = (D3DVALUE)1.0;
  778.     mat.power = (float)40.0;
  779. #else
  780.     mat.specular.r = (D3DVALUE)0.0;
  781.     mat.specular.g = (D3DVALUE)0.0;
  782.     mat.specular.b = (D3DVALUE)0.0;
  783.     mat.power = (float)0.0;
  784. #endif    
  785. //    mat.hTexture = hTexure;
  786.     mat.dwRampSize = 16;
  787.     g_lpMat->SetMaterial (&mat);
  788.     g_lpMat->GetHandle (lpDev, &hMat);
  789.     g_hMat= (DWORD) hMat;
  790. //    g_hTex= hTexure;
  791.  
  792.     //g_view = ViewMatrix(100.0f);
  793.     g_proj = ProjectionMatrix (1.0f, 1000.0f, 90.0f);
  794.     g_world = IdentityMatrix ();
  795.  
  796.     // set up the light
  797.     memset (&g_light, 0, sizeof(D3DLIGHT));
  798.     g_light.dwSize = sizeof(D3DLIGHT);
  799.     g_light.dltType = D3DLIGHT_POINT;
  800.     // position light behind viewer
  801.     g_light.dvPosition.x = 0.0f;
  802.     g_light.dvPosition.y = 1000.0f;
  803.     g_light.dvPosition.z = -100.0f;
  804.     g_light.dcvColor.r = D3DVAL(1.0);
  805.     g_light.dcvColor.g = D3DVAL(1.0);
  806.     g_light.dcvColor.b = D3DVAL(1.0);
  807.     g_light.dvAttenuation0 = (float)1.0;
  808.     g_light.dvAttenuation1 = (float)0.0;
  809.     g_light.dvAttenuation2 = (float)0.0;
  810.  
  811.     hResult = lpD3D->CreateLight (&g_lpD3DLight, NULL);
  812.     if (FAILED (hResult))
  813.     {
  814.         REPORTERR (hResult);
  815.         return hResult;
  816.     }
  817.  
  818.     hResult = g_lpD3DLight->SetLight (&g_light);
  819.     if (FAILED (hResult))
  820.     {
  821.         REPORTERR (hResult);
  822.         return hResult;
  823.     }
  824.  
  825.     hResult = lpViewport->AddLight (g_lpD3DLight);
  826.     if (FAILED (hResult))
  827.     {
  828.         REPORTERR (hResult);
  829.         return hResult;
  830.     }
  831.  
  832.     // Success
  833.     return DD_OK;
  834. } // End D3DScene::InitViewport
  835.  
  836.  
  837.  
  838. /*
  839. **-----------------------------------------------------------------------------
  840. **  Name:       D3DScene::FiniViewport
  841. **  Purpose:    Cleanup Viewport
  842. **-----------------------------------------------------------------------------
  843. */
  844.  
  845. HRESULT D3DScene::FiniViewport (void)
  846. {
  847.     HRESULT hResult;
  848.     LPDIRECT3DVIEWPORT2 lpViewport;
  849.  
  850.     // Check Initialization
  851.     if (! lpd3dWindow)
  852.     {
  853.         // Error,
  854.         REPORTERR (DDERR_GENERIC);
  855.         return DDERR_GENERIC;
  856.     }
  857.  
  858.     lpViewport = lpd3dWindow->GetViewport ();
  859.  
  860.     // Cleanup light
  861.     if (g_lpD3DLight)
  862.     {
  863.         // Remove from current view
  864.         if (lpViewport) 
  865.         {
  866.             hResult = lpViewport->DeleteLight (g_lpD3DLight);
  867.             if (FAILED (hResult))
  868.             {
  869.                 REPORTERR (hResult);
  870.             }
  871.  
  872.         }
  873.  
  874.         // Release light
  875.         hResult = g_lpD3DLight->Release ();
  876.         if (FAILED (hResult))
  877.         {
  878.             REPORTERR (hResult);
  879.         }
  880.  
  881.         g_lpD3DLight = NULL;
  882.     }
  883.  
  884.     // Cleanup Material
  885.     if (g_lpMat)
  886.     {
  887.         hResult = g_lpMat->Release ();
  888.         if (FAILED (hResult))
  889.         {
  890.             REPORTERR (hResult);
  891.         }
  892.  
  893.         g_lpMat = NULL;
  894.         g_hMat = NULL;
  895.     }
  896.  
  897.     // Cleanup Background
  898.     if (g_lpmatBackground)
  899.     {
  900.         hResult = g_lpmatBackground->Release ();
  901.         if (FAILED (hResult))
  902.         {
  903.             REPORTERR (hResult);
  904.         }
  905.  
  906.         g_lpmatBackground = NULL;
  907.         g_hBackMat = NULL;
  908.     }
  909.  
  910.     // Success
  911.     return DD_OK;
  912. } // End D3DScene::FiniViewport
  913.  
  914.  
  915.   
  916. /*
  917. **-----------------------------------------------------------------------------
  918. **    End of File
  919. **-----------------------------------------------------------------------------
  920. */
  921.  
  922.  
  923.