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

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995, 1996 Microsoft Corporation. All Rights Reserved.
  4.  *
  5.  *  File: fly.c
  6.  *
  7.  ***************************************************************************/
  8.  
  9. /*
  10.  * landscape fly by
  11.  */
  12.  
  13. #include <math.h>
  14. #include <stdlib.h>
  15. #include "rmdemo.h"
  16.  
  17. typedef struct PATHINFO {
  18.     D3DVALUE t;
  19.     LPDIRECT3DRMFRAME chase;
  20.     LPDIRECT3DRMFRAME plane_frame;
  21.     LPDIRECT3DRMANIMATION flight_path;
  22. } pathInfo;
  23.  
  24. #define NUM_SMOKE 7
  25. int smoke_num = 0;
  26. int done_all = 0;
  27.  
  28. LPDIRECT3DRMFRAME smoke[NUM_SMOKE];
  29.  
  30. static void cleanupObjects(LPDIRECT3DRMOBJECT obj, void* arg)
  31. {
  32.     pathInfo *info = (pathInfo*) arg;
  33.     int i;
  34.  
  35.     for (i = 0; i < NUM_SMOKE; i++)
  36.         smoke[i]->lpVtbl->Release(smoke[i]);
  37.     info->chase->lpVtbl->Release(info->chase);
  38.     info->plane_frame->lpVtbl->Release(info->plane_frame);
  39.     info->flight_path->lpVtbl->Release(info->flight_path);
  40. }
  41.  
  42. void 
  43. moveCamera(LPDIRECT3DRMFRAME camera, void *arg, D3DVALUE delta)
  44. {
  45.     D3DVECTOR dir, up;
  46.     D3DVECTOR dirCam, upCam;
  47.     struct PATHINFO *info;
  48.     LPDIRECT3DRMFRAME scene;
  49.     D3DVALUE a_bit;
  50.  
  51.     info = (struct PATHINFO *) arg;
  52.     camera->lpVtbl->GetScene(camera, &scene);
  53.     info->t += D3DVAL(0.04);
  54.     info->flight_path->lpVtbl->SetFrame(info->flight_path, camera);
  55.     info->flight_path->lpVtbl->SetTime(info->flight_path, info->t);
  56.  
  57.     info->flight_path->lpVtbl->SetFrame(info->flight_path, info->plane_frame);
  58.     info->flight_path->lpVtbl->SetTime(info->flight_path, info->t + D3DVAL(0.5));
  59.  
  60.     info->flight_path->lpVtbl->SetFrame(info->flight_path, info->chase);
  61.     info->flight_path->lpVtbl->SetTime(info->flight_path, info->t + D3DVAL(1.0));
  62.  
  63.     camera->lpVtbl->LookAt(camera, info->plane_frame, scene, D3DRMCONSTRAIN_Z);
  64.     info->plane_frame->lpVtbl->LookAt(info->plane_frame, info->chase,scene,
  65.                                       D3DRMCONSTRAIN_Y);
  66.     camera->lpVtbl->GetOrientation(camera, scene, &dirCam, &upCam);
  67.     info->plane_frame->lpVtbl->GetOrientation(info->plane_frame, scene,
  68.                                               &dir, &up);
  69.     up.x = dir.x - dirCam.x;
  70.     up.y = dir.y - dirCam.y + D3DVAL(1.0);
  71.     up.z = dir.z - dirCam.z;
  72.                 
  73.     info->plane_frame->lpVtbl->SetOrientation(info->plane_frame, scene,
  74.                                               dir.x, dir.y, dir.z,
  75.                                               up.x, up.y, up.z);
  76.  
  77.     if (done_all < NUM_SMOKE) {
  78.         scene->lpVtbl->AddVisual(scene, (LPDIRECT3DRMVISUAL) smoke[smoke_num]);
  79.         done_all++;
  80.     } else {
  81.         if (smoke_num == NUM_SMOKE) {
  82.             smoke_num = 0;
  83.         }
  84.     }
  85.     a_bit = D3DDivide(D3DDivide(D3DVAL(smoke_num), D3DVAL(NUM_SMOKE)),
  86.                      D3DVAL(10.0));
  87.     info->flight_path->lpVtbl->SetFrame(info->flight_path, smoke[smoke_num]);
  88.     info->flight_path->lpVtbl->SetTime(info->flight_path, 
  89.                                        info->t + D3DVAL(0.4) - a_bit);
  90.     smoke[smoke_num]->lpVtbl->SetOrientation(smoke[smoke_num], scene,
  91.                                              dir.x, dir.y, dir.z,
  92.                                              up.x, up.y, up.z);
  93.     smoke_num++;
  94.     scene->lpVtbl->Release(scene);
  95. }
  96.  
  97. BOOL
  98. BuildScene(LPDIRECT3DRMDEVICE dev, LPDIRECT3DRMVIEWPORT view,
  99.            LPDIRECT3DRMFRAME scene, LPDIRECT3DRMFRAME camera)
  100. {
  101.     LPDIRECT3DRMFRAME lights = NULL;
  102.     D3DRMBOX box;
  103.     LPDIRECT3DRMMESHBUILDER plane_builder = NULL;
  104.     LPDIRECT3DRMMESHBUILDER mesh_builder = NULL;
  105.     LPDIRECT3DRMMESHBUILDER smoke_builder = NULL;
  106.     LPDIRECT3DRMMESH plane = NULL;
  107.     LPDIRECT3DRMMESH mesh = NULL;
  108.     LPDIRECT3DRMMESH smokemesh = NULL;
  109.     LPDIRECT3DRMLIGHT ambient = NULL;
  110.     LPDIRECT3DRMLIGHT parallel = NULL;
  111.     D3DCOLOR smokec;
  112.     LPDIRECT3DRMFRAME frame = NULL;
  113.     LPDIRECT3DRMFRAME sl = NULL;
  114.     LPDIRECT3DRMFRAME sr = NULL;
  115.     HRESULT rval;
  116.     int i;
  117.     int numPts = 11;
  118.     D3DVECTOR path[] = {
  119.         -D3DVAL(8.0), D3DVAL(3.0), -D3DVAL(12.0),
  120.         -D3DVAL(4.0), D3DVAL(2.0), -D3DVAL(8.0),
  121.         -D3DVAL(2.0), D3DVAL(0.0), -D3DVAL(4.0),
  122.         D3DVAL(9.0), -D3DVAL(1.0), D3DVAL(7.0),
  123.         D3DVAL(4.0), D3DVAL(6.0), D3DVAL(10.0),
  124.         -D3DVAL(4.0), D3DVAL(5.0), D3DVAL(9.0),
  125.         D3DVAL(5.5), D3DVAL(3.5), -D3DVAL(6.5),
  126.         D3DVAL(2.0), D3DVAL(5.0), -D3DVAL(10.0),
  127.         D3DVAL(0.0), D3DVAL(4.0), -D3DVAL(15.0),
  128.         -D3DVAL(5.0), D3DVAL(4.0), -D3DVAL(15.0),
  129.         -D3DVAL(8.0), D3DVAL(3.0), -D3DVAL(12.0)
  130.     };
  131.     D3DVALUE path_t[] = {
  132.         D3DVAL(0), D3DVAL(1), D3DVAL(2), D3DVAL(3), D3DVAL(4), D3DVAL(5), D3DVAL(6), D3DVAL(7), D3DVAL(8), D3DVAL(9), D3DVAL(10)
  133.     };
  134.     static pathInfo info;
  135.  
  136.     if (FAILED(view->lpVtbl->SetField(view, D3DVAL(0.8))))
  137.         goto generic_error;
  138.     if (FAILED(dev->lpVtbl->SetQuality(dev, D3DRMRENDER_GOURAUD)))
  139.         goto generic_error;
  140. #ifdef FOG
  141.     if (FAILED(dev->lpVtbl->SetDither(dev, TRUE)))
  142.         goto generic_error;
  143.     if (FAILED(scene->lpVtbl->SetFogEnable(scene, TRUE)))
  144.         goto generic_error;
  145.     if (FAILED(scene->lpVtbl->SetFogParams(scene, 1, 30, 1)))
  146.         goto generic_error;
  147. #endif
  148.  
  149.     /*
  150.      * This Demo flies a plane through a small landscape, followed by a
  151.      * camera. The paths are spline curves.
  152.      */
  153.  
  154.     /*
  155.      * Initialise smoke trail
  156.      */
  157.     smokec = D3DRMCreateColorRGBA(D3DVAL(0.6), D3DVAL(0.6), D3DVAL(0.6),
  158.                                 D3DVAL(0.5));
  159.     if (FAILED(lpD3DRM->lpVtbl->CreateMeshBuilder(lpD3DRM, &smoke_builder)))
  160.         goto generic_error;
  161.     rval = smoke_builder->lpVtbl->Load(smoke_builder, "sphere0.x", NULL,
  162.                                 D3DRMLOAD_FROMFILE, NULL, NULL);
  163.     if (rval != D3DRM_OK) {
  164.         Msg("Failed to load sphere0.x.\n%s", D3DRMErrorToString(rval));
  165.         goto ret_with_error;
  166.     }
  167.     if (FAILED(smoke_builder->lpVtbl->Scale(smoke_builder, D3DVAL(0.015), D3DVAL(0.015),
  168.                                  D3DVAL(0.015))))
  169.                                  goto generic_error;
  170.  
  171.     if (FAILED(smoke_builder->lpVtbl->CreateMesh(smoke_builder, &smokemesh)))
  172.         goto generic_error;
  173.     for (i = 0; i < NUM_SMOKE; i++) {
  174.         if (FAILED(lpD3DRM->lpVtbl->CreateFrame(lpD3DRM, scene, &smoke[i])))
  175.             goto generic_error;
  176.         if (FAILED(lpD3DRM->lpVtbl->CreateFrame(lpD3DRM, smoke[i], &sl)))
  177.             goto generic_error;
  178.         if (FAILED(lpD3DRM->lpVtbl->CreateFrame(lpD3DRM, smoke[i], &sr)))
  179.             goto generic_error;
  180.  
  181.         if (FAILED(sl->lpVtbl->AddVisual(sl, (LPDIRECT3DRMVISUAL) smokemesh)))
  182.             goto generic_error;
  183.         if (FAILED(sr->lpVtbl->AddVisual(sr, (LPDIRECT3DRMVISUAL) smokemesh)))
  184.             goto generic_error;
  185.         if (FAILED(sr->lpVtbl->SetPosition(sr, smoke[i], D3DVAL(-0.1), D3DVAL(0.0),
  186.                                            D3DVAL(0.0))))
  187.                                            goto generic_error;
  188.         if (FAILED(smoke[i]->lpVtbl->SetMaterialMode(smoke[i], D3DRMMATERIAL_FROMFRAME)))
  189.             goto generic_error;
  190.         if (FAILED(smoke[i]->lpVtbl->SetColor(smoke[i], smokec)))
  191.             goto generic_error;
  192.         if (FAILED(sl->lpVtbl->SetMaterialMode(sl, D3DRMMATERIAL_FROMPARENT)))
  193.             goto generic_error;
  194.         if (FAILED(sr->lpVtbl->SetMaterialMode(sr, D3DRMMATERIAL_FROMPARENT)))
  195.             goto generic_error;
  196.         RELEASE(sl);
  197.         RELEASE(sr);
  198.     }
  199.     /*
  200.      * initialize the lights in the scene
  201.      */
  202.     if (FAILED(lpD3DRM->lpVtbl->CreateFrame(lpD3DRM, scene, &lights)))
  203.         goto generic_error;
  204.     if (FAILED(lights->lpVtbl->SetPosition(lights, scene, D3DVAL(5.0), D3DVAL(5.0),
  205.                                             -D3DVAL(5.0))))
  206.         goto generic_error;
  207.                                 
  208.     if (FAILED(lpD3DRM->lpVtbl->CreateLightRGB(lpD3DRM, D3DRMLIGHT_PARALLELPOINT, D3DVAL(0.8),
  209.                                                 D3DVAL(0.6), D3DVAL(0.7), ¶llel)))
  210.                                                 goto generic_error;
  211.                                   
  212.     if (FAILED(lights->lpVtbl->AddLight(lights, parallel)))
  213.         goto generic_error;
  214.     if (FAILED(lpD3DRM->lpVtbl->CreateLightRGB(lpD3DRM, D3DRMLIGHT_AMBIENT, D3DVAL(0.1),
  215.                                   D3DVAL(0.1), D3DVAL(0.1), &ambient)))
  216.                                   goto generic_error;
  217.     if (FAILED(scene->lpVtbl->AddLight(scene, ambient)))
  218.         goto generic_error;
  219.  
  220.     /*
  221.      * load mesh file
  222.      */
  223.  
  224.     if (FAILED(lpD3DRM->lpVtbl->CreateFrame(lpD3DRM, scene, &frame)))
  225.         goto generic_error;
  226.     if (FAILED(lpD3DRM->lpVtbl->CreateMeshBuilder(lpD3DRM, &mesh_builder)))
  227.         goto generic_error;
  228.     if (FAILED(mesh_builder->lpVtbl->Load(mesh_builder, "land4.x", NULL,
  229.                                         D3DRMLOAD_FROMFILE, NULL, NULL)))
  230.         goto generic_error;
  231.     if (FAILED(mesh_builder->lpVtbl->Scale(mesh_builder, D3DVAL(10.0), D3DVAL(8.0),
  232.                                 D3DVAL(10.0))))
  233.                                 goto generic_error;
  234.     if (FAILED(mesh_builder->lpVtbl->GetBox(mesh_builder, &box)))
  235.         goto generic_error;
  236.  
  237.     /*
  238.      * Color the landscape's faces.
  239.      */
  240.     if (mesh_builder) {
  241.         LPDIRECT3DRMFACEARRAY faces;
  242.         LPDIRECT3DRMFACE this_face;
  243.         int face_count, vertex_count;
  244.         int j;
  245.         D3DVALUE range, height;
  246.         D3DVECTOR *coords;
  247.  
  248.         if (FAILED(mesh_builder->lpVtbl->GetFaces(mesh_builder, &faces)))
  249.             goto generic_error;
  250.         face_count = faces->lpVtbl->GetSize(faces);
  251.             
  252.         range = box.max.y - box.min.y;
  253.  
  254.         /*
  255.          * color the faces according to the height
  256.          */
  257.         for (i = 0; i < face_count; i++) {
  258.             faces->lpVtbl->GetElement(faces, i, &this_face);
  259.             vertex_count = this_face->lpVtbl->GetVertexCount(this_face);
  260.             coords = (LPD3DVECTOR) malloc(vertex_count * sizeof(D3DVECTOR));
  261.             this_face->lpVtbl->GetVertices(this_face, &vertex_count,
  262.                                            coords, NULL);
  263.             if (vertex_count) {
  264.                 /*
  265.                  * find maximum height of the face
  266.                  */
  267.                 height = coords[0].y;
  268.                 for (j = 1; j < vertex_count; j++) {
  269.                     if (coords[j].y > height)
  270.                         height = coords[j].y;
  271.                 }
  272.                 height = D3DDivide((height - box.min.y), range);
  273.  
  274.                 if (height < D3DVAL(0.03))      /* water */
  275.                     this_face->lpVtbl->SetColorRGB(this_face,
  276.                                      D3DVAL(0.2), D3DVAL(0.2), D3DVAL(0.5));
  277.                 else if (height < D3DVAL(0.3))  /* greenery */
  278.                     this_face->lpVtbl->SetColorRGB(this_face,
  279.                                      D3DVAL(0.1), D3DVAL(0.8), D3DVAL(0.1));
  280.                 else if (height < D3DVAL(0.5))  /* rocks */
  281.                     this_face->lpVtbl->SetColorRGB(this_face, D3DVAL(0.6),
  282.                                                     D3DVAL(0.3),D3DVAL(0.3));
  283.                 else if (height < D3DVAL(0.7))  /* dirty snow */
  284.                     this_face->lpVtbl->SetColorRGB(this_face, D3DVAL(0.8),
  285.                                                     D3DVAL(0.65),
  286.                                                     D3DVAL(0.65));
  287.                 else            /* snow */
  288.                     this_face->lpVtbl->SetColorRGB(this_face, D3DVAL(1.0),
  289.                                                     D3DVAL(1.0),D3DVAL(1.0));
  290.             }
  291.             free(coords);
  292.             RELEASE(this_face);
  293.         }
  294.         RELEASE(faces);
  295.     }
  296.     if (FAILED(mesh_builder->lpVtbl->CreateMesh(mesh_builder, &mesh)))
  297.         goto generic_error;
  298.     if (FAILED(frame->lpVtbl->AddVisual(frame, (LPDIRECT3DRMVISUAL) mesh)))
  299.         goto generic_error;
  300.  
  301.     if (FAILED(lpD3DRM->lpVtbl->CreateMeshBuilder(lpD3DRM, &plane_builder)))
  302.         goto generic_error;
  303.     rval = plane_builder->lpVtbl->Load(plane_builder, "dropship.x", NULL,
  304.                                 D3DRMLOAD_FROMFILE, NULL, NULL);
  305.     if (rval != D3DRM_OK) {
  306.         Msg("Failed to load dropship.x.\n%s", D3DRMErrorToString(rval));
  307.         goto ret_with_error;
  308.     }
  309.     if (FAILED(plane_builder->lpVtbl->Scale(plane_builder, D3DVAL(0.015),
  310.                                  D3DVAL(0.008), D3DVAL(0.015))))
  311.                                  goto generic_error;
  312.     if (FAILED(plane_builder->lpVtbl->CreateMesh(plane_builder, &plane)))
  313.         goto generic_error;
  314.  
  315.     if (FAILED(lpD3DRM->lpVtbl->CreateAnimation(lpD3DRM, &info.flight_path)))
  316.         goto generic_error;
  317.     info.flight_path->lpVtbl->SetOptions(info.flight_path, D3DRMANIMATION_CLOSED
  318.                                          | D3DRMANIMATION_SPLINEPOSITION
  319.                                          | D3DRMANIMATION_POSITION);
  320.     for (i = 0; i < numPts; i++)
  321.         info.flight_path->lpVtbl->AddPositionKey(info.flight_path, path_t[i], 
  322.                                                  path[i].x,
  323.                                                  path[i].y, path[i].z);
  324.  
  325.     info.t = D3DVAL(0.0);
  326.     if (FAILED(lpD3DRM->lpVtbl->CreateFrame(lpD3DRM, scene, &info.chase)))
  327.         goto generic_error;
  328.     if (FAILED(lpD3DRM->lpVtbl->CreateFrame(lpD3DRM, scene, &info.plane_frame)))
  329.         goto generic_error;
  330.     if (FAILED(info.plane_frame->lpVtbl->AddVisual(info.plane_frame,
  331.                                         (LPDIRECT3DRMVISUAL) plane)))
  332.                                         goto generic_error;
  333.  
  334.     if (FAILED(camera->lpVtbl->AddMoveCallback(camera, moveCamera, (void *) &info)))
  335.         goto generic_error;
  336.     if (FAILED(camera->lpVtbl->AddDestroyCallback(camera, cleanupObjects, &info)))
  337.         goto generic_error;
  338.  
  339.     RELEASE(lights);
  340.     RELEASE(plane_builder);
  341.     RELEASE(mesh_builder);
  342.     RELEASE(smoke_builder);
  343.     RELEASE(plane);
  344.     RELEASE(mesh);
  345.     RELEASE(smokemesh);
  346.     RELEASE(ambient);
  347.     RELEASE(parallel);
  348.     RELEASE(frame);
  349.     return TRUE;
  350.  
  351. generic_error:
  352.     Msg("A failure has occured while building the scene.\n");
  353. ret_with_error:
  354.     RELEASE(lights);
  355.     RELEASE(plane_builder);
  356.     RELEASE(mesh_builder);
  357.     RELEASE(smoke_builder);
  358.     RELEASE(plane);
  359.     RELEASE(mesh);
  360.     RELEASE(smokemesh);
  361.     RELEASE(ambient);
  362.     RELEASE(parallel);
  363.     RELEASE(frame);
  364.     RELEASE(sl);
  365.     RELEASE(sr);
  366.     return FALSE;
  367. }
  368.  
  369. void
  370. OverrideDefaults(Defaults* defaults)
  371. {
  372.     defaults->bNoTextures = TRUE;
  373.     defaults->bConstRenderQuality = TRUE;
  374.     lstrcpy(defaults->Name, "Fly Direct3DRM Example");
  375. }
  376.