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

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.         
  59.         GetCurrentDirectory(sizeof(szMediaBase),szMediaBase);
  60. _tcscat(szMediaBase,_T("\..\..\..\..\..\media\"));
  61. _tcscpy(szImg,szMediaBase);
  62. _tcscpy(szGeo,szMediaBase);
  63. _tcscpy(szSnd,szMediaBase);
  64. _tcscat(szImg,_T("image\"));
  65. _tcscat(szGeo,_T("geometry\"));
  66. _tcscat(szSnd,_T("sound\"));
  67.       
  68.       IDAGeometryPtr rawSphere = 
  69.         e->ImportGeometry( _bstr_t(szGeo) + _bstr_t( "sphere.wrl" ) );
  70.       IDAGeometryPtr rawCube = 
  71.         e->ImportGeometry( _bstr_t(szGeo) + _bstr_t( "cube.wrl" ) );
  72.       IDAGeometryPtr rawCone = 
  73.         e->ImportGeometry( _bstr_t(szGeo) + _bstr_t( "cone.wrl" ) );
  74.       IDAGeometryPtr rawCylinder = 
  75.         e->ImportGeometry( _bstr_t(szGeo) + _bstr_t( "cylinder.wrl" ) );
  76.       // Import a sound, supply null as the second argument since we don't
  77.       // want a length. 
  78.       IDASoundPtr snd = e->ImportSound(  _bstr_t(szSnd) + _bstr_t( "etherial.mp2" ) )->Sound->Loop();
  79.   // Size the objects down.
  80.       IDATransform3Ptr scaler = e->Scale3UniformAnim( e->DANumber( 0.25 ) );
  81.       IDAGeometryPtr sphere   = rawSphere->Transform( scaler );
  82.       IDAGeometryPtr cube     = rawCube->Transform( scaler );
  83.       IDAGeometryPtr cone     = rawCone->Transform( scaler );
  84.       IDAGeometryPtr cylinder = rawCylinder->Transform( scaler );
  85.       IDAGeometryPtr xcone    = cone->Transform( e->Rotate3Anim(
  86.         e->GetXVector3(), e->DANumber( 3.1415927 ) ) );
  87.       IDAColorPtr color1 = myColor( 0, 2, e );
  88.       IDAColorPtr color2 = myColor( 0.25, 3, e );
  89.       IDAColorPtr color3 = myColor( 0.5, 4, e );
  90.       IDAColorPtr color4 = myColor( 0.75, 1, e );
  91.       // Shapes to start with (many with time varying colors)
  92.       IDAGeometryPtr shapes[] = {
  93.         sphere->DiffuseColor( color1 ),
  94.         sphere->DiffuseColor( color1 ),
  95.         cone->DiffuseColor( color2 ),
  96.         xcone->DiffuseColor( color2 ),
  97.         cube->DiffuseColor( color3 ),
  98.         cube->DiffuseColor( color3 ),
  99.         cylinder->DiffuseColor( color4 ) };
  100.       // Places to Translate them to.
  101.       double tls[][3] = { { 0.75, 0, 0 },
  102.                          { -0.75, 0, 0 },
  103.                          { 0, 0.75, 0 },
  104.                          { 0, -0.75, 0 },
  105.                          { 0, 0, 0.75 },
  106.                          { 0, 0, -0.75 },
  107.                          { 0, 0, 0 } };
  108.       // Go ahead and accumulate up the Translated geometry by cycling
  109.       // through the arrays.
  110.       IDAGeometryPtr geo = e->EmptyGeometry;
  111.       for ( int i = 0; i < sizeof( shapes ) / sizeof( shapes[0] ); i++ ) {
  112.         IDATransform3Ptr xf = e->Translate3Anim( e->DANumber( tls[i][0] ),
  113.           e->DANumber( tls[i][1] ), e->DANumber( tls[i][2] ) );
  114.         geo = e->UnionGeometry( geo, shapes[i]->Transform( xf ) );
  115.       }
  116.       // Set the whole thing in motion
  117.       IDATransform3Ptr xf =
  118.           e->Compose3( e->Rotate3Anim( e->GetXVector3(), e->LocalTime ),
  119.             e->Compose3( e->Rotate3Anim( e->GetZVector3(), e->Mul( e->LocalTime, e->DANumber( 1.9 ) ) ),
  120.               e->Compose3( e->Rotate3Anim( e->GetYVector3(), e->Mul( e->LocalTime, e->DANumber( 3.1415927 ) ) ),
  121.                 e->Scale3UniformAnim( e->DANumber( 0.75 ) ) ) ) );
  122.       geo = geo->Transform( xf );
  123.       // Render into an image, and overlay atop a solid image.
  124.       IDAImagePtr geoIm = geometryImage( e->UnionGeometry( geo, e->DirectionalLight ), e );
  125.       IDAImagePtr model = e->Overlay( geoIm, e->SolidColorImage( e->White ) );
  126.       
  127.       // Set the size of the viewport.  Not doing this  (as done in this
  128.       // case) will render the animation accross the entire primary surface.
  129.   _view->SetViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
  130.   // Let the view draw to the primary surface.
  131.       _view->IDirectDrawSurface = ddsurf;
  132.   _view->CompositeDirectlyToTarget = FALSE;
  133.   // Start the model on the view.
  134.       _view->StartModel(model, snd, 0);
  135.     } catch (_com_error &e) {
  136.         dump_com_error( e );
  137.         return false;
  138.     }
  139.     return true;
  140. }
  141. BOOL DXA::resetDXASurfaces(IUnknown *ddsurf)
  142. {
  143.     try {
  144.         _view->IDirectDrawSurface = ddsurf;
  145.     } catch (_com_error &e) {
  146.         dump_com_error( e );
  147.         return false;
  148.     }
  149.     return true;
  150. }
  151. /* 
  152.  * geometryImage
  153.  * Renders a geometry as an image
  154.  */
  155. IDAImagePtr DXA::geometryImage( IDAGeometryPtr geo, IDAStaticsPtr e ) {
  156.     IDACameraPtr cam = e->PerspectiveCameraAnim( e->DANumber( 1 ),
  157.       e->DANumber( 0 ) )->Transform( e->Translate3Anim(
  158.       e->DANumber( 0 ), e->DANumber( 0 ), e->DANumber( 2 ) ) );
  159.     IDATransform2Ptr sc = e->Scale2UniformAnim( e->DANumber( 0.1 ) );
  160.     return geo->Render( cam )->Transform( sc );
  161.   }
  162. /*
  163.  * myColor
  164.  * Create a animated color whose saturation varies over time.
  165.  */
  166. IDAColorPtr DXA::myColor( double hue, double saturationRate,
  167.     IDAStaticsPtr e ) {
  168.     IDANumberPtr sat = e->Add( e->Mul( e->Sin( e->Mul( e->LocalTime,
  169.       e->DANumber( saturationRate ) ) ), e->DANumber( 0.5 ) ), e->DANumber( 0.5 ) );
  170.     return e->ColorHslAnim( e->DANumber( hue ), sat, e->DANumber( 0.5 ) );
  171.   }
  172. /*
  173.  * tick
  174.  * Ask DA to sample and display the model.
  175.  */
  176. void DXA::tick() {
  177. static double startTime = 0;
  178.     struct _timeb timebuffer;
  179.     if (_view != NULL) {
  180.         _ftime( &timebuffer );
  181.         double thisTime = timebuffer.time + ( timebuffer.millitm / 1000.0 );
  182.         if ( startTime == 0 )  {
  183.             startTime = thisTime;
  184.             thisTime = 0;
  185.         }
  186.         else
  187.             thisTime -= startTime;
  188.         _view->Tick(thisTime);
  189.         _view->Render();
  190.     }
  191. }