home *** CD-ROM | disk | FTP | other *** search
/ NEXT Generation 27 / NEXT27.iso / pc / demos / emperor / dx3.exe / SDK / SAMPLES / OCT1 / OCT1.C < prev    next >
C/C++ Source or Header  |  1996-08-28  |  15KB  |  471 lines

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995, 1996 Microsoft Corporation. All Rights Reserved.
  4.  *
  5.  *  File: oct1.c
  6.  *
  7.  ***************************************************************************/
  8.  
  9. #include <d3d.h>
  10. #include <math.h>
  11. #include "d3ddemo.h"
  12.  
  13. static D3DEXECUTEDATA d3dExData;
  14. static LPDIRECT3DEXECUTEBUFFER lpD3DExBuf;
  15. static D3DEXECUTEBUFFERDESC debDesc;
  16. LPDIRECT3DLIGHT lpD3DLight;
  17. LPDIRECT3DMATERIAL lpBmat, lpMat1, lpMat2;
  18.  
  19. extern LPD3DVECTOR D3DVECTORNormalise(LPD3DVECTOR);
  20.  
  21. /*
  22.  * Global projection, view, world and identity matricies
  23.  */
  24. D3DMATRIXHANDLE hProj;
  25. D3DMATRIXHANDLE hView;
  26. D3DMATRIXHANDLE hViewRot, hDViewRot;
  27. D3DMATRIXHANDLE hViewPos;
  28. D3DMATRIXHANDLE hWorld, hDWorld;
  29.  
  30. D3DMATRIX proj = {
  31.     D3DVAL(2.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0),
  32.     D3DVAL(0.0), D3DVAL(2.0), D3DVAL(0.0), D3DVAL(0.0),
  33.     D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1.0), D3DVAL(1.0),
  34.     D3DVAL(0.0), D3DVAL(0.0), D3DVAL(-1.0), D3DVAL(0.0)
  35. };
  36.  
  37. D3DMATRIX viewpos = {
  38.     D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0),
  39.     D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0),
  40.     D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0),
  41.     D3DVAL(0.0), D3DVAL(0.0), D3DVAL(10.0), D3DVAL(1.0)
  42. };
  43. D3DMATRIX viewrot, view, dviewrot, dworld;
  44. D3DMATRIX identity = {
  45.     D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0),
  46.     D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0),
  47.     D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0),
  48.     D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1.0)
  49. };
  50.  
  51. void
  52. OverrideDefaults(Defaults* defaults)
  53. {
  54.     lstrcpy(defaults->Name, "Octagon D3D Example");
  55. }
  56.  
  57. BOOL
  58. TickScene(LPDIRECT3DDEVICE lpDev, LPDIRECT3DVIEWPORT lpView)
  59. {
  60.     static int dir = 1;
  61.  
  62.     if (viewpos._43 < D3DVAL(4.0))
  63.         dir = 0;
  64.     if (viewpos._43 > D3DVAL(12.0))
  65.         dir = 1;
  66.     if (dir) 
  67.         viewpos._43 -= D3DVAL(0.4);
  68.     else 
  69.         viewpos._43 += D3DVAL(0.4);
  70.     if (lpDev->lpVtbl->SetMatrix(lpDev, hViewPos, &viewpos) != D3D_OK)
  71.         return FALSE;
  72.     return TRUE;
  73. }
  74.  
  75. BOOL
  76. RenderScene(LPDIRECT3DDEVICE lpDev, LPDIRECT3DVIEWPORT lpView,
  77.             LPD3DRECT lpExtent)
  78. {
  79.     /*
  80.      * Execute the instruction buffer
  81.      */
  82.     if (lpDev->lpVtbl->BeginScene(lpDev) != D3D_OK)
  83.         return FALSE;
  84.     if (lpDev->lpVtbl->Execute(lpDev, lpD3DExBuf, lpView, D3DEXECUTE_CLIPPED) != D3D_OK)
  85.         return FALSE;
  86.     if (lpDev->lpVtbl->EndScene(lpDev) != D3D_OK)
  87.         return FALSE;
  88.     if (lpD3DExBuf->lpVtbl->GetExecuteData(lpD3DExBuf, &d3dExData) != D3D_OK)
  89.         return FALSE;
  90.     *lpExtent = d3dExData.dsStatus.drExtent;
  91.     if (!(TickScene(lpDev, lpView)))
  92.         return FALSE;
  93.     return TRUE;
  94. }
  95.  
  96. void
  97. ReleaseScene(void)
  98. {
  99.     return;
  100. }
  101.  
  102. void
  103. ReleaseView(LPDIRECT3DVIEWPORT lpView)
  104. {
  105.     if (lpView && lpD3DLight)
  106.         lpView->lpVtbl->DeleteLight(lpView, lpD3DLight);
  107.     RELEASE(lpD3DLight);
  108.     RELEASE(lpD3DExBuf);
  109.     RELEASE(lpMat2);
  110.     RELEASE(lpBmat);
  111. }
  112.  
  113. BOOL
  114. InitScene(void)
  115. {
  116.     return TRUE;
  117. }
  118.  
  119. #define NUM_VERTICES 6
  120. #define NUM_TRIANGLES 8
  121.  
  122. BOOL
  123. InitView(LPDIRECTDRAW lpDD, LPDIRECT3D lpD3D, LPDIRECT3DDEVICE lpDev, 
  124.            LPDIRECT3DVIEWPORT lpView, int NumTextures,
  125.            LPD3DTEXTUREHANDLE TextureHandle)
  126. {
  127.     D3DVERTEX v[NUM_VERTICES];
  128.     D3DLIGHT light;
  129.     LPVOID lpBufStart, lpInsStart, lpPointer;
  130.     LPD3DTRIANGLE lpTri;
  131.     LPDIRECT3DEXECUTEBUFFER lpD3DExCmdBuf;
  132.     size_t size;
  133.     int t[8][3] = {
  134.         0, 1, 2,
  135.         0, 2, 3,
  136.         0, 3, 4,
  137.         0, 4, 1,
  138.         5, 2, 1,
  139.         5, 3, 2,
  140.         5, 4, 3,
  141.         5, 1, 4
  142.     };
  143.     D3DMATERIAL bmat, mat1, mat2;
  144.     D3DMATERIALHANDLE hBmat, hMat1, hMat2;
  145.     D3DTEXTUREHANDLE bTex;
  146.     D3DTEXTUREHANDLE fooTex;
  147.     int i;
  148.     D3DVALUE ct, st;
  149.  
  150.     bTex = TextureHandle[1];
  151.     fooTex = TextureHandle[0];
  152.     memset(&bmat, 0, sizeof(D3DMATERIAL));
  153.     bmat.dwSize = sizeof(D3DMATERIAL);
  154.     bmat.diffuse.r = (D3DVALUE)1.0;
  155.     bmat.diffuse.g = (D3DVALUE)1.0;
  156.     bmat.diffuse.b = (D3DVALUE)1.0;
  157.     bmat.ambient.r = (D3DVALUE)1.0;
  158.     bmat.ambient.g = (D3DVALUE)1.0;
  159.     bmat.ambient.b = (D3DVALUE)1.0;
  160.     bmat.hTexture = fooTex;
  161.     bmat.dwRampSize = 1;
  162.     if (lpD3D->lpVtbl->CreateMaterial(lpD3D, &lpBmat, NULL) != D3D_OK) {
  163.         return FALSE;
  164.     }
  165.     if (lpBmat->lpVtbl->SetMaterial(lpBmat, &bmat) != D3D_OK) {
  166.         return FALSE;
  167.     }
  168.     if (lpBmat->lpVtbl->GetHandle(lpBmat, lpDev, &hBmat) != D3D_OK) {
  169.         return FALSE;
  170.     }
  171.     if (lpView->lpVtbl->SetBackground(lpView, hBmat) != D3D_OK) {
  172.         return FALSE;
  173.     }
  174.  
  175.     /*
  176.      * Set the view, world and projection matrices
  177.      * Create a buffer for matrix set commands etc.
  178.      */
  179.     MAKE_MATRIX(lpDev, hViewRot, identity);
  180.     MAKE_MATRIX(lpDev, hViewPos, viewpos);
  181.     MAKE_MATRIX(lpDev, hView, identity);
  182.     MAKE_MATRIX(lpDev, hProj, proj);
  183.     MAKE_MATRIX(lpDev, hWorld, identity);
  184.     ct = D3DVAL(cos(0.1));
  185.     st = D3DVAL(sin(0.1));
  186.     dviewrot = identity;
  187.     dviewrot._22 = ct;
  188.     dviewrot._23 = -st;
  189.     dviewrot._32 = st;
  190.     dviewrot._33 = ct;
  191.     MAKE_MATRIX(lpDev, hDViewRot, dviewrot);
  192.     dworld = identity;
  193.     dworld._11 = ct;
  194.     dworld._13 = -st;
  195.     dworld._31 = st;
  196.     dworld._33 = ct;
  197.     MAKE_MATRIX(lpDev, hDWorld, dworld);
  198.     size = 0;
  199.     size += sizeof(D3DINSTRUCTION) * 3;
  200.     size += sizeof(D3DSTATE) * 4;
  201.     memset(&debDesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
  202.     debDesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
  203.     debDesc.dwFlags = D3DDEB_BUFSIZE;
  204.     debDesc.dwBufferSize = size;
  205.     if (lpDev->lpVtbl->CreateExecuteBuffer(lpDev, &debDesc, &lpD3DExCmdBuf,
  206.                                            NULL) != D3D_OK)
  207.         return FALSE;
  208.     /*
  209.      * lock it so it can be filled
  210.      */
  211.     if (lpD3DExCmdBuf->lpVtbl->Lock(lpD3DExCmdBuf, &debDesc) != D3D_OK)
  212.         return FALSE;
  213.     lpBufStart = debDesc.lpData;
  214.     memset(lpBufStart, 0, size);
  215.     lpPointer = lpBufStart;
  216.  
  217.     lpInsStart = lpPointer;
  218.     OP_STATE_TRANSFORM(3, lpPointer);
  219.         STATE_DATA(D3DTRANSFORMSTATE_VIEW, hView, lpPointer);
  220.         STATE_DATA(D3DTRANSFORMSTATE_WORLD, hWorld, lpPointer);
  221.         STATE_DATA(D3DTRANSFORMSTATE_PROJECTION, hProj, lpPointer);
  222.     OP_STATE_LIGHT(1, lpPointer);
  223.         STATE_DATA(D3DLIGHTSTATE_AMBIENT, RGBA_MAKE(64, 64, 64, 64), lpPointer);
  224.     OP_EXIT(lpPointer);
  225.     /*
  226.      * Setup the execute data describing the buffer
  227.      */
  228.     lpD3DExCmdBuf->lpVtbl->Unlock(lpD3DExCmdBuf);
  229.     memset(&d3dExData, 0, sizeof(D3DEXECUTEDATA));
  230.     d3dExData.dwSize = sizeof(D3DEXECUTEDATA);
  231.     d3dExData.dwInstructionOffset = (ULONG) 0;
  232.     d3dExData.dwInstructionLength = (ULONG) ((char *)lpPointer - (char*)lpInsStart);
  233.     lpD3DExCmdBuf->lpVtbl->SetExecuteData(lpD3DExCmdBuf, &d3dExData);
  234.     lpDev->lpVtbl->BeginScene(lpDev);
  235.     lpDev->lpVtbl->Execute(lpDev, lpD3DExCmdBuf, lpView, D3DEXECUTE_UNCLIPPED);
  236.     lpDev->lpVtbl->EndScene(lpDev);
  237.     /*
  238.      * We are done with the command buffer.
  239.      */
  240.     lpD3DExCmdBuf->lpVtbl->Release(lpD3DExCmdBuf);
  241.     /*
  242.      * Setup a material
  243.      */
  244.     if (lpD3D->lpVtbl->CreateMaterial(lpD3D, &lpMat1, NULL) != D3D_OK) {
  245.         return FALSE;
  246.     }
  247.     if (lpD3D->lpVtbl->CreateMaterial(lpD3D, &lpMat2, NULL) != D3D_OK) {
  248.         return FALSE;
  249.     }
  250.     memset(&mat1, 0, sizeof(D3DMATERIAL));
  251.     mat1.dwSize = sizeof(D3DMATERIAL);
  252.     
  253.     mat1.diffuse.r = (D3DVALUE)1.0;
  254.     mat1.diffuse.g = (D3DVALUE)0.0;
  255.     mat1.diffuse.b = (D3DVALUE)0.0;
  256.     mat1.diffuse.a = (D3DVALUE)1.0;
  257.     mat1.ambient.r = (D3DVALUE)1.0;
  258.     mat1.ambient.g = (D3DVALUE)0.0;
  259.     mat1.ambient.b = (D3DVALUE)0.0;
  260.     mat1.specular.r = (D3DVALUE)1.0;
  261.     mat1.specular.g = (D3DVALUE)1.0;
  262.     mat1.specular.b = (D3DVALUE)1.0;
  263.     mat1.power = (float)20.0;
  264.     mat1.dwRampSize = 16;
  265.     mat1.hTexture = bTex;
  266.     lpMat1->lpVtbl->SetMaterial(lpMat1, &mat1);
  267.     lpMat1->lpVtbl->GetHandle(lpMat1, lpDev, &hMat1);
  268.     memset(&mat2, 0, sizeof(D3DMATERIAL));
  269.     mat2.dwSize = sizeof(D3DMATERIAL);
  270.     mat2.diffuse.r = (D3DVALUE)1.0;
  271.     mat2.diffuse.g = (D3DVALUE)1.0;
  272.     mat2.diffuse.b = (D3DVALUE)1.0;
  273.     mat2.diffuse.a = (D3DVALUE)1.0;
  274.     mat2.ambient.r = (D3DVALUE)1.0;
  275.     mat2.ambient.g = (D3DVALUE)1.0;
  276.     mat2.ambient.b = (D3DVALUE)1.0;
  277.     mat2.specular.r = (D3DVALUE)1.0;
  278.     mat2.specular.g = (D3DVALUE)1.0;
  279.     mat2.specular.b = (D3DVALUE)1.0;
  280.     mat2.power = (float)20.0;
  281.     mat2.dwRampSize = 16;
  282.     mat2.hTexture = bTex;
  283.     lpMat2->lpVtbl->SetMaterial(lpMat2, &mat2);
  284.     lpMat2->lpVtbl->GetHandle(lpMat2, lpDev, &hMat2);
  285.     /*
  286.      * Setup vertices
  287.      */
  288.     memset(&v[0], 0, sizeof(D3DVERTEX) * NUM_VERTICES);
  289.     /* V 0 */
  290.     v[0].x = D3DVALP(0.0, 12);
  291.     v[0].y = D3DVALP(1.0, 12);
  292.     v[0].z = D3DVALP(1.0, 12);
  293.  
  294.     v[0].nx = D3DVALP(0.0, 12);
  295.     v[0].ny = D3DVALP(1.0, 12);
  296.     v[0].nz = D3DVALP(0.0, 12);
  297.  
  298.     v[0].tu = D3DVAL(0.0);
  299.     v[0].tv = D3DVAL(0.0);
  300.  
  301.     /* V 1 */
  302.     v[1].x = D3DVALP(1.0, 12);
  303.     v[1].y = D3DVALP(0.0, 12);
  304.     v[1].z = D3DVALP(0.0, 12);
  305.  
  306.     v[1].nx = D3DVALP(1.0, 12);
  307.     v[1].ny = D3DVALP(0.0, 12);
  308.     v[1].nz = D3DVALP(-1.0, 12);
  309.  
  310.     v[1].tu = D3DVAL(1.0);
  311.     v[1].tv = D3DVAL(1.0);
  312.  
  313.     D3DVECTORNormalise((LPD3DVECTOR) & v[1].nx);
  314.  
  315.     /* V 2 */
  316.     v[2].x = D3DVALP(-1.0, 12);
  317.     v[2].y = D3DVALP(0.0, 12);
  318.     v[2].z = D3DVALP(0.0, 12);
  319.  
  320.     v[2].nx = D3DVALP(-1.0, 12);
  321.     v[2].ny = D3DVALP(0.0, 12);
  322.     v[2].nz = D3DVALP(-1.0, 12);
  323.  
  324.     v[2].tu = D3DVAL(0.0);
  325.     v[2].tv = D3DVAL(1.0);
  326.  
  327.     D3DVECTORNormalise((LPD3DVECTOR) & v[2].nx);
  328.  
  329.     /* V 3 */
  330.     v[3].x = D3DVALP(-1.0, 12);
  331.     v[3].y = D3DVALP(0.0, 12);
  332.     v[3].z = D3DVALP(2.0, 12);
  333.  
  334.     v[3].nx = D3DVALP(-1.0, 12);
  335.     v[3].ny = D3DVALP(0.0, 12);
  336.     v[3].nz = D3DVALP(1.0, 12);
  337.  
  338.     v[3].tu = D3DVAL(1.0);
  339.     v[3].tv = D3DVAL(1.0);
  340.  
  341.     D3DVECTORNormalise((LPD3DVECTOR) & v[3].nx);
  342.  
  343.     /* V 4 */
  344.     v[4].x = D3DVALP(1.0, 12);
  345.     v[4].y = D3DVALP(0.0, 12);
  346.     v[4].z = D3DVALP(2.0, 12);
  347.  
  348.     v[4].nx = D3DVALP(1.0, 12);
  349.     v[4].ny = D3DVALP(0.0, 12);
  350.     v[4].nz = D3DVALP(1.0, 12);
  351.  
  352.     v[4].tu = D3DVAL(0.0);
  353.     v[4].tv = D3DVAL(1.0);
  354.  
  355.     D3DVECTORNormalise((LPD3DVECTOR) & v[4].nx);
  356.  
  357.     /* V 5 */
  358.     v[5].x = D3DVALP(0.0, 12);
  359.     v[5].y = D3DVALP(-1.0, 12);
  360.     v[5].z = D3DVALP(1.0, 12);
  361.  
  362.     v[5].nx = D3DVALP(0.0, 12);
  363.     v[5].ny = D3DVALP(-1.0, 12);
  364.     v[5].nz = D3DVALP(0.0, 12);
  365.  
  366.     v[5].tu = D3DVAL(0.0);
  367.     v[5].tv = D3DVAL(0.0);
  368.  
  369.     D3DVECTORNormalise((LPD3DVECTOR) & v[5].nx);
  370.  
  371.     /*
  372.      * Create an execute buffer
  373.      */
  374.     size = sizeof(D3DVERTEX) * NUM_VERTICES;
  375.     size += sizeof(D3DSTATUS) * 1;
  376.     size += sizeof(D3DPROCESSVERTICES) * 2;
  377.     size += sizeof(D3DINSTRUCTION) * 10;
  378.     size += sizeof(D3DMATRIXMULTIPLY) * 3;
  379.     size += sizeof(D3DSTATE) * 5;
  380.     size += sizeof(D3DTRIANGLE) * NUM_TRIANGLES;
  381.     memset(&debDesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
  382.     debDesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
  383.     debDesc.dwFlags = D3DDEB_BUFSIZE;
  384.     debDesc.dwBufferSize = size;
  385.     if (lpDev->lpVtbl->CreateExecuteBuffer(lpDev, &debDesc, &lpD3DExBuf,
  386.                                            NULL) != D3D_OK) {
  387.         return FALSE;
  388.     }
  389.     if (lpD3DExBuf->lpVtbl->Lock(lpD3DExBuf, &debDesc) != D3D_OK) {
  390.         return FALSE;
  391.     }
  392.     lpBufStart = debDesc.lpData;
  393.     memset(lpBufStart, 0, size);
  394.     lpPointer = lpBufStart;
  395.     /*
  396.      * Copy vertices to execute buffer
  397.      */
  398.     VERTEX_DATA(&v[0], NUM_VERTICES, lpPointer);
  399.     /*
  400.      * Setup instructions in execute buffer
  401.      */
  402.     lpInsStart = lpPointer;
  403.     OP_MATRIX_MULTIPLY(3, lpPointer);
  404.         MATRIX_MULTIPLY_DATA(hViewRot, hDViewRot, hViewRot, lpPointer);
  405.         MATRIX_MULTIPLY_DATA(hViewRot, hViewPos, hView, lpPointer);
  406.         MATRIX_MULTIPLY_DATA(hWorld, hDWorld, hWorld, lpPointer);
  407.     OP_STATE_LIGHT(1, lpPointer);
  408.         STATE_DATA(D3DLIGHTSTATE_MATERIAL, hMat1, lpPointer);
  409.     OP_SET_STATUS(D3DSETSTATUS_ALL, D3DSTATUS_DEFAULT, 2048, 2048, 0, 0, lpPointer);
  410.     OP_PROCESS_VERTICES(1, lpPointer);
  411.         PROCESSVERTICES_DATA(D3DPROCESSVERTICES_TRANSFORMLIGHT, 0, 5, lpPointer);
  412.     OP_STATE_LIGHT(1, lpPointer);
  413.         STATE_DATA(D3DLIGHTSTATE_MATERIAL, hMat2, lpPointer);
  414.     OP_PROCESS_VERTICES(1, lpPointer);
  415.         PROCESSVERTICES_DATA(D3DPROCESSVERTICES_TRANSFORMLIGHT, 5, 1, lpPointer);
  416.     OP_STATE_RENDER(3, lpPointer);
  417.         STATE_DATA(D3DRENDERSTATE_TEXTUREHANDLE, bTex, lpPointer);
  418.         STATE_DATA(D3DRENDERSTATE_WRAPU, FALSE, lpPointer);
  419.         STATE_DATA(D3DRENDERSTATE_WRAPV, FALSE, lpPointer);
  420.     /*
  421.      * Make sure that the triangle data (not OP) will be QWORD aligned
  422.      */
  423.     if (QWORD_ALIGNED(lpPointer)) {
  424.         OP_NOP(lpPointer);
  425.     }
  426.     OP_TRIANGLE_LIST(NUM_TRIANGLES, lpPointer);
  427.         lpTri = (LPD3DTRIANGLE)lpPointer;
  428.         for (i = 0; i < NUM_TRIANGLES; i++) {
  429.             lpTri->v1 = t[i][0];
  430.             lpTri->v2 = t[i][1];
  431.             lpTri->v3 = t[i][2];
  432.             lpTri->wFlags = D3DTRIFLAG_EDGEENABLETRIANGLE;
  433.             lpTri++;
  434.         }
  435.         lpPointer = (void*)lpTri;
  436.     OP_EXIT(lpPointer);
  437.     /*
  438.      * Setup the execute data
  439.      */
  440.     lpD3DExBuf->lpVtbl->Unlock(lpD3DExBuf);
  441.     memset(&d3dExData, 0, sizeof(D3DEXECUTEDATA));
  442.     d3dExData.dwSize = sizeof(D3DEXECUTEDATA);
  443.     d3dExData.dwVertexCount = NUM_VERTICES;
  444.     d3dExData.dwInstructionOffset = (ULONG) ((char *)lpInsStart - (char *)lpBufStart);
  445.     d3dExData.dwInstructionLength = (ULONG) ((char *)lpPointer - (char*)lpInsStart);
  446.     lpD3DExBuf->lpVtbl->SetExecuteData(lpD3DExBuf, &d3dExData);
  447.     /*
  448.      * Setup lights
  449.      */
  450.     memset(&light, 0, sizeof(D3DLIGHT));
  451.     light.dwSize = sizeof(D3DLIGHT);
  452.     light.dltType = D3DLIGHT_DIRECTIONAL;
  453.     light.dcvColor.r = D3DVAL(1.0);
  454.     light.dcvColor.g = D3DVAL(1.0);
  455.     light.dcvColor.b = D3DVAL(1.0);
  456.     light.dcvColor.a = D3DVAL(1.0);
  457.     light.dvDirection.x = D3DVALP(0.0, 12);
  458.     light.dvDirection.y = D3DVALP(0.0, 12);
  459.     light.dvDirection.z = D3DVALP(1.0, 12);
  460.     if (lpD3D->lpVtbl->CreateLight(lpD3D, &lpD3DLight, NULL) != D3D_OK) {
  461.         return FALSE;
  462.     }
  463.     if (lpD3DLight->lpVtbl->SetLight(lpD3DLight, &light) != D3D_OK) {
  464.         return FALSE;
  465.     }
  466.     if (lpView->lpVtbl->AddLight(lpView, lpD3DLight) != D3D_OK) {
  467.         return FALSE;
  468.     }
  469.     return TRUE;
  470. }
  471.