home *** CD-ROM | disk | FTP | other *** search
/ The Net: Ultimate Internet Guide / WWLCD1.ISO / pc / directx2 / sdk / samples / flipcube / flipcube.c next >
Encoding:
C/C++ Source or Header  |  1996-05-28  |  21.4 KB  |  588 lines

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995, 1996 Microsoft Corporation. All Rights Reserved.
  4.  *
  5.  *  File: flipcube.c
  6.  *
  7.  *  Mouse controls: Left-click stops cube rotating.  Holding down left mouse
  8.  *     button and moving mouse moves cube.  Right-click resumes rotating.
  9.  *
  10.  ***************************************************************************/
  11.  
  12. #include <windows.h>
  13. #include <windowsx.h>
  14. #include <math.h>
  15. #include <malloc.h>
  16. #include "d3ddemo.h"
  17.  
  18. BOOL KeyboardHandler(UINT message, WPARAM wParam, LPARAM lParam);
  19. BOOL MouseHandler(UINT message, WPARAM wParam, LPARAM lParam);
  20. void ConcatenateXRotation(LPD3DMATRIX lpM, float Degrees );
  21. void ConcatenateYRotation(LPD3DMATRIX lpM, float Degrees );
  22. void ConcatenateZRotation(LPD3DMATRIX lpM, float Degrees );
  23.  
  24. //*** Cube colors - one RGB color per material
  25. const D3DCOLOR MaterialColors[6][2] =
  26. {
  27.   RGBA_MAKE(240,  20,  20, 255),    // Unsaturated Red
  28.   RGB_MAKE (240,  20,  20),         // Unsaturated Red
  29.   RGBA_MAKE( 20, 240,  20, 255),    // Unsaturated Green
  30.   RGB_MAKE ( 20, 240,  20),         // Unsaturated Green
  31.   RGBA_MAKE( 20,  20, 240, 255),    // Unsaturated Blue  
  32.   RGB_MAKE ( 20,  20, 240),         // Unsaturated Blue
  33.   RGBA_MAKE(128,  64,   0, 255),    // Brown
  34.   RGB_MAKE (128,  64,   0),         // Brown
  35.   RGBA_MAKE(240,  20, 240, 255),    // Unsaturated Magenta
  36.   RGB_MAKE (240,  20, 240),         // Unsaturated Magenta
  37.   RGBA_MAKE(240, 240,  20, 255),    // Unsaturated Yellow
  38.   RGB_MAKE (240, 240,  20),         // Unsaturated Yellow
  39. };
  40.  
  41. //*** Lighting
  42. const D3DCOLOR AmbientColor = RGBA_MAKE(20, 20, 20, 20);
  43. LPDIRECT3DLIGHT lpD3DLight;
  44.  
  45. //*** Viewing and perspective
  46. D3DMATRIXHANDLE hProj, hView, hWorld;
  47. D3DMATRIX proj = {
  48.     D3DVAL(2.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0),
  49.     D3DVAL(0.0), D3DVAL(2.0), D3DVAL(0.0), D3DVAL(0.0),
  50.     D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1.0), D3DVAL(1.0),
  51.     D3DVAL(0.0), D3DVAL(0.0), D3DVAL(-1.0), D3DVAL(0.0)
  52. };
  53. D3DMATRIX view = {
  54.     D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0),
  55.     D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0),
  56.     D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0),
  57.     D3DVAL(0.0), D3DVAL(0.0), D3DVAL(10.0), D3DVAL(1.0)
  58. };
  59. D3DMATRIX identity = {
  60.     D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0),
  61.     D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0),
  62.     D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0),
  63.     D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1.0)
  64. };
  65. D3DMATRIX world, spin;
  66.  
  67. //*** Execute buffer
  68. static D3DEXECUTEDATA d3dExData;
  69. static LPDIRECT3DEXECUTEBUFFER lpD3DExBuf;
  70. static D3DEXECUTEBUFFERDESC debDesc;
  71.  
  72. //*** Interaction
  73. static POINT       Move;
  74. static POINT       Last;
  75.  
  76. /*
  77.  * A structure which holds the object's data
  78.  */
  79.  
  80. LPDIRECT3DMATERIAL lpBackgroundMaterial;
  81. LPDIRECT3DMATERIAL lpD3DMaterial[6];
  82. D3DMATERIALHANDLE  D3DMaterialHandle[6];
  83. /* Cube vertices, normals, shades, and modeling transform */
  84. int NumVertices = 24;
  85. static D3DVERTEX CubeVertices[] = {
  86.   {D3DVAL(-1.0),D3DVAL(1.0),D3DVAL(1.0),D3DVAL(0.0),D3DVAL(1.0),D3DVAL(0.0),D3DVAL(1.0),D3DVAL(0.0) },
  87.   {D3DVAL(1.0),D3DVAL(1.0),D3DVAL(1.0),D3DVAL(0.0),D3DVAL(1.0),D3DVAL(0.0),D3DVAL(1.0),D3DVAL(1.0) },
  88.   {D3DVAL(1.0),D3DVAL(1.0),D3DVAL(-1.0),D3DVAL(0.0),D3DVAL(1.0),D3DVAL(0.0),D3DVAL(0.0),D3DVAL(1.0) },
  89.   {D3DVAL(-1.0),D3DVAL(1.0),D3DVAL(-1.0),D3DVAL(0.0),D3DVAL(1.0),D3DVAL(0.0),D3DVAL(0.0),D3DVAL(0.0) },
  90.  
  91.   {D3DVAL(1.0),D3DVAL(1.0),D3DVAL(-1.0),D3DVAL(0.0),D3DVAL(0.0),D3DVAL(-1.0),D3DVAL(1.0),D3DVAL(0.0) },
  92.   {D3DVAL(1.0),D3DVAL(-1.0),D3DVAL(-1.0),D3DVAL(0.0),D3DVAL(0.0),D3DVAL(-1.0),D3DVAL(1.0),D3DVAL(1.0) },
  93.   {D3DVAL(-1.0),D3DVAL(-1.0),D3DVAL(-1.0),D3DVAL(0.0),D3DVAL(0.0),D3DVAL(-1.0),D3DVAL(0.0),D3DVAL(1.0) },
  94.   {D3DVAL(-1.0),D3DVAL(1.0),D3DVAL(-1.0),D3DVAL(0.0),D3DVAL(0.0),D3DVAL(-1.0),D3DVAL(0.0),D3DVAL(0.0) },
  95.  
  96.   {D3DVAL(1.0),D3DVAL(1.0),D3DVAL(1.0),D3DVAL(1.0),D3DVAL(0.0),D3DVAL(0.0),D3DVAL(1.0),D3DVAL(0.0) },
  97.   {D3DVAL(1.0),D3DVAL(-1.0),D3DVAL(1.0),D3DVAL(1.0),D3DVAL(0.0),D3DVAL(0.0),D3DVAL(1.0),D3DVAL(1.0) },
  98.   {D3DVAL(1.0),D3DVAL(-1.0),D3DVAL(-1.0),D3DVAL(1.0),D3DVAL(0.0),D3DVAL(0.0),D3DVAL(0.0),D3DVAL(1.0) },
  99.   {D3DVAL(1.0),D3DVAL(1.0),D3DVAL(-1.0),D3DVAL(1.0),D3DVAL(0.0),D3DVAL(0.0),D3DVAL(0.0),D3DVAL(0.0) },
  100.  
  101.   {D3DVAL(-1.0),D3DVAL(1.0),D3DVAL(1.0),D3DVAL(0.0),D3DVAL(0.0),D3DVAL(1.0),D3DVAL(1.0),D3DVAL(0.0) },
  102.   {D3DVAL(-1.0),D3DVAL(-1.0),D3DVAL(1.0),D3DVAL(0.0),D3DVAL(0.0),D3DVAL(1.0),D3DVAL(1.0),D3DVAL(1.0) },
  103.   {D3DVAL(1.0),D3DVAL(-1.0),D3DVAL(1.0),D3DVAL(0.0),D3DVAL(0.0),D3DVAL(1.0),D3DVAL(0.0),D3DVAL(1.0) },
  104.   {D3DVAL(1.0),D3DVAL(1.0),D3DVAL(1.0),D3DVAL(0.0),D3DVAL(0.0),D3DVAL(1.0),D3DVAL(0.0),D3DVAL(0.0) },
  105.  
  106.   {D3DVAL(-1.0),D3DVAL(-1.0),D3DVAL(-1.0),D3DVAL(-1.0),D3DVAL(0.0),D3DVAL(0.0),D3DVAL(0.0),D3DVAL(1.0) },
  107.   {D3DVAL(-1.0),D3DVAL(-1.0),D3DVAL(1.0),D3DVAL(-1.0),D3DVAL(0.0),D3DVAL(0.0),D3DVAL(1.0),D3DVAL(1.0) },
  108.   {D3DVAL(-1.0),D3DVAL(1.0),D3DVAL(1.0),D3DVAL(-1.0),D3DVAL(0.0),D3DVAL(0.0),D3DVAL(1.0),D3DVAL(0.0) },
  109.   {D3DVAL(-1.0),D3DVAL(1.0),D3DVAL(-1.0),D3DVAL(-1.0),D3DVAL(0.0),D3DVAL(0.0),D3DVAL(0.0),D3DVAL(0.0) },
  110.   
  111.   {D3DVAL(1.0),D3DVAL(-1.0),D3DVAL(-1.0),D3DVAL(0.0),D3DVAL(-1.0),D3DVAL(0.0),D3DVAL(1.0),D3DVAL(1.0) },
  112.   {D3DVAL(1.0),D3DVAL(-1.0),D3DVAL(1.0),D3DVAL(0.0),D3DVAL(-1.0),D3DVAL(0.0),D3DVAL(0.0),D3DVAL(1.0) },
  113.   {D3DVAL(-1.0),D3DVAL(-1.0),D3DVAL(1.0),D3DVAL(0.0),D3DVAL(-1.0),D3DVAL(0.0),D3DVAL(0.0),D3DVAL(0.0) },
  114.   {D3DVAL(-1.0),D3DVAL(-1.0),D3DVAL(-1.0),D3DVAL(0.0),D3DVAL(-1.0),D3DVAL(0.0),D3DVAL(1.0),D3DVAL(0.0) }
  115. };
  116.  
  117. //*** Cube edges - ordered indices into the vertex array
  118. const int NumTri = 12;
  119. const int CubeTri[] = {
  120.    0,  1,  2,  0, 2, 3,
  121.    4,  5,  6,  4, 6, 7,
  122.    8,  9, 10, 8, 10, 11,
  123.   12, 13, 14, 12, 14, 15,
  124.   16, 17, 18, 16, 18, 19,
  125.   20, 21, 22, 20, 22, 23
  126. };
  127.  
  128. void
  129. OverrideDefaults(Defaults* defaults)
  130. {
  131.     lstrcpy(defaults->Name, "Flipcube D3D Example");
  132.     defaults->rs.ShadeMode = D3DSHADE_FLAT;
  133.     defaults->rs.bZBufferOn = FALSE;
  134.     defaults->bTexturesDisabled = TRUE;
  135. }
  136.  
  137. BOOL
  138. TickScene()
  139. {
  140.     if (GetAsyncKeyState(VK_LBUTTON) < 0) {
  141.         if(Move.x || Move.y) {
  142.             D3DMATRIX Movement;
  143.             Movement = identity;
  144.             ConcatenateYRotation(&Movement, (float)Move.x);
  145.             ConcatenateXRotation(&Movement, (float)Move.y);
  146.             Move.x = Move.y = 0;
  147.             MultiplyD3DMATRIX(&world, &world, &Movement);
  148.         }
  149.     } else {
  150.         MultiplyD3DMATRIX(&world, &spin, &world);
  151.     }
  152.     return TRUE;
  153. }
  154.  
  155. /*
  156.  * Each frame, renders the scene and calls mod_buffer to modify the object
  157.  * for the next frame.
  158.  */
  159. BOOL
  160. RenderScene(LPDIRECT3DDEVICE lpDev, LPDIRECT3DVIEWPORT lpView,
  161.             LPD3DRECT lpExtent)
  162. {
  163.     /*
  164.      * Execute the instruction buffer
  165.      */
  166.     if (lpDev->lpVtbl->SetMatrix(lpDev, hWorld, &world) != D3D_OK)
  167.         return FALSE;
  168.     if (lpDev->lpVtbl->BeginScene(lpDev) != D3D_OK)
  169.         return FALSE;
  170.     if (lpDev->lpVtbl->Execute(lpDev, lpD3DExBuf,
  171.                                lpView, D3DEXECUTE_CLIPPED) != D3D_OK)
  172.         return FALSE;
  173.     if (lpDev->lpVtbl->EndScene(lpDev) != D3D_OK)
  174.         return FALSE;
  175.     if (lpD3DExBuf->lpVtbl->GetExecuteData(lpD3DExBuf, &d3dExData)!= D3D_OK)
  176.         return FALSE;
  177.     *lpExtent = d3dExData.dsStatus.drExtent;
  178.     if (!(TickScene()))
  179.         return FALSE;
  180.     return TRUE;
  181. }
  182.  
  183. void
  184. InitSpin(void)
  185. {
  186.     spin = identity;
  187.     ConcatenateYRotation(&spin, D3DVAL(6.0));
  188.     ConcatenateXRotation(&spin, D3DVAL(3.5));
  189.     ConcatenateZRotation(&spin, D3DVAL(2.0));
  190. }
  191.  
  192. BOOL
  193. InitScene(void)
  194. {
  195.     world = identity;
  196.     InitSpin();
  197.     if (!(SetKeyboardCallback(KeyboardHandler)))
  198.         return FALSE;
  199.     if (!(SetMouseCallback(MouseHandler)))
  200.         return FALSE;
  201.     return TRUE;
  202. }
  203.  
  204. void
  205. ReleaseScene(void)
  206. {
  207.    
  208. }
  209.  
  210. /*
  211.  * Release the memory allocated for the scene and all D3D objects created.
  212.  */
  213. void
  214. ReleaseView(LPDIRECT3DVIEWPORT lpView)
  215. {
  216.     int i;
  217.     if (lpView)
  218.         lpView->lpVtbl->DeleteLight(lpView, lpD3DLight);
  219.     RELEASE(lpD3DLight);
  220.     RELEASE(lpD3DExBuf);
  221.  
  222.     RELEASE(lpBackgroundMaterial);
  223.     for (i = 0; i < 6; i++) {
  224.         RELEASE(lpD3DMaterial[i]);
  225.     }
  226. }
  227.  
  228. /*
  229.  * Builds the scene and initializes the execute buffer for rendering.  Returns 0 on failure.
  230.  */
  231. BOOL
  232. InitView(LPDIRECTDRAW lpDD, LPDIRECT3D lpD3D, LPDIRECT3DDEVICE lpDev,
  233.            LPDIRECT3DVIEWPORT lpView, int NumTextures,
  234.            LPD3DTEXTUREHANDLE TextureHandle)
  235. {
  236.     D3DMATERIAL MaterialDesc;
  237.     D3DMATERIALHANDLE BackgroundHandle;
  238.     D3DLIGHT LightDesc;
  239.     LPDIRECT3DEXECUTEBUFFER lpD3DExCmdBuf;
  240.     LPVOID lpBufStart, lpInsStart, lpPointer;
  241.     DWORD size;
  242.     int i;
  243.  
  244.     for (i = 0; i < 6; i++) {
  245.         if (lpD3D->lpVtbl->CreateMaterial(lpD3D, &lpD3DMaterial[i], NULL) != D3D_OK)
  246.            return FALSE;
  247.         memset(&MaterialDesc, 0, sizeof(D3DMATERIAL));
  248.         MaterialDesc.dwSize = sizeof(D3DMATERIAL);
  249.         MaterialDesc.diffuse.r = (D3DVALUE)(RGBA_GETRED(MaterialColors[i][0]) / 255.0);
  250.         MaterialDesc.diffuse.g = (D3DVALUE)(RGBA_GETGREEN(MaterialColors[i][0]) / 255.0);
  251.         MaterialDesc.diffuse.b = (D3DVALUE)(RGBA_GETBLUE(MaterialColors[i][0]) / 255.0);
  252.         MaterialDesc.diffuse.a = (D3DVALUE)(RGBA_GETALPHA(MaterialColors[i][0]) / 255.0);
  253.         MaterialDesc.ambient.r = (D3DVALUE)(RGBA_GETALPHA(MaterialColors[i][1]) / 255.0);
  254.         MaterialDesc.ambient.g = (D3DVALUE)(RGBA_GETALPHA(MaterialColors[i][1]) / 255.0);
  255.         MaterialDesc.ambient.b = (D3DVALUE)(RGBA_GETALPHA(MaterialColors[i][1]) / 255.0);
  256.         MaterialDesc.ambient.a = (D3DVALUE)(RGBA_GETALPHA(MaterialColors[i][1]) / 255.0);
  257.         MaterialDesc.specular.r = (D3DVALUE)1.0;
  258.         MaterialDesc.specular.g = (D3DVALUE)1.0;
  259.         MaterialDesc.specular.b = (D3DVALUE)1.0;
  260.         MaterialDesc.power = (float)20.0;
  261.         MaterialDesc.dwRampSize = 16;
  262.         MaterialDesc.hTexture = TextureHandle[1];
  263.         lpD3DMaterial[i]->lpVtbl->SetMaterial(lpD3DMaterial[i], &MaterialDesc);
  264.         lpD3DMaterial[i]->lpVtbl->GetHandle(lpD3DMaterial[i], lpDev,
  265.                                             &D3DMaterialHandle[i]);
  266.     }
  267.     /*
  268.      * Set background to black material
  269.      */
  270.     if (lpD3D->lpVtbl->CreateMaterial(lpD3D, &lpBackgroundMaterial, NULL) != D3D_OK)
  271.         return FALSE;
  272.     memset(&MaterialDesc, 0, sizeof(D3DMATERIAL));
  273.     MaterialDesc.dwSize = sizeof(D3DMATERIAL);
  274.     MaterialDesc.dwRampSize = 1;
  275.     lpBackgroundMaterial->lpVtbl->SetMaterial(lpBackgroundMaterial, &MaterialDesc);
  276.     lpBackgroundMaterial->lpVtbl->GetHandle(lpBackgroundMaterial, lpDev,
  277.                                             &BackgroundHandle);
  278.     lpView->lpVtbl->SetBackground(lpView, BackgroundHandle);
  279.     /*
  280.      * Add one directional light.
  281.      */
  282.     memset(&LightDesc, 0, sizeof(D3DLIGHT));
  283.     LightDesc.dwSize = sizeof(D3DLIGHT);
  284.     LightDesc.dltType = D3DLIGHT_POINT;
  285.     LightDesc.dcvColor.r = D3DVAL(0.9);
  286.     LightDesc.dcvColor.g = D3DVAL(0.9);
  287.     LightDesc.dcvColor.b = D3DVAL(0.9);
  288.     LightDesc.dcvColor.a = D3DVAL(1.0);
  289.     LightDesc.dvPosition.x = D3DVALP(0.0, 12);
  290.     LightDesc.dvPosition.y = D3DVALP(0.0, 12);
  291.     LightDesc.dvPosition.z = D3DVALP(-12.0, 12);
  292.     LightDesc.dvAttenuation0 = D3DVAL(1.0);
  293.     LightDesc.dvAttenuation1 = D3DVAL(0.0);
  294.     LightDesc.dvAttenuation2 = D3DVAL(0.0);
  295.  
  296. //    LightDesc.type = D3DLIGHT_DIRECTIONAL;
  297.     LightDesc.dvDirection.x = D3DVALP(0.0, 12);
  298.     LightDesc.dvDirection.y = D3DVALP(0.0, 12);
  299.     LightDesc.dvDirection.z = D3DVALP(1.0, 12);
  300.  
  301.     if (lpD3D->lpVtbl->CreateLight(lpD3D, &lpD3DLight, NULL) != D3D_OK)
  302.         return FALSE;
  303.     if (lpD3DLight->lpVtbl->SetLight(lpD3DLight, &LightDesc) != D3D_OK)
  304.         return FALSE;
  305.     if (lpView->lpVtbl->AddLight(lpView, lpD3DLight) != D3D_OK)
  306.         return FALSE;
  307.  
  308.     /*
  309.      * Set the view, world and projection matrices
  310.      * Create a buffer for matrix set commands etc.
  311.      */
  312.     MAKE_MATRIX(lpDev, hView, view);
  313.     MAKE_MATRIX(lpDev, hProj, proj);
  314.     MAKE_MATRIX(lpDev, hWorld, world);
  315.     size = 0;
  316.     size += sizeof(D3DINSTRUCTION) * 3;
  317.     size += sizeof(D3DSTATE) * 4;
  318.     memset(&debDesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
  319.     debDesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
  320.     debDesc.dwFlags = D3DDEB_BUFSIZE;
  321.     debDesc.dwBufferSize = size;
  322.     if (lpDev->lpVtbl->CreateExecuteBuffer(lpDev, &debDesc, &lpD3DExCmdBuf,
  323.                                          NULL) != D3D_OK)
  324.         return FALSE;
  325.  
  326.     /*
  327.      * lock it so it can be filled
  328.      */
  329.     if (lpD3DExCmdBuf->lpVtbl->Lock(lpD3DExCmdBuf, &debDesc) != D3D_OK)
  330.         return FALSE;
  331.     lpBufStart = debDesc.lpData;
  332.     memset(lpBufStart, 0, size);
  333.     lpPointer = lpBufStart;
  334.  
  335.     lpInsStart = lpPointer;
  336.     OP_STATE_TRANSFORM(3, lpPointer);
  337.         STATE_DATA(D3DTRANSFORMSTATE_PROJECTION, hProj, lpPointer);
  338.         STATE_DATA(D3DTRANSFORMSTATE_VIEW, hView, lpPointer);
  339.         STATE_DATA(D3DTRANSFORMSTATE_WORLD, hWorld, lpPointer);
  340.     OP_STATE_LIGHT(1, lpPointer);
  341.         STATE_DATA(D3DLIGHTSTATE_AMBIENT, AmbientColor, lpPointer);
  342.     OP_EXIT(lpPointer);
  343.     
  344.     /*
  345.      * Setup the execute data describing the buffer
  346.      */
  347.     lpD3DExCmdBuf->lpVtbl->Unlock(lpD3DExCmdBuf);
  348.     memset(&d3dExData, 0, sizeof(D3DEXECUTEDATA));
  349.     d3dExData.dwSize = sizeof(D3DEXECUTEDATA);
  350.     d3dExData.dwInstructionOffset = (ULONG) 0;
  351.     d3dExData.dwInstructionLength = (ULONG) ((char *)lpPointer - (char*)lpInsStart);
  352.     lpD3DExCmdBuf->lpVtbl->SetExecuteData(lpD3DExCmdBuf, &d3dExData);
  353.     lpDev->lpVtbl->BeginScene(lpDev);
  354.     lpDev->lpVtbl->Execute(lpDev, lpD3DExCmdBuf, lpView, D3DEXECUTE_UNCLIPPED);
  355.     lpDev->lpVtbl->EndScene(lpDev);
  356.  
  357.     /*
  358.      * We are done with the command buffer.
  359.      */
  360.     lpD3DExCmdBuf->lpVtbl->Release(lpD3DExCmdBuf);
  361.     /*
  362.      * Create an execute buffer
  363.      */
  364.     // calculate the size of the buffer
  365.     size = sizeof(D3DVERTEX) * NumVertices;
  366.     size += sizeof(D3DSTATUS) * 1;
  367.     size += sizeof(D3DPROCESSVERTICES) * 6;
  368.     size += sizeof(D3DINSTRUCTION) * 17;
  369.     size += sizeof(D3DSTATE) * 9;
  370.     size += sizeof(D3DTRIANGLE) * NumTri;
  371.     // Create an execute buffer
  372.     memset(&debDesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
  373.     debDesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
  374.     debDesc.dwFlags = D3DDEB_BUFSIZE;
  375.     debDesc.dwBufferSize = size;
  376.     if (lpDev->lpVtbl->CreateExecuteBuffer(lpDev, &debDesc, &lpD3DExBuf, NULL)
  377.         != D3D_OK)
  378.             return FALSE;
  379.     if (lpD3DExBuf->lpVtbl->Lock(lpD3DExBuf, &debDesc) != D3D_OK)
  380.         return FALSE;
  381.     lpBufStart = debDesc.lpData;
  382.     memset(lpBufStart, 0, size);
  383.     lpPointer = lpBufStart;
  384.  
  385.     VERTEX_DATA(&CubeVertices[0], NumVertices, lpPointer);
  386.  
  387.     lpInsStart = lpPointer;
  388.     OP_SET_STATUS(D3DSETSTATUS_ALL, D3DSTATUS_DEFAULT, 2048, 2048, 0, 0, lpPointer);
  389.     for (i = 0; i < 6; i++) {
  390.         OP_STATE_LIGHT(1, lpPointer);
  391.             STATE_DATA(D3DLIGHTSTATE_MATERIAL, D3DMaterialHandle[i], lpPointer);
  392.         OP_PROCESS_VERTICES(1, lpPointer);
  393.             PROCESSVERTICES_DATA(D3DPROCESSVERTICES_TRANSFORMLIGHT, i * 4, 4, lpPointer);
  394.     }
  395.     OP_STATE_RENDER(3, lpPointer);
  396.         STATE_DATA(D3DRENDERSTATE_TEXTUREHANDLE, TextureHandle[1], lpPointer);
  397.         STATE_DATA(D3DRENDERSTATE_WRAPU, FALSE, lpPointer);
  398.         STATE_DATA(D3DRENDERSTATE_WRAPV, FALSE, lpPointer);
  399.     /*
  400.      * Make sure that the triangle data (not OP) will be QWORD aligned
  401.      */
  402.     if (QWORD_ALIGNED(lpPointer)) {
  403.         OP_NOP(lpPointer);
  404.     }
  405.     OP_TRIANGLE_LIST(NumTri, lpPointer);
  406.     for (i = 0; i < NumTri; i++) {
  407.         ((LPD3DTRIANGLE)lpPointer)->v1 = CubeTri[i*3];
  408.         ((LPD3DTRIANGLE)lpPointer)->v2 = CubeTri[i*3 + 1];
  409.         ((LPD3DTRIANGLE)lpPointer)->v3 = CubeTri[i*3 + 2];
  410.         ((LPD3DTRIANGLE)lpPointer)->wFlags = D3DTRIFLAG_EDGEENABLETRIANGLE;
  411.         ((LPD3DTRIANGLE)lpPointer)++;
  412.     }
  413.     OP_EXIT(lpPointer);
  414.     /*
  415.      * Setup the execute data describing the buffer
  416.      */
  417.     lpD3DExBuf->lpVtbl->Unlock(lpD3DExBuf);
  418.     memset(&d3dExData, 0, sizeof(D3DEXECUTEDATA));
  419.     d3dExData.dwSize = sizeof(D3DEXECUTEDATA);
  420.     d3dExData.dwVertexCount = NumVertices;
  421.     d3dExData.dwInstructionOffset = (ULONG)((char*)lpInsStart - (char*)lpBufStart);
  422.     d3dExData.dwInstructionLength = (ULONG)((char*)lpPointer - (char*)lpInsStart);
  423.     lpD3DExBuf->lpVtbl->SetExecuteData(lpD3DExBuf, &d3dExData);
  424.  
  425.     return TRUE;
  426. }
  427.  
  428. /****************************************************************************
  429.   Keyboard and mouse handlers
  430.  ****************************************************************************/
  431.  
  432. BOOL
  433. KeyboardHandler(UINT message, WPARAM wParam, LPARAM lParam) {
  434.     D3DMATRIX m;
  435.     if (message == WM_KEYDOWN) {
  436.         if ((int)wParam == VK_F11) {
  437.             m = identity;
  438.             m._11 = D3DVAL(1.5);
  439.             m._22 = D3DVAL(1.5);
  440.             m._33 = D3DVAL(1.5);
  441.             MultiplyD3DMATRIX(&world, &world,  &m);
  442.             return TRUE;
  443.         } else if ((int)wParam == VK_F12) {
  444.             m = identity;
  445.             m._11 = D3DVAL(0.9);
  446.             m._22 = D3DVAL(0.9);
  447.             m._33 = D3DVAL(0.9);
  448.             MultiplyD3DMATRIX(&world, &world, &m);
  449.             return TRUE;
  450.         }
  451.     }
  452.     return FALSE;
  453. }
  454.  
  455. BOOL
  456. MouseHandler(UINT message, WPARAM wParam, LPARAM lParam) {
  457.     if (message == WM_LBUTTONDOWN) {
  458.         /* Get the start location for mouse rotations */
  459.         spin = identity;
  460.         Last.x = LOWORD(lParam);
  461.         Last.y = HIWORD(lParam);
  462.         return TRUE;
  463.     } else if (message == WM_RBUTTONDOWN) {
  464.         /* start spinning again */
  465.         InitSpin();
  466.         return TRUE;
  467.     } else if (message == WM_MOUSEMOVE) {
  468.         /* While the mouse button is down, keep track of movement
  469.          * to update the eye position
  470.          */
  471.         if(GetKeyState(VK_LBUTTON) < 0) {
  472.             Move.x = (int)LOWORD(lParam) - Last.x;
  473.             Move.y = (int)HIWORD(lParam) - Last.y;
  474.             Last.x = LOWORD(lParam);
  475.             Last.y = HIWORD(lParam);
  476.             return TRUE;
  477.         }
  478.     }
  479.     return FALSE;
  480. }
  481.  
  482. /**************************************************************************
  483.   TransformCube
  484.  
  485.   Description:
  486.     Multiplies the world matrix by the given transform matrix
  487.  **************************************************************************/
  488.  
  489. /*****************************************************************************
  490.   Rotatations
  491.  *****************************************************************************/
  492. #define M_PI            3.14159265358979323846
  493. void
  494. ConcatenateXRotation(LPD3DMATRIX lpM, float Degrees )
  495. {
  496.   float Temp01, Temp11, Temp21, Temp31;
  497.   float Temp02, Temp12, Temp22, Temp32;
  498.   float aElements[4][4];
  499.  
  500.   float Radians = (float)((Degrees/360) * M_PI * 2.0);
  501.  
  502.   float Sin = (float)sin(Radians), Cos = (float)cos(Radians);
  503.  
  504.   memcpy(aElements, lpM, sizeof(D3DMATRIX));
  505.   Temp01 = aElements[0][1] * Cos + aElements[0][2] * Sin;
  506.   Temp11 = aElements[1][1] * Cos + aElements[1][2] * Sin;
  507.   Temp21 = aElements[2][1] * Cos + aElements[2][2] * Sin;
  508.   Temp31 = aElements[3][1] * Cos + aElements[3][2] * Sin;
  509.  
  510.   Temp02 = aElements[0][1] * -Sin + aElements[0][2] * Cos;
  511.   Temp12 = aElements[1][1] * -Sin + aElements[1][2] * Cos;
  512.   Temp22 = aElements[2][1] * -Sin + aElements[2][2] * Cos;
  513.   Temp32 = aElements[3][1] * -Sin + aElements[3][2] * Cos;
  514.  
  515.   lpM->_12 = Temp01;
  516.   lpM->_22 = Temp11;
  517.   lpM->_32 = Temp21;
  518.   lpM->_42 = Temp31;
  519.   lpM->_13 = Temp02;
  520.   lpM->_23 = Temp12;
  521.   lpM->_33 = Temp22;
  522.   lpM->_43 = Temp32;
  523. }
  524.  
  525. void
  526. ConcatenateYRotation(LPD3DMATRIX lpM, float Degrees )
  527. {
  528.   float Temp00, Temp10, Temp20, Temp30;
  529.   float Temp02, Temp12, Temp22, Temp32;
  530.   float aElements[4][4];
  531.  
  532.   float Radians = (float)((Degrees/360) * M_PI * 2);
  533.  
  534.   float Sin = (float)sin(Radians), Cos = (float)cos(Radians);
  535.  
  536.   memcpy(aElements, lpM, sizeof(D3DMATRIX));
  537.   Temp00 = aElements[0][0] * Cos + aElements[0][2] * -Sin;
  538.   Temp10 = aElements[1][0] * Cos + aElements[1][2] * -Sin;
  539.   Temp20 = aElements[2][0] * Cos + aElements[2][2] * -Sin;
  540.   Temp30 = aElements[3][0] * Cos + aElements[3][2] * -Sin;
  541.  
  542.   Temp02 = aElements[0][0] * Sin + aElements[0][2] * Cos;
  543.   Temp12 = aElements[1][0] * Sin + aElements[1][2] * Cos;
  544.   Temp22 = aElements[2][0] * Sin + aElements[2][2] * Cos;
  545.   Temp32 = aElements[3][0] * Sin + aElements[3][2] * Cos;
  546.  
  547.   lpM->_11 = Temp00;
  548.   lpM->_21 = Temp10;
  549.   lpM->_31 = Temp20;
  550.   lpM->_41 = Temp30;
  551.   lpM->_13 = Temp02;
  552.   lpM->_23 = Temp12;
  553.   lpM->_33 = Temp22;
  554.   lpM->_43 = Temp32;
  555. }
  556.  
  557. void
  558. ConcatenateZRotation(LPD3DMATRIX lpM, float Degrees )
  559. {
  560.   float Temp00, Temp10, Temp20, Temp30;
  561.   float Temp01, Temp11, Temp21, Temp31;
  562.   float aElements[4][4];
  563.  
  564.   float Radians = (float)((Degrees/360) * M_PI * 2);
  565.  
  566.   float Sin = (float)sin(Radians), Cos = (float)cos(Radians);
  567.  
  568.   memcpy(aElements, lpM, sizeof(D3DMATRIX));
  569.   Temp00 = aElements[0][0] * Cos + aElements[0][1] * Sin;
  570.   Temp10 = aElements[1][0] * Cos + aElements[1][1] * Sin;
  571.   Temp20 = aElements[2][0] * Cos + aElements[2][1] * Sin;
  572.   Temp30 = aElements[3][0] * Cos + aElements[3][1] * Sin;
  573.  
  574.   Temp01 = aElements[0][0] * -Sin + aElements[0][1] * Cos;
  575.   Temp11 = aElements[1][0] * -Sin + aElements[1][1] * Cos;
  576.   Temp21 = aElements[2][0] * -Sin + aElements[2][1] * Cos;
  577.   Temp31 = aElements[3][0] * -Sin + aElements[3][1] * Cos;
  578.  
  579.   lpM->_11 = Temp00;
  580.   lpM->_21 = Temp10;
  581.   lpM->_31 = Temp20;
  582.   lpM->_41 = Temp30;
  583.   lpM->_12 = Temp01;
  584.   lpM->_22 = Temp11;
  585.   lpM->_32 = Temp21;
  586.   lpM->_42 = Temp31;
  587. }
  588.