FLY.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:13k
源码类别:

Windows编程

开发平台:

Visual C++

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