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