home *** CD-ROM | disk | FTP | other *** search
/ The Net: Ultimate Internet Guide / WWLCD1.ISO / pc / directx2 / sdk / samples / oct1 / oct1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-28  |  14.3 KB  |  473 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)
  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.     if (NumTextures < 2)
  151.         return FALSE;
  152.     bTex = TextureHandle[1];
  153.     fooTex = TextureHandle[0];
  154.     memset(&bmat, 0, sizeof(D3DMATERIAL));
  155.     bmat.dwSize = sizeof(D3DMATERIAL);
  156.     bmat.diffuse.r = (D3DVALUE)1.0;
  157.     bmat.diffuse.g = (D3DVALUE)1.0;
  158.     bmat.diffuse.b = (D3DVALUE)1.0;
  159.     bmat.ambient.r = (D3DVALUE)1.0;
  160.     bmat.ambient.g = (D3DVALUE)1.0;
  161.     bmat.ambient.b = (D3DVALUE)1.0;
  162.     bmat.hTexture = fooTex;
  163.     bmat.dwRampSize = 1;
  164.     if (lpD3D->lpVtbl->CreateMaterial(lpD3D, &lpBmat, NULL) != D3D_OK) {
  165.         return FALSE;
  166.     }
  167.     if (lpBmat->lpVtbl->SetMaterial(lpBmat, &bmat) != D3D_OK) {
  168.         return FALSE;
  169.     }
  170.     if (lpBmat->lpVtbl->GetHandle(lpBmat, lpDev, &hBmat) != D3D_OK) {
  171.         return FALSE;
  172.     }
  173.     if (lpView->lpVtbl->SetBackground(lpView, hBmat) != D3D_OK) {
  174.         return FALSE;
  175.     }
  176.  
  177.     /*
  178.      * Set the view, world and projection matrices
  179.      * Create a buffer for matrix set commands etc.
  180.      */
  181.     MAKE_MATRIX(lpDev, hViewRot, identity);
  182.     MAKE_MATRIX(lpDev, hViewPos, viewpos);
  183.     MAKE_MATRIX(lpDev, hView, identity);
  184.     MAKE_MATRIX(lpDev, hProj, proj);
  185.     MAKE_MATRIX(lpDev, hWorld, identity);
  186.     ct = D3DVAL(cos(0.1));
  187.     st = D3DVAL(sin(0.1));
  188.     dviewrot = identity;
  189.     dviewrot._22 = ct;
  190.     dviewrot._23 = -st;
  191.     dviewrot._32 = st;
  192.     dviewrot._33 = ct;
  193.     MAKE_MATRIX(lpDev, hDViewRot, dviewrot);
  194.     dworld = identity;
  195.     dworld._11 = ct;
  196.     dworld._13 = -st;
  197.     dworld._31 = st;
  198.     dworld._33 = ct;
  199.     MAKE_MATRIX(lpDev, hDWorld, dworld);
  200.     size = 0;
  201.     size += sizeof(D3DINSTRUCTION) * 3;
  202.     size += sizeof(D3DSTATE) * 4;
  203.     memset(&debDesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
  204.     debDesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
  205.     debDesc.dwFlags = D3DDEB_BUFSIZE;
  206.     debDesc.dwBufferSize = size;
  207.     if (lpDev->lpVtbl->CreateExecuteBuffer(lpDev, &debDesc, &lpD3DExCmdBuf,
  208.                                            NULL) != D3D_OK)
  209.         return FALSE;
  210.     /*
  211.      * lock it so it can be filled
  212.      */
  213.     if (lpD3DExCmdBuf->lpVtbl->Lock(lpD3DExCmdBuf, &debDesc) != D3D_OK)
  214.         return FALSE;
  215.     lpBufStart = debDesc.lpData;
  216.     memset(lpBufStart, 0, size);
  217.     lpPointer = lpBufStart;
  218.  
  219.     lpInsStart = lpPointer;
  220.     OP_STATE_TRANSFORM(3, lpPointer);
  221.         STATE_DATA(D3DTRANSFORMSTATE_VIEW, hView, lpPointer);
  222.         STATE_DATA(D3DTRANSFORMSTATE_WORLD, hWorld, lpPointer);
  223.         STATE_DATA(D3DTRANSFORMSTATE_PROJECTION, hProj, lpPointer);
  224.     OP_STATE_LIGHT(1, lpPointer);
  225.         STATE_DATA(D3DLIGHTSTATE_AMBIENT, RGBA_MAKE(64, 64, 64, 64), lpPointer);
  226.     OP_EXIT(lpPointer);
  227.     /*
  228.      * Setup the execute data describing the buffer
  229.      */
  230.     lpD3DExCmdBuf->lpVtbl->Unlock(lpD3DExCmdBuf);
  231.     memset(&d3dExData, 0, sizeof(D3DEXECUTEDATA));
  232.     d3dExData.dwSize = sizeof(D3DEXECUTEDATA);
  233.     d3dExData.dwInstructionOffset = (ULONG) 0;
  234.     d3dExData.dwInstructionLength = (ULONG) ((char *)lpPointer - (char*)lpInsStart);
  235.     lpD3DExCmdBuf->lpVtbl->SetExecuteData(lpD3DExCmdBuf, &d3dExData);
  236.     lpDev->lpVtbl->BeginScene(lpDev);
  237.     lpDev->lpVtbl->Execute(lpDev, lpD3DExCmdBuf, lpView, D3DEXECUTE_UNCLIPPED);
  238.     lpDev->lpVtbl->EndScene(lpDev);
  239.     /*
  240.      * We are done with the command buffer.
  241.      */
  242.     lpD3DExCmdBuf->lpVtbl->Release(lpD3DExCmdBuf);
  243.     /*
  244.      * Setup a material
  245.      */
  246.     if (lpD3D->lpVtbl->CreateMaterial(lpD3D, &lpMat1, NULL) != D3D_OK) {
  247.         return FALSE;
  248.     }
  249.     if (lpD3D->lpVtbl->CreateMaterial(lpD3D, &lpMat2, NULL) != D3D_OK) {
  250.         return FALSE;
  251.     }
  252.     memset(&mat1, 0, sizeof(D3DMATERIAL));
  253.     mat1.dwSize = sizeof(D3DMATERIAL);
  254.     
  255.     mat1.diffuse.r = (D3DVALUE)1.0;
  256.     mat1.diffuse.g = (D3DVALUE)0.0;
  257.     mat1.diffuse.b = (D3DVALUE)0.0;
  258.     mat1.diffuse.a = (D3DVALUE)1.0;
  259.     mat1.ambient.r = (D3DVALUE)1.0;
  260.     mat1.ambient.g = (D3DVALUE)0.0;
  261.     mat1.ambient.b = (D3DVALUE)0.0;
  262.     mat1.specular.r = (D3DVALUE)1.0;
  263.     mat1.specular.g = (D3DVALUE)1.0;
  264.     mat1.specular.b = (D3DVALUE)1.0;
  265.     mat1.power = (float)20.0;
  266.     mat1.dwRampSize = 16;
  267.     mat1.hTexture = bTex;
  268.     lpMat1->lpVtbl->SetMaterial(lpMat1, &mat1);
  269.     lpMat1->lpVtbl->GetHandle(lpMat1, lpDev, &hMat1);
  270.     memset(&mat2, 0, sizeof(D3DMATERIAL));
  271.     mat2.dwSize = sizeof(D3DMATERIAL);
  272.     mat2.diffuse.r = (D3DVALUE)1.0;
  273.     mat2.diffuse.g = (D3DVALUE)1.0;
  274.     mat2.diffuse.b = (D3DVALUE)1.0;
  275.     mat2.diffuse.a = (D3DVALUE)1.0;
  276.     mat2.ambient.r = (D3DVALUE)1.0;
  277.     mat2.ambient.g = (D3DVALUE)1.0;
  278.     mat2.ambient.b = (D3DVALUE)1.0;
  279.     mat2.specular.r = (D3DVALUE)1.0;
  280.     mat2.specular.g = (D3DVALUE)1.0;
  281.     mat2.specular.b = (D3DVALUE)1.0;
  282.     mat2.power = (float)20.0;
  283.     mat2.dwRampSize = 16;
  284.     mat2.hTexture = bTex;
  285.     lpMat2->lpVtbl->SetMaterial(lpMat2, &mat2);
  286.     lpMat2->lpVtbl->GetHandle(lpMat2, lpDev, &hMat2);
  287.     /*
  288.      * Setup vertices
  289.      */
  290.     memset(&v[0], 0, sizeof(D3DVERTEX) * NUM_VERTICES);
  291.     /* V 0 */
  292.     v[0].x = D3DVALP(0.0, 12);
  293.     v[0].y = D3DVALP(1.0, 12);
  294.     v[0].z = D3DVALP(1.0, 12);
  295.  
  296.     v[0].nx = D3DVALP(0.0, 12);
  297.     v[0].ny = D3DVALP(1.0, 12);
  298.     v[0].nz = D3DVALP(0.0, 12);
  299.  
  300.     v[0].tu = D3DVAL(0.0);
  301.     v[0].tv = D3DVAL(0.0);
  302.  
  303.     /* V 1 */
  304.     v[1].x = D3DVALP(1.0, 12);
  305.     v[1].y = D3DVALP(0.0, 12);
  306.     v[1].z = D3DVALP(0.0, 12);
  307.  
  308.     v[1].nx = D3DVALP(1.0, 12);
  309.     v[1].ny = D3DVALP(0.0, 12);
  310.     v[1].nz = D3DVALP(-1.0, 12);
  311.  
  312.     v[1].tu = D3DVAL(1.0);
  313.     v[1].tv = D3DVAL(1.0);
  314.  
  315.     D3DVECTORNormalise((LPD3DVECTOR) & v[1].nx);
  316.  
  317.     /* V 2 */
  318.     v[2].x = D3DVALP(-1.0, 12);
  319.     v[2].y = D3DVALP(0.0, 12);
  320.     v[2].z = D3DVALP(0.0, 12);
  321.  
  322.     v[2].nx = D3DVALP(-1.0, 12);
  323.     v[2].ny = D3DVALP(0.0, 12);
  324.     v[2].nz = D3DVALP(-1.0, 12);
  325.  
  326.     v[2].tu = D3DVAL(0.0);
  327.     v[2].tv = D3DVAL(1.0);
  328.  
  329.     D3DVECTORNormalise((LPD3DVECTOR) & v[2].nx);
  330.  
  331.     /* V 3 */
  332.     v[3].x = D3DVALP(-1.0, 12);
  333.     v[3].y = D3DVALP(0.0, 12);
  334.     v[3].z = D3DVALP(2.0, 12);
  335.  
  336.     v[3].nx = D3DVALP(-1.0, 12);
  337.     v[3].ny = D3DVALP(0.0, 12);
  338.     v[3].nz = D3DVALP(1.0, 12);
  339.  
  340.     v[3].tu = D3DVAL(1.0);
  341.     v[3].tv = D3DVAL(1.0);
  342.  
  343.     D3DVECTORNormalise((LPD3DVECTOR) & v[3].nx);
  344.  
  345.     /* V 4 */
  346.     v[4].x = D3DVALP(1.0, 12);
  347.     v[4].y = D3DVALP(0.0, 12);
  348.     v[4].z = D3DVALP(2.0, 12);
  349.  
  350.     v[4].nx = D3DVALP(1.0, 12);
  351.     v[4].ny = D3DVALP(0.0, 12);
  352.     v[4].nz = D3DVALP(1.0, 12);
  353.  
  354.     v[4].tu = D3DVAL(0.0);
  355.     v[4].tv = D3DVAL(1.0);
  356.  
  357.     D3DVECTORNormalise((LPD3DVECTOR) & v[4].nx);
  358.  
  359.     /* V 5 */
  360.     v[5].x = D3DVALP(0.0, 12);
  361.     v[5].y = D3DVALP(-1.0, 12);
  362.     v[5].z = D3DVALP(1.0, 12);
  363.  
  364.     v[5].nx = D3DVALP(0.0, 12);
  365.     v[5].ny = D3DVALP(-1.0, 12);
  366.     v[5].nz = D3DVALP(0.0, 12);
  367.  
  368.     v[5].tu = D3DVAL(0.0);
  369.     v[5].tv = D3DVAL(0.0);
  370.  
  371.     D3DVECTORNormalise((LPD3DVECTOR) & v[5].nx);
  372.  
  373.     /*
  374.      * Create an execute buffer
  375.      */
  376.     size = sizeof(D3DVERTEX) * NUM_VERTICES;
  377.     size += sizeof(D3DSTATUS) * 1;
  378.     size += sizeof(D3DPROCESSVERTICES) * 2;
  379.     size += sizeof(D3DINSTRUCTION) * 10;
  380.     size += sizeof(D3DMATRIXMULTIPLY) * 3;
  381.     size += sizeof(D3DSTATE) * 5;
  382.     size += sizeof(D3DTRIANGLE) * NUM_TRIANGLES;
  383.     memset(&debDesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
  384.     debDesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
  385.     debDesc.dwFlags = D3DDEB_BUFSIZE;
  386.     debDesc.dwBufferSize = size;
  387.     if (lpDev->lpVtbl->CreateExecuteBuffer(lpDev, &debDesc, &lpD3DExBuf,
  388.                                            NULL) != D3D_OK) {
  389.         return FALSE;
  390.     }
  391.     if (lpD3DExBuf->lpVtbl->Lock(lpD3DExBuf, &debDesc) != D3D_OK) {
  392.         return FALSE;
  393.     }
  394.     lpBufStart = debDesc.lpData;
  395.     memset(lpBufStart, 0, size);
  396.     lpPointer = lpBufStart;
  397.     /*
  398.      * Copy vertices to execute buffer
  399.      */
  400.     VERTEX_DATA(&v[0], NUM_VERTICES, lpPointer);
  401.     /*
  402.      * Setup instructions in execute buffer
  403.      */
  404.     lpInsStart = lpPointer;
  405.     OP_MATRIX_MULTIPLY(3, lpPointer);
  406.         MATRIX_MULTIPLY_DATA(hViewRot, hDViewRot, hViewRot, lpPointer);
  407.         MATRIX_MULTIPLY_DATA(hViewRot, hViewPos, hView, lpPointer);
  408.         MATRIX_MULTIPLY_DATA(hWorld, hDWorld, hWorld, lpPointer);
  409.     OP_STATE_LIGHT(1, lpPointer);
  410.         STATE_DATA(D3DLIGHTSTATE_MATERIAL, hMat1, lpPointer);
  411.     OP_SET_STATUS(D3DSETSTATUS_ALL, D3DSTATUS_DEFAULT, 2048, 2048, 0, 0, lpPointer);
  412.     OP_PROCESS_VERTICES(1, lpPointer);
  413.         PROCESSVERTICES_DATA(D3DPROCESSVERTICES_TRANSFORMLIGHT, 0, 5, lpPointer);
  414.     OP_STATE_LIGHT(1, lpPointer);
  415.         STATE_DATA(D3DLIGHTSTATE_MATERIAL, hMat2, lpPointer);
  416.     OP_PROCESS_VERTICES(1, lpPointer);
  417.         PROCESSVERTICES_DATA(D3DPROCESSVERTICES_TRANSFORMLIGHT, 5, 1, lpPointer);
  418.     OP_STATE_RENDER(3, lpPointer);
  419.         STATE_DATA(D3DRENDERSTATE_TEXTUREHANDLE, bTex, lpPointer);
  420.         STATE_DATA(D3DRENDERSTATE_WRAPU, FALSE, lpPointer);
  421.         STATE_DATA(D3DRENDERSTATE_WRAPV, FALSE, lpPointer);
  422.     /*
  423.      * Make sure that the triangle data (not OP) will be QWORD aligned
  424.      */
  425.     if (QWORD_ALIGNED(lpPointer)) {
  426.         OP_NOP(lpPointer);
  427.     }
  428.     OP_TRIANGLE_LIST(NUM_TRIANGLES, lpPointer);
  429.         lpTri = (LPD3DTRIANGLE)lpPointer;
  430.         for (i = 0; i < NUM_TRIANGLES; i++) {
  431.             lpTri->v1 = t[i][0];
  432.             lpTri->v2 = t[i][1];
  433.             lpTri->v3 = t[i][2];
  434.             lpTri->wFlags = D3DTRIFLAG_EDGEENABLETRIANGLE;
  435.             lpTri++;
  436.         }
  437.         lpPointer = (void*)lpTri;
  438.     OP_EXIT(lpPointer);
  439.     /*
  440.      * Setup the execute data
  441.      */
  442.     lpD3DExBuf->lpVtbl->Unlock(lpD3DExBuf);
  443.     memset(&d3dExData, 0, sizeof(D3DEXECUTEDATA));
  444.     d3dExData.dwSize = sizeof(D3DEXECUTEDATA);
  445.     d3dExData.dwVertexCount = NUM_VERTICES;
  446.     d3dExData.dwInstructionOffset = (ULONG) ((char *)lpInsStart - (char *)lpBufStart);
  447.     d3dExData.dwInstructionLength = (ULONG) ((char *)lpPointer - (char*)lpInsStart);
  448.     lpD3DExBuf->lpVtbl->SetExecuteData(lpD3DExBuf, &d3dExData);
  449.     /*
  450.      * Setup lights
  451.      */
  452.     memset(&light, 0, sizeof(D3DLIGHT));
  453.     light.dwSize = sizeof(D3DLIGHT);
  454.     light.dltType = D3DLIGHT_DIRECTIONAL;
  455.     light.dcvColor.r = D3DVAL(1.0);
  456.     light.dcvColor.g = D3DVAL(1.0);
  457.     light.dcvColor.b = D3DVAL(1.0);
  458.     light.dcvColor.a = D3DVAL(1.0);
  459.     light.dvDirection.x = D3DVALP(0.0, 12);
  460.     light.dvDirection.y = D3DVALP(0.0, 12);
  461.     light.dvDirection.z = D3DVALP(1.0, 12);
  462.     if (lpD3D->lpVtbl->CreateLight(lpD3D, &lpD3DLight, NULL) != D3D_OK) {
  463.         return FALSE;
  464.     }
  465.     if (lpD3DLight->lpVtbl->SetLight(lpD3DLight, &light) != D3D_OK) {
  466.         return FALSE;
  467.     }
  468.     if (lpView->lpVtbl->AddLight(lpView, lpD3DLight) != D3D_OK) {
  469.         return FALSE;
  470.     }
  471.     return TRUE;
  472. }
  473.