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

Windows编程

开发平台:

Visual C++

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995-1997 Microsoft Corporation. All Rights Reserved.
  4.  *
  5.  *  File:       dxa.cpp
  6.  *
  7.  *  This file contains functions that make use of DirectX Animation
  8.  *  to render animation to a ddraw surface.
  9.  *
  10.  ***************************************************************************/
  11. #include "dxa.h"
  12. IDAViewPtr DXA::_view = NULL;
  13. /*
  14.  * StartOle
  15.  *
  16.  * Start the Ole services.
  17.  */
  18. struct StartOle {
  19.     StartOle() { CoInitialize( NULL ); }
  20.     ~StartOle() { CoUninitialize(); }
  21. } _inst_StartOle;
  22. /*
  23.  * dump_com_error
  24.  *
  25.  * Dump the com error should an exception occurs in InitDXAViewObj.
  26.  * This is mainly for debugging purpose.
  27.  */
  28. void dump_com_error( _com_error &e )
  29. {
  30.     char buf[2048];
  31.     sprintf(buf, _T( "Oops - hit an error!ntCode = %08lxntCode meaning = %sn" ),
  32.             e.Error(), e.ErrorMessage());
  33.     OutputDebugString(buf);
  34. }
  35. /*
  36.  * initDXAViewObj
  37.  *
  38.  * Create the DAView object, construct the model, then start the model.
  39.  *
  40.  */
  41. BOOL DXA::initDXAViewObj(IUnknown *ddsurf)
  42. {
  43.     try {
  44.         IDAStaticsPtr e;
  45.         // Create the statics object
  46.         e.CreateInstance( L"DirectAnimation.DAStatics" );
  47.         
  48.         // Create and establish the view
  49.         _view.CreateInstance( L"DirectAnimation.DAView" );
  50.         // Import Media (images and sound in this case).  The
  51. // GetCurrentDirectory() (which will return the path to either 
  52. // the debug or release sub directory) is used as a starting
  53. // point for relative file importing.
  54.         TCHAR szMediaBase[_MAX_PATH];
  55. TCHAR szImg[_MAX_PATH];
  56. TCHAR szGeo[_MAX_PATH];
  57. TCHAR szSnd[_MAX_PATH];
  58. GetCurrentDirectory(sizeof(szMediaBase),szMediaBase);
  59. _tcscat(szMediaBase,_T("\..\..\..\..\..\media\"));
  60. _tcscpy(szImg,szMediaBase);
  61. _tcscpy(szGeo,szMediaBase);
  62. _tcscpy(szSnd,szMediaBase);
  63. _tcscat(szImg,_T("image\"));
  64. _tcscat(szGeo,_T("geometry\"));
  65. _tcscat(szSnd,_T("sound\"));
  66.         // Define constants
  67.         SIZE = e->Scale3Uniform(0.25);
  68.         PICKEVENT = e->LeftButtonDown;
  69. SPEED = e->DANumber(0.07);
  70. PI = 3.14159265359;
  71. // Import the geometries.
  72.         IDAGeometryPtr rawCube = 
  73.           e->ImportGeometry( _bstr_t(szGeo) + _bstr_t( "cube.wrl" ) );
  74.         rawCube = rawCube->Transform(SIZE);
  75.         IDAGeometryPtr rawCylinder = 
  76.     e->ImportGeometry(_bstr_t(szGeo) + _bstr_t("cylinder.wrl"));
  77.         rawCylinder = rawCylinder->Transform(SIZE);
  78.         IDAGeometryPtr rawCone = 
  79. e->ImportGeometry(_bstr_t(szGeo) + _bstr_t("cone.wrl"));
  80.         rawCone = rawCone->Transform(SIZE);
  81.         // Make the geometries pickable.
  82.         IDAGeometryPtr cone1 = activate(rawCone, e->Green, e);
  83.         IDAGeometryPtr cube1 = activate(rawCube, e->Magenta, e);
  84.         IDAGeometryPtr cube2 = activate(rawCube, e->ColorHslAnim(e->Div(e->LocalTime,
  85.           e->DANumber(8)), e->DANumber(1), e->DANumber(0.5)), e);
  86.         IDAGeometryPtr cylinder = activate(rawCylinder, e->ColorRgb(0.8,0.4,0.4), e);
  87.         // Construct the final geometry, scale and rotate it.
  88.         IDAGeometryPtr multigeo = e->UnionGeometry(cone1->Transform(e->Translate3(0,1,0)),
  89.           e->UnionGeometry(cube1->Transform(e->Translate3(0,0,1)),
  90.             e->UnionGeometry(cube2->Transform(e->Translate3(0,0,-1)),cylinder)));
  91.         IDAGeometryPtr geo = multigeo->Transform(e->Scale3Anim(e->Add(e->Abs(e->Sin(e->Mul(e->LocalTime,
  92.           e->DANumber(0.2)))),e->DANumber(0.5)),e->Add(e->Abs(e->Sin(e->Mul(e->LocalTime,
  93.             e->DANumber(0.26)))),e->DANumber(0.5)),e->Add(e->Abs(e->Sin(e->Mul(e->LocalTime,
  94.               e->DANumber(0.14)))),e->DANumber(0.5))));
  95.  
  96.         IDATransform3Ptr transform1 = e->Rotate3Anim(e->ZVector3,
  97.           e->Mul(e->DANumber(0.07), e->Mul(e->LocalTime, e->DANumber(1.9))));
  98.         IDATransform3Ptr transform2 = e->Rotate3Anim(e->YVector3,
  99.           e->Mul(e->DANumber(0.07), e->Mul(e->LocalTime, e->DANumber(PI))));
  100.         IDAImagePtr movingGeoImg = geometryImage(geo->Transform(e->Compose3(e->Rotate3Anim(e->ZVector3,
  101.           e->Mul(e->DANumber(0.07),e->Mul(e->LocalTime,e->DANumber(1.9)))), e->Rotate3Anim(e->YVector3,
  102.             e->Mul(e->DANumber(0.07),e->Mul(e->LocalTime,e->DANumber(PI)))))), e);
  103. IDAImagePtr model = e->Overlay( movingGeoImg, e->SolidColorImage( e->Black ) );
  104.       // Set the size and position of the viewport.
  105.       //_view->SetViewport(100, 100, 300, 300);
  106.       // Let the view draw to the primary surface.
  107.   _view->SetViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
  108.   // Let the view draw to the primary surface.
  109.       _view->IDirectDrawSurface = ddsurf;
  110.       _view->CompositeDirectlyToTarget = FALSE;
  111.   // Start the model on the view.
  112.       _view->StartModel(model, e->Silence, 0);
  113.     } catch (_com_error &e) {
  114.         dump_com_error( e );
  115.         return false;
  116.     }
  117.     return true;
  118. }
  119. BOOL DXA::resetDXASurfaces(IUnknown *ddsurf)
  120. {
  121.     try {
  122.         _view->IDirectDrawSurface = ddsurf;
  123.     } catch (_com_error &e) {
  124.         dump_com_error( e );
  125.         return false;
  126.     }
  127.     return true;
  128. }
  129. IDAGeometryPtr DXA::activate(IDAGeometryPtr unpickedGeo, IDAColorPtr col, IDAStaticsPtr e)  {
  130.   //IDAEventPtr pickEvent = e->Timer(3); // Hack for now until picking works.
  131.   //IDAPickableResultPtr pickGeo = unpickedGeo->Pickable();
  132.   //e->AndEvent(e->LeftButtonDown, pickGeo->PickEvent);
  133.   
  134.   IDANumberPtr numcyc;
  135.   numcyc.CreateInstance( L"DirectAnimation.DANumber");
  136.   numcyc->Init(e->Until(e->DANumber(0),PICKEVENT,
  137.     e->Until(e->DANumber(1), PICKEVENT, numcyc)));
  138.   IDAColorPtr colcyc;
  139.   colcyc.CreateInstance( L"DirectAnimation.DAColor");
  140.   colcyc->Init(e->Until(e->White, PICKEVENT, e->Until(col, PICKEVENT, colcyc)));
  141.   IDATransform3Ptr xf = e->Rotate3Anim(e->XVector3, e->Integral(numcyc));
  142.   return unpickedGeo->DiffuseColor(colcyc)->Transform(xf);
  143.   //return pickGeo->Geometry->DiffuseColor(colcyc)->Transform(xf);
  144. }
  145. /* 
  146.  * geometryImage
  147.  * Renders a geometry as an image
  148.  */
  149. IDAImagePtr DXA::geometryImage(IDAGeometryPtr geo, IDAStaticsPtr e)  {
  150.   IDANumberPtr scaleFactor = e->DANumber(0.02);
  151.   IDATransform3Ptr perspTransform;
  152.   perspTransform.CreateInstance( L"DirectAnimation.DATransform3");
  153.   perspTransform->Init(e->Until(e->Compose3(e->Rotate3Anim(e->XVector3,
  154.     e->Mul(SPEED,e->LocalTime)),e->Translate3(0, 0, 0.2)),PICKEVENT, 
  155.       e->Until(e->Rotate3Anim(e->XVector3, e->Mul(SPEED,e->LocalTime)),
  156.         PICKEVENT, perspTransform)));
  157.   IDAGeometryPtr myLight = 
  158.     e->UnionGeometry(e->DirectionalLight->Transform(perspTransform), e->DirectionalLight);
  159.   IDACameraPtr perspectiveCam = (e->PerspectiveCamera(1,0))->Transform(e->Compose3(e->Rotate3Anim(e->XVector3,
  160.     e->Mul(SPEED,e->LocalTime)),e->Translate3(0,0,0.2)));
  161.   IDACameraPtr parallelCam = (e->ParallelCamera(1))->Transform(e->Rotate3Anim(e->XVector3,
  162.     e->Mul(SPEED,e->LocalTime)));
  163.   IDACameraPtr camera;
  164.   camera.CreateInstance( L"DirectAnimation.DACamera");
  165.   camera->Init(e->Until(perspectiveCam, PICKEVENT,
  166.     e->Until(parallelCam, PICKEVENT, camera)));
  167.   return e->UnionGeometry(geo->Transform(e->Scale3UniformAnim(scaleFactor)),
  168.     myLight)->Render(camera);
  169. }
  170. /*
  171.  * tick
  172.  * Ask DA to sample and display the model.
  173.  */
  174. void DXA::tick() {
  175. static double startTime = 0;
  176.     struct _timeb timebuffer;
  177.     if (_view != NULL) {
  178.         _ftime( &timebuffer );
  179.         double thisTime = timebuffer.time + ( timebuffer.millitm / 1000.0 );
  180.         if ( startTime == 0 )  {
  181.             startTime = thisTime;
  182.             thisTime = 0;
  183.         }
  184.         else
  185.             thisTime -= startTime;
  186.         _view->Tick(thisTime);
  187.         _view->Render();
  188.     }
  189. }