home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 39 / IOPROG_39.ISO / SOFT / sdkjava40.exe / data1.cab / fg_Samples / Samples / DirectX / d3drmviewer / ViewerCanvas.java < prev    next >
Encoding:
Java Source  |  2000-05-04  |  29.8 KB  |  1,153 lines

  1. //
  2. // (C) Copyright 1995 - 1999 Microsoft Corporation.  All rights reserved.
  3. //
  4. import java.awt.*;
  5. import java.net.URL;
  6. import java.io.File;
  7. import java.io.FilenameFilter;
  8. import com.ms.com.*;
  9. import com.ms.awt.*;
  10. import com.ms.directX.*;
  11. import com.ms.ui.*;
  12.  
  13. /////////////////////////////////////////////////////////////////////////////////////////////////////
  14. class FrameMoveData implements IUnknown
  15. {
  16.     float time;
  17.     Direct3dRMAnimationSet anim;
  18. }
  19.  
  20. //////////////////////////////////////////////////////////////////////////
  21. class FileName implements FilenameFilter 
  22. {
  23.     public String path;
  24.     public String fileName;
  25.     
  26.     FileName(String p, String n) 
  27.     {
  28.         path = p;
  29.         fileName = n;
  30.     }
  31.  
  32.     public boolean accept(File dir, String name) 
  33.     {
  34.         if(path.equals(dir.getPath()) && name.equals(fileName)) 
  35.         {
  36.             return true;
  37.         }
  38.         return false;
  39.     }
  40. }
  41.  
  42. /////////////////////////////////////////////////////////////////////////////////////////////////////
  43. public class ViewerCanvas extends Canvas implements DirectXConstants, MenuXConstants, IFrameMoveCallback, 
  44.         ILoadTextureCallback
  45. {
  46.     //////////////////////////////////////////////////////////////////////////
  47.     public void callbackFrameMove(Direct3dRMFrame obj, IUnknown punk, float delta)
  48.     {
  49.         FrameMoveData fmd = (FrameMoveData)punk;
  50.         fmd.anim.setTime(fmd.time);
  51.         fmd.time += delta;
  52.     }
  53.  
  54.     //////////////////////////////////////////////////////////////////////////
  55.     void setAnimationCallback(Direct3dRMFrame f, Direct3dRMAnimationSet animset)
  56.     {
  57.         FrameMoveData fmd = new FrameMoveData();
  58.         fmd.time = 0;
  59.         fmd.anim = animset;
  60.  
  61.         f.addMoveCallback((IFrameMoveCallback)this, fmd);
  62.     }
  63.  
  64.     public Direct3dRM                d3drm;
  65.     public DirectDrawClipper        ddclipper;
  66.     public DirectDraw                DD;                    // DirectDraw object
  67.     public DirectDrawSurface        DDSZBuffer;
  68.     public Direct3dDevice            D3DDevice;            
  69.     public Direct3d                    D3D; 
  70.     public DirectDrawPalette        DDPal;                // DirectDraw palette
  71.     public Direct3dRMFrame            scene;
  72.     public Direct3dRMFrame            camera;
  73.        public Direct3dRMFrame            mainframe;
  74.     public Direct3dRMDevice            dev;
  75.     public Direct3dRMViewport        view;
  76.     public DirectDrawSurface        ddsPrimary;            // DirectDraw primary surface
  77.     public DirectDrawSurface        ddsOffscreen;        // Offscreen rendering surface 
  78.        public Direct3dRMFrame            light;
  79.     public Direct3dRMLight            light1;
  80.     public Direct3dRMLight            light2;
  81.     public Direct3dRMMaterial        mat;
  82.     public int                        model;
  83.  
  84.     private boolean                    inblit;
  85.     private Rect                    bltrect;
  86.  
  87.     ViewerSelection    sel;
  88.     int             last_x, last_y;        // mouse positions
  89.     Viewer            tg;
  90.  
  91.     public final int MENU_FILE_ABOUT            = 1 ;
  92.     public final int MENU_FILE_OPEN             = 2 ;
  93.     public final int MENU_FILE_OPEN_ANIMSET     = 3 ; 
  94.     public final int MENU_FILE_OPEN_FRAME       = 4 ;
  95.     public final int MENU_FILE_EXIT             = 5 ;
  96.     public final int MENU_EDIT_CUT              = 6 ;
  97.     public final int MENU_EDIT_COPY             = 7 ;
  98.     public final int MENU_EDIT_PASTE            = 8 ;
  99.     public final int MENU_EDIT_DELETE           = 9 ;
  100.     public final int MENU_EDIT_COLOR            = 10;
  101.     public final int MENU_EDIT_BOXES            = 11;
  102.     public final int MENU_QUALITY_LIGHTING      = 12; // first in menu
  103.     public final int MENU_QUALITY_POINTS        = 13;
  104.     public final int MENU_QUALITY_WIREFRAME     = 14;
  105.     public final int MENU_QUALITY_SOLID         = 15;
  106.     public final int MENU_QUALITY_FLAT          = 16;
  107.     public final int MENU_QUALITY_GOURAUD       = 17;
  108.     public final int MENU_QUALITY_PHONG         = 18;
  109.     public final int MENU_MODEL_MONO            = 19;
  110.     public final int MENU_MODEL_RGB             = 20;
  111.     public final int MENU_DITHER                = 21;
  112.     public final int MENU_TEXTURE_FILTERING     = 22;
  113.     public final int MENU_LIGHT_DIRECTIONAL     = 23; 
  114.     public final int MENU_LIGHT_PARALLEL_POINT  = 24;
  115.     public final int MENU_LIGHT_POINT           = 25;
  116.     public final int MENU_LIGHT_SPOT            = 26;
  117.     public final int MENU_FOG_ENABLE            = 27;
  118.  
  119.     MenuPanel menu;
  120.  
  121.     public void attachMenu(MenuPanel menu)
  122.     {
  123.         this.menu = menu;
  124.     }
  125.  
  126.     public Dimension preferredSize() 
  127.     {
  128.         return new Dimension(640,480);
  129.     }
  130.  
  131.     //////////////////////////////////////////////////////////////////////////
  132.     public void paint(Graphics g)
  133.     {
  134.     }
  135.  
  136.     public void update(Graphics g)
  137.     {
  138.     }
  139.   
  140.     //////////////////////////////////////////////////////////////////////////
  141.     ViewerCanvas(String s, Viewer t)
  142.     {
  143.         tg  = t;
  144.         setBackground(Color.black);
  145.     }
  146.     
  147.     //////////////////////////////////////////////////////////////////////////
  148.     // Initialize everyting, cant do anything in the constructor, 
  149.     // no window created yet!
  150.     //
  151.     public void startDirect()
  152.     {
  153.         menu.CheckMenuItem(MENU_QUALITY_LIGHTING, true);
  154.         menu.CheckMenuItem(MENU_QUALITY_FLAT, true);
  155.         menu.CheckMenuItem(MENU_QUALITY_SOLID, true);
  156.         menu.CheckMenuItem(MENU_MODEL_MONO, true);
  157.  
  158.         model     = D3DCOLOR_MONO;
  159.  
  160.         d3drm        = new Direct3dRM();
  161.         sel            = new ViewerSelection(d3drm);
  162.  
  163.         CreateDevice();
  164.  
  165.         Dimension s = size();
  166.         bltrect            = new Rect();
  167.         bltrect.left    = 0;
  168.         bltrect.top     = 0;
  169.         bltrect.right   = s.width;
  170.         bltrect.bottom  = s.height;
  171.     }
  172.  
  173.     //////////////////////////////////////////////////////////////////////////
  174.     int ShadeModeToMenuItem(int sm)
  175.     {
  176.         switch (sm) 
  177.         {
  178.             case D3DRMSHADE_FLAT:
  179.                 return MENU_QUALITY_FLAT;
  180.  
  181.             case D3DRMSHADE_GOURAUD:
  182.                 return MENU_QUALITY_GOURAUD;
  183.  
  184.             case D3DRMSHADE_PHONG:
  185.                 return MENU_QUALITY_PHONG;
  186.         }
  187.         return -1;
  188.     }
  189.  
  190.     //////////////////////////////////////////////////////////////////////////
  191.     void SetShadeMode(int sm)
  192.     {
  193.         int quality = dev.getQuality();
  194.         int oldsm = (int)(quality & D3DRMSHADE_MASK);
  195.  
  196.         menu.CheckMenuItem(ShadeModeToMenuItem(oldsm),  false );
  197.         menu.CheckMenuItem(ShadeModeToMenuItem(sm),        true );
  198.  
  199.         quality = (quality & ~D3DRMSHADE_MASK) | sm;
  200.         dev.setQuality(quality);
  201.     }
  202.  
  203.     //////////////////////////////////////////////////////////////////////////
  204.     String OpenNewFile(String title)
  205.     {
  206.         FileDialog fileDialog = new FileDialog(tg.frame, title, FileDialog.LOAD);
  207.         
  208.         // set the fileNameFilter in this FileDialog object
  209.         FileName fileName = new FileName("~/", "*.x");
  210.         fileDialog.setFilenameFilter(fileName);
  211.         
  212.         // set the directory in the FileDialog object
  213.         fileDialog.setDirectory("C:\\dxsdk\\sdk\\media");
  214.         
  215.         // set the file in the FileDialog object
  216.         fileDialog.setFile("*.x");
  217.                 
  218.         // show this fileDialog to the screen
  219.         fileDialog.show();
  220.         return fileDialog.getFile();
  221.     }
  222.     
  223.     //////////////////////////////////////////////////////////////////////////
  224.     int FillModeToMenuItem(int fm)
  225.     {
  226.         switch (fm) 
  227.         {
  228.             case D3DRMFILL_POINTS:
  229.                 return MENU_QUALITY_POINTS;
  230.  
  231.             case D3DRMFILL_WIREFRAME:
  232.                 return MENU_QUALITY_WIREFRAME;
  233.  
  234.             case D3DRMFILL_SOLID:
  235.                 return MENU_QUALITY_SOLID;
  236.         }
  237.         return -1;
  238.     }
  239.  
  240.     //////////////////////////////////////////////////////////////////////////
  241.     void SetFillMode(int fm)
  242.     {
  243.         int quality = dev.getQuality();
  244.         int oldfm = (int)(quality & D3DRMFILL_MASK);
  245.  
  246.         menu.CheckMenuItem(FillModeToMenuItem(oldfm), false);
  247.         menu.CheckMenuItem(FillModeToMenuItem(fm),      true);
  248.  
  249.          quality = (quality & ~D3DRMFILL_MASK) | fm;
  250.         dev.setQuality(quality);
  251.     }
  252.  
  253.     //////////////////////////////////////////////////////////////////////////
  254.     void SetModel(int newmodel)
  255.     {
  256.         if (model != newmodel) 
  257.         {
  258.             try 
  259.             {
  260.                 tg.rebuilddevice = true;
  261.                 tg.model    = model;
  262.                 tg.width    = dev.getWidth();
  263.                 tg.height    = dev.getHeight();
  264.  
  265.                 model = newmodel;
  266.             }
  267.             catch( ComException ce)
  268.             {
  269.                 // Device failed to build exception 
  270.             }
  271.         }
  272.         menu.CheckMenuItem((model==D3DCOLOR_MONO)?MENU_MODEL_MONO:MENU_MODEL_RGB, true);
  273.     }
  274.  
  275.     //////////////////////////////////////////////////////////////////////////
  276.     void ToggleDither()
  277.     {
  278.         int dither = dev.getDither();
  279.         boolean checked;
  280.         
  281.         dither = (dither == 0) ?1 :0;
  282.         dev.setDither(dither);
  283.  
  284.         if (dither != 0) 
  285.             checked = true;
  286.         else 
  287.             checked = false;
  288.  
  289.         menu.CheckMenuItem(MENU_DITHER, checked);
  290.     }
  291.  
  292.     void ToggleFog()
  293.     {
  294.         int fog = scene.getSceneFogEnable();
  295.         boolean checked;
  296.         
  297.         fog = (fog == 0) ?1 :0;
  298.         
  299.         if (fog != 0) 
  300.         {
  301.             checked = true;
  302.             setFog(1, 0, 5, 15, 0);
  303.         }
  304.         else 
  305.         {
  306.             checked = false;
  307.             setFog(0,0,0,0,0);
  308.         }
  309.         menu.CheckMenuItem(MENU_FOG_ENABLE, checked);
  310.     }
  311.  
  312.     void ToggleTextureFiltering()
  313.     {
  314.         int tq = dev.getTextureQuality();
  315.         boolean checked;
  316.  
  317.         if (tq == D3DRMTEXTURE_NEAREST)
  318.             tq = D3DRMTEXTURE_LINEAR;
  319.         else
  320.             tq = D3DRMTEXTURE_NEAREST;
  321.  
  322.         dev.setTextureQuality(tq);
  323.  
  324.         if (tq == D3DRMTEXTURE_LINEAR) 
  325.             checked = true;
  326.         else 
  327.             checked = false;
  328.  
  329.         menu.CheckMenuItem(MENU_TEXTURE_FILTERING, checked);
  330.     }
  331.  
  332.     void ToggleLighting()
  333.     {
  334.         int quality = dev.getQuality();
  335.         int mode = (int)(quality & D3DRMLIGHT_MASK);
  336.  
  337.         if (mode == D3DRMLIGHT_ON)
  338.             mode = D3DRMLIGHT_OFF;
  339.         else
  340.             mode = D3DRMLIGHT_ON;
  341.  
  342.         menu.CheckMenuItem(MENU_QUALITY_LIGHTING, (mode == D3DRMLIGHT_ON ?true:false));
  343.  
  344.         quality = (quality & ~D3DRMLIGHT_MASK) | mode;
  345.         dev.setQuality(quality);
  346.     }
  347.  
  348.     //////////////////////////////////////////////////////////////////////////
  349.     void CreateLight(int wparam)
  350.     {
  351.         Direct3dRMMeshBuilder builder = null;
  352.         Direct3dRMLight light = null;
  353.         Direct3dRMFrame f = null;
  354.  
  355.         builder = d3drm.createMeshBuilder();
  356.  
  357.         if (wparam == MENU_LIGHT_DIRECTIONAL) 
  358.         {
  359.             builder.loadFromFileByPos(tg.getFileName("camera.x"), 0, 0, null, null);
  360.  
  361.             builder.setQuality(D3DRMRENDER_UNLITFLAT);
  362.             
  363.             light = d3drm.createLightRGB(D3DRMLIGHT_DIRECTIONAL, 1.0F, 1.0F, 1.0F);
  364.         } 
  365.         else if (wparam == MENU_LIGHT_PARALLEL_POINT) 
  366.         {
  367.             builder.loadFromFileByPos(tg.getFileName("sphere2.x"), 0, 0, null, null);
  368.  
  369.             builder.setQuality(D3DRMRENDER_UNLITFLAT);
  370.             builder.scale(0.2F, 0.2F, 0.2F);
  371.             light = d3drm.createLightRGB (D3DRMLIGHT_PARALLELPOINT, 
  372.                         1.0F, 1.0F, 1.0F);
  373.         } 
  374.         else if (wparam == MENU_LIGHT_POINT) 
  375.         {
  376.             builder.loadFromFileByPos(tg.getFileName("sphere2.x"), 0, 0, null, null);
  377.  
  378.             builder.setQuality(D3DRMRENDER_UNLITFLAT);
  379.  
  380.             builder.scale( 0.2F, 0.2F, 0.2F);
  381.  
  382.             light = d3drm.createLightRGB (D3DRMLIGHT_POINT, 
  383.                                             1.0F, 1.0F, 1.0F);
  384.  
  385.         } else if (wparam == MENU_LIGHT_SPOT) 
  386.         {
  387.             builder.loadFromFileByPos(tg.getFileName("camera.x"), 0, 0, null, null);
  388.  
  389.             builder.setQuality(D3DRMRENDER_UNLITFLAT);
  390.  
  391.             light = d3drm.createLightRGB( D3DRMLIGHT_SPOT, 1.0F,1.0F,1.0F);
  392.         }
  393.  
  394.         f = d3drm.createFrame(scene);
  395.         f.setPosition(camera,0.0F,0.0F,10.0F);
  396.         f.addVisualMeshBuilder(builder);
  397.         f.addLight(light);
  398.     }
  399.  
  400.     //////////////////////////////////////////////////////////////////////////
  401.     public void LoadMesh(String file)
  402.        {
  403.         Direct3dRMMeshBuilder builder;
  404.  
  405.         builder = d3drm.createMeshBuilder();
  406.         builder.loadFromFileByPos(tg.getFileName(file), 0, 0, (ILoadTextureCallback)this, null);
  407.  
  408.         PlaceMesh(builder);
  409.     }
  410.  
  411.     void LoadFrameHierarchy(String filename)
  412.     {
  413.         Direct3dRMMeshBuilder builder;
  414.         Direct3dRMFrame f;
  415.  
  416.         if ( filename == "castle.x" )
  417.         {
  418.             D3dRMBox box = new D3dRMBox();
  419.  
  420.             f = d3drm.createFrame(scene);
  421.             f.loadFromFileByPos(tg.getFileName(filename), 0, 0, (ILoadTextureCallback)this, null);
  422.  
  423.             builder = d3drm.createMeshBuilder();
  424.             builder.setPerspective(1);
  425.             builder.addFrame(f);
  426.             builder.getBox(box);
  427.  
  428.             float maxDim = 0.0F;
  429.  
  430.             maxDim = box.xMax - box.xMin;
  431.             if (box.yMax - box.yMin > maxDim) 
  432.                 maxDim = box.yMax - box.yMin;
  433.  
  434.             if (box.zMax - box.zMin > maxDim)
  435.                 maxDim = box.zMax - box.zMin;
  436.  
  437.             f.addScale(D3DRMCOMBINE_BEFORE, 16.0F/maxDim, 16.0F/maxDim, 16.0F/maxDim);
  438.             f.setPosition(scene, 0.0F, -1.0F, 5.0F);
  439.         }
  440.         else 
  441.         {
  442.             f = d3drm.createFrame(scene);
  443.             f.loadFromFileByPos(tg.getFileName(filename), 0, 0, (ILoadTextureCallback)this, null);
  444.             ScaleScene(f, false );
  445.         }
  446.     }
  447.  
  448.     void LoadAnimationSet(String filename)
  449.     {
  450.         Direct3dRMAnimationSet lpAnimSet;
  451.         Direct3dRMFrame f;
  452.  
  453.         //
  454.         // Create a new parent frame for the animation, load it, and set up 
  455.         // the callback 
  456.         //
  457.         f = d3drm.createFrame(scene);
  458.         lpAnimSet = d3drm.createAnimationSet();
  459.  
  460.         lpAnimSet.loadFromFileByPos(tg.getFileName(filename), 0, 0, (ILoadTextureCallback)this, null, f);
  461.  
  462.         ScaleScene(f, false);
  463.  
  464.         setAnimationCallback(f, lpAnimSet);
  465.     }
  466.  
  467.     //////////////////////////////////////////////////////////////////////////
  468.     void ScaleScene(Direct3dRMFrame f, boolean castlespecialcase )
  469.     {
  470.           Direct3dRMMeshBuilder  builder;
  471.         D3dRMBox box = new D3dRMBox();
  472.  
  473.         float maxDim = 0.0F;
  474.  
  475.         builder = d3drm.createMeshBuilder();
  476.         builder.addFrame(f);
  477.         builder.getBox(box);
  478.  
  479.         maxDim = box.xMax - box.xMin;
  480.         if (box.yMax - box.yMin > maxDim) 
  481.             maxDim = box.yMax - box.yMin;
  482.  
  483.         if (box.zMax - box.zMin > maxDim)
  484.             maxDim = box.zMax - box.zMin;
  485.  
  486.         if ( castlespecialcase )
  487.         {
  488.             f.addScale(D3DRMCOMBINE_BEFORE, 16.0F/maxDim, 16.0F/maxDim, 16.0F/maxDim);
  489.             f.setPosition(scene, 0.0F, -1.0F, 5.0F);
  490.         }
  491.         else
  492.         {
  493.             f.addScale(D3DRMCOMBINE_BEFORE, 8.0F/maxDim, 8.0F/maxDim, 8.0F/maxDim);
  494.             f.setPosition(scene, 0.0F, 0.0F, 15.0F);
  495.         }
  496.     }
  497.  
  498.     void setFog( int enable, int mode, float start, float end, float desity )
  499.     {
  500.         scene.setSceneFogEnable(enable);
  501.         if ( enable > 0 )
  502.         {
  503.             scene.setSceneFogMode(mode);
  504. //            scene.setSceneFogParams(start,end,desity);
  505.             scene.setSceneFogParams(start,end,1);
  506.             scene.setSceneFogColor(-1);
  507.             scene.setSceneBackgroundRGB(1.0f,1.0f,1.0f);
  508.         }
  509.         else
  510.         {
  511.             scene.setSceneBackgroundRGB(0.0f,0.0f,0.0f);
  512.         }
  513.     }
  514.  
  515.     //////////////////////////////////////////////////////////////////////////
  516.     //
  517.     // Place an object in front of the camera.
  518.     //
  519.     void PlaceMesh( Direct3dRMMeshBuilder mesh)
  520.     {
  521.         Direct3dRMFrame f;
  522.  
  523.         f = d3drm.createFrame(scene);
  524.         f.addVisualMeshBuilder(mesh);
  525.         f.setPosition(camera, 0.0F, 0.0F, 15.0F);
  526.     }
  527.  
  528.  
  529.     //////////////////////////////////////////////////////////////////////////
  530.  
  531.     static final int DDBD_1 = 0x00004000;
  532.     static final int DDBD_2 = 0x00002000;
  533.     static final int DDBD_4 = 0x00001000;
  534.     static final int DDBD_8 = 0x00000800;
  535.     static final int DDBD_16 = 0x00000400;
  536.     static final int DDBD_24 = 0x00000200;
  537.     static final int DDBD_32 = 0x00000100;
  538.     
  539.     int bppToddbd(int bpp)
  540.     {
  541.         switch(bpp) 
  542.         {    
  543.             case 1:        return DDBD_1;
  544.             case 2:        return DDBD_2;
  545.             case 4:        return DDBD_4;
  546.             case 8:        return DDBD_8;
  547.             case 16:    return DDBD_16;
  548.             case 24:    return DDBD_24;
  549.             case 32:    return DDBD_32;
  550.         }
  551.         return 0;
  552.     }
  553.     
  554.     //////////////////////////////////////////////////////////////////////////
  555.     //
  556.     // Create the device and viewport.
  557.     //
  558.     // uses global this and info
  559.     //
  560.     void CreateDevice()
  561.     {
  562.         _Guid g;
  563.  
  564.         Dimension s = size();
  565.  
  566.         //
  567.         // Create a DirectDraw object
  568.         //
  569.         DD = new DirectDraw();
  570.  
  571.         //
  572.         // The level is used to direct Direct Draw what 
  573.         // window behaviors are allowed, this is used
  574.         // primarly to allow Direct Draw applications
  575.         // to take over the whole screen.  Since 
  576.         // we are security bound in Java this value
  577.         // must allways be set to DDSCL_NORMAL
  578.         //
  579.         DD.setCooperativeLevel(this, DDSCL_NORMAL);
  580.  
  581.         //
  582.         // Create the D3d device interface associtated with the DD draw object
  583.         //
  584.         D3D = DD.createD3D();
  585.  
  586.         //
  587.         // Create the primary surface
  588.         //
  589.         DDSurfaceDesc ddsd = new DDSurfaceDesc();
  590.         ddsd.flags   = DDSD_CAPS;
  591.         ddsd.ddsCaps = DDSCAPS_PRIMARYSURFACE;
  592.         ddsPrimary     = DD.createSurface(ddsd);
  593.  
  594.         //
  595.         // Create and Set the clipper for the primary surface
  596.         //
  597.         ddclipper = DD.createClipper(0);
  598.         ddclipper.setComponent(this);    
  599.         ddsPrimary.setClipper( ddclipper );
  600.  
  601.         //
  602.         // Create an offscreen rendering surface
  603.         //
  604.         ddsd.flags   = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
  605.         ddsd.ddsCaps = DDSCAPS_3DDEVICE | DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
  606.         ddsd.width   = s.width;
  607.         ddsd.height  = s.height;
  608.         ddsOffscreen = DD.createSurface(ddsd);
  609.  
  610.         ddsd.flags   = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_ZBUFFERBITDEPTH;
  611.         ddsd.ddsCaps = DDSCAPS_ZBUFFER | DDSCAPS_SYSTEMMEMORY;
  612.         ddsd.width   = s.width;    
  613.         ddsd.height  = s.height; 
  614.         ddsd.zbufferBitDepth = 16;
  615.         DDSZBuffer     = DD.createSurface(ddsd);
  616.  
  617.         ddsOffscreen.addAttachedSurface(DDSZBuffer);
  618.  
  619.         //
  620.         // This will attach the system palette to the offscreen surface
  621.         //
  622.         try
  623.         {
  624.             DDPal = DD.createPalette(DDPCAPS_8BIT);
  625.             if( DDPal != null)
  626.             {
  627.                 ddsPrimary.setPalette(DDPal);
  628.                 ddsOffscreen.setPalette(DDPal);
  629.             }
  630.            }
  631.            catch(Exception e)
  632.            {
  633.             // Failed palette probably not in 8-bit mode
  634.            }
  635.  
  636.         try
  637.         {
  638.             g = D3D.findDeviceForColorModel(model, 0);
  639.         }
  640.            catch(Exception e)
  641.            {
  642.             // Try again just in case we are running on Minidrivers that 
  643.             // don't support MOMO modes 
  644.             g = D3D.findDeviceForColorModel(D3DCOLOR_RGB, 0);
  645.             model = D3DCOLOR_RGB;
  646.            }
  647.  
  648.         // 
  649.         // Create the D3D Device object associated 
  650.         // with the offscreen surface
  651.         //
  652.         D3DDevice = ddsOffscreen.create3DDevice(g);
  653.  
  654.         dev = d3drm.createDeviceFromD3D(D3D,D3DDevice);
  655.  
  656.         switch (D3D.systemBpp())
  657.         {
  658.             case 1:
  659.                 dev.setShades(4);
  660.                 d3drm.setDefaultTextureShades(4);
  661.                 break;
  662.                 
  663.             case 16:
  664.                 dev.setShades(32);
  665.                 d3drm.setDefaultTextureColors(64);
  666.                 d3drm.setDefaultTextureShades(32);
  667.                 dev.setDither(0);
  668.                 break;
  669.                 
  670.             case 24:
  671.             case 32:
  672.                 dev.setShades(256);
  673.                 d3drm.setDefaultTextureColors(64);
  674.                 d3drm.setDefaultTextureShades(256);
  675.                 dev.setDither(0);
  676.                 break;
  677.                 
  678.             default:
  679.                 dev.setDither(0);
  680.         }
  681.  
  682.         dev.setQuality(D3DRMRENDER_FLAT);
  683.         dev.setTextureQuality( D3DRMTEXTURE_NEAREST );
  684.         
  685.         CreateScene();
  686.  
  687.         view = d3drm.createViewport(dev, camera, 0, 0, dev.getWidth(), dev.getHeight());
  688.         view.setBack(5000.0F);
  689.     }
  690.  
  691.     //////////////////////////////////////////////////////////////////////////
  692.     // Regenerate the device if the color model changes or the window 
  693.     // size changes.
  694.     //
  695.     void RebuildDevice(int model, int width, int height)
  696.     {
  697.         _Guid g;
  698.  
  699.         //
  700.         // Save off previous device data 
  701.         //
  702.         int old_dither  = dev.getDither();
  703.         int old_quality = dev.getQuality();
  704.            int old_shades  = dev.getShades();
  705.         int old_texturequailty = dev.getTextureQuality();
  706.  
  707.         //
  708.         // Make sure we release old devices 
  709.         //
  710.         view = null;
  711.         dev = null;
  712.         DDSZBuffer = null;
  713.         ddsOffscreen = null;
  714.         D3DDevice = null;
  715.         System.gc();
  716.  
  717.         //
  718.         // Create an offscreen rendering surface
  719.         //
  720.         DDSurfaceDesc ddsd = new DDSurfaceDesc();
  721.         ddsd.flags   = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
  722.         ddsd.ddsCaps = DDSCAPS_3DDEVICE | DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
  723.         ddsd.width   = width;    
  724.         ddsd.height  = height; 
  725.         ddsOffscreen = DD.createSurface(ddsd);
  726.  
  727.         ddsd.flags   = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_ZBUFFERBITDEPTH;
  728.         ddsd.ddsCaps = DDSCAPS_ZBUFFER | DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
  729.         ddsd.width   = width;    
  730.         ddsd.height  = height; 
  731.         ddsd.zbufferBitDepth = 16;
  732.         DDSZBuffer     = DD.createSurface(ddsd);
  733.  
  734.         ddsOffscreen.addAttachedSurface(DDSZBuffer);
  735.  
  736.         try
  737.         {
  738.             ddsOffscreen.setPalette(DDPal);
  739.            }
  740.            catch(Exception e)
  741.            {
  742.             // setpalette failed normal cause display not in 8-bit mode
  743.            }
  744.  
  745.         try
  746.         {
  747.             g = D3D.findDeviceForColorModel(model, 0);
  748.         }
  749.            catch(Exception e)
  750.            {
  751.             // Try again just in case we are running on DirectX Minidrivers that 
  752.             // dose not support MONO lighting model
  753.             g = D3D.findDeviceForColorModel(D3DCOLOR_RGB, 0);
  754.             model = D3DCOLOR_RGB;
  755.            }
  756.  
  757.         // 
  758.         // Create the D3D Device object associated 
  759.         // with the offscreen surface
  760.         //
  761.         D3DDevice = ddsOffscreen.create3DDevice(g);
  762.         dev = d3drm.createDeviceFromD3D(D3D,D3DDevice);
  763.  
  764.         //
  765.         // Restore the previous devices values 
  766.         //
  767.         dev.setDither(old_dither);
  768.         dev.setQuality(old_quality);
  769.         dev.setShades(old_shades);
  770.         dev.setTextureQuality( old_texturequailty );
  771.  
  772.         //
  773.         // Create the new viewport 
  774.         //
  775.         view = d3drm.createViewport(dev,camera,0,0,width,height);
  776.         view.setBack(5000.0F);
  777.  
  778.         //
  779.         // Reset the blt rects in case the view size has changed
  780.         // then start rendering again.
  781.         bltrect.left   = 0;
  782.         bltrect.top    = 0;
  783.         bltrect.right  = width;
  784.         bltrect.bottom = height;
  785.     }
  786.  
  787.     //////////////////////////////////////////////////////////////////////////
  788.     public Direct3dRMTexture callbackLoadTexture(String name, IUnknown args)
  789.     {
  790.         int ext = name.lastIndexOf(".");
  791.  
  792.         if (ext != -1) 
  793.         {
  794.             String fileExtension = name.substring(ext);
  795.             fileExtension.toLowerCase();
  796.             if( fileExtension.equals(".ppm") == true || fileExtension.equals(".bmp") == true )
  797.             {
  798.                 return d3drm.loadTexture(tg.getFileName(name));
  799.             }
  800.         }
  801.         return null;
  802.     }
  803.     
  804.     //////////////////////////////////////////////////////////////////////////
  805.     void CreateScene()
  806.     {
  807.         Direct3dRMMeshBuilder    builder;
  808.  
  809.         scene = d3drm.createFrame(null);
  810.         light1     = d3drm.createLightRGB(D3DRMLIGHT_DIRECTIONAL, 1.0F, 1.0F, 1.0F);
  811.         light2     = d3drm.createLightRGB(D3DRMLIGHT_AMBIENT, 0.1F, 0.1F, 0.1F);
  812.         light      = d3drm.createFrame(scene);
  813.  
  814.         light.setPosition(scene, 2.0F, 2.0F, 5.0F);
  815.         light.setOrientation(scene, -1.0F, -1.0F, 1.0F, 0.0F, 1.0F, 0.0F);
  816.         light.addLight(light1);
  817.  
  818.         scene.addLight(light2);
  819.  
  820.         builder = d3drm.createMeshBuilder();
  821.         builder.loadFromFileByPos(tg.getFileName("camera.x"), 0, 0, null, null);
  822.         builder.setQuality(D3DRMRENDER_UNLITFLAT);
  823.         light.addVisualMeshBuilder(builder);
  824.  
  825.         mainframe = d3drm.createFrame(scene);
  826.         mainframe.setRotation(scene, 0.0F, 1.0F, 0.0F, -0.02F);
  827.         mainframe.setPosition(scene, 0.0F, 0.0F, 10.0F);
  828.  
  829.         builder = d3drm.createMeshBuilder();
  830.         builder.loadFromFileByPos(tg.getFileName("mslogo.x"), 0, 0, (ILoadTextureCallback)this, null);
  831.  
  832.         builder.setColorRGB(0.8F, 0.8F, 0.8F);
  833.         
  834.         mat = d3drm.createMaterial(10.0F);
  835.         builder.setMaterial(mat);
  836.         
  837.         mainframe.addVisualMeshBuilder(builder);
  838.  
  839.         camera = d3drm.createFrame(scene);
  840.         camera.setPosition(scene, 0.0F, 0.0F, 0.0F);
  841.     }
  842.  
  843.     //////////////////////////////////////////////////////////////////////////
  844.     public boolean mouseDown(Event e, int x, int y)
  845.     {
  846.         //
  847.         // Find which object was selected 
  848.         //
  849.            sel.FindAndSelectVisual(view, x, y);
  850.         last_x = x;
  851.            last_y = y;
  852.  
  853.         //
  854.         // Stop obecjt if it is a left click
  855.         if( (e.modifiers & 4) == 0 )
  856.         {
  857.             //
  858.             // Stop the rotation
  859.             //
  860.             Direct3dRMFrame sFrame = sel.SelectedFrame();
  861.             
  862.             if ( sFrame != null )
  863.                  sFrame.setRotation(scene, 0.0F, 1.0F, 0.0F, 0.0F);
  864.  
  865.             return true;
  866.         }
  867.         return false;
  868.     }
  869.  
  870.     //////////////////////////////////////////////////////////////////////////
  871.     public boolean mouseDrag(Event e, int x, int y)
  872.     {
  873.         float delta_x, delta_y;
  874.         
  875.         Direct3dRMFrame    sFrame = sel.SelectedFrame();
  876.         if( sFrame != null )
  877.         {
  878.             if( ((e.modifiers & 4) != 0) )
  879.             {
  880.                 // right mouse button
  881.                 D3dVector p1 = new D3dVector();
  882.                 D3dRMVector4d p2 = new D3dRMVector4d();
  883.  
  884.                 delta_x = x - last_x;
  885.                 delta_y = y - last_y;
  886.                 last_x  = x;
  887.                 last_y  = y;
  888.                 sFrame.getPosition(scene, p1);
  889.                 view.transform(p2, p1);
  890.                 p2.x += delta_x*p2.w;
  891.                 p2.y += delta_y*p2.w;
  892.                 view.inverseTransform(p1, p2);
  893.                 sFrame.setPosition(scene, p1.x, p1.y, p1.z);
  894.             }
  895.             else if( ((e.modifiers & 4)==0) )
  896.             {
  897.                 delta_x = x - last_x;
  898.                 delta_y = -(y - last_y);
  899.                 last_x = x;
  900.                 last_y = y;
  901.  
  902.                 double radius = 50;
  903.                 double delta_r = Math.sqrt(delta_x * delta_x + delta_y * delta_y);
  904.                 double denom = Math.sqrt(radius * radius + delta_r * delta_r);
  905.  
  906.                 if (delta_r != 0 && denom != 0) 
  907.                 {
  908.                     sFrame.setRotation(    camera,  
  909.                         (float)(delta_y/delta_r),
  910.                         (float)(-delta_x/delta_r), 
  911.                         0.0F, 
  912.                         (float)(delta_r/denom) );
  913.                 }
  914.             }
  915.         }
  916.         return true;
  917.     }
  918.  
  919.     //////////////////////////////////////////////////////////////////////////
  920.     public boolean keyUp(Event e, int key)
  921.     {
  922.         switch (key)
  923.         {
  924.             case Event.DELETE:
  925.                 sel.DeleteVisual();
  926.                 break;
  927.             case Event.PGUP:
  928.             case Event.PGDN:
  929.             case Event.UP:
  930.             case Event.DOWN:
  931.             case Event.LEFT:
  932.             case Event.RIGHT:
  933.                 camera.setVelocity(scene, 0.0F, 0.0F, 0.0F, 0);
  934.             break;
  935.  
  936.             case '+':
  937.             case '-':
  938.                 Direct3dRMFrame sFrame = sel.SelectedFrame();
  939.                 if (sFrame != null)
  940.                     sFrame.setVelocity(scene, 0.0F, 0.0F, 0.0F, 0);
  941.             break;
  942.         }
  943.         return true;
  944.     }
  945.  
  946.     //////////////////////////////////////////////////////////////////////////
  947.     public boolean keyDown(Event e, int key)
  948.     {
  949.         Direct3dRMFrame       sFrame  = sel.SelectedFrame();
  950.         Direct3dRMMeshBuilder sVisual = sel.SelectedVisual();
  951.  
  952.         D3dVector dir   = new D3dVector();
  953.         D3dVector up    = new D3dVector();
  954.          D3dVector right = new D3dVector();
  955.  
  956.         camera.getOrientation(scene, dir, up);
  957.         d3drm.vectorCrossProduct(right, up, dir);
  958.  
  959.         up.x    /= 4.0F;
  960.         up.y    /= 4.0F;
  961.         up.z    /= 4.0F;
  962.         right.x /= 4.0F;
  963.         right.y /= 4.0F;
  964.         right.z /= 4.0F;
  965.  
  966.         switch(key)
  967.         {
  968.             case Event.PGUP:
  969.                 camera.setVelocity(scene, dir.x, dir.y, dir.z, 0); 
  970.                 break;
  971.  
  972.             case Event.PGDN:
  973.                 camera.setVelocity(scene, -dir.x, -dir.y, -dir.z, 0);
  974.                 break;
  975.                  
  976.             case Event.UP:
  977.                 camera.setVelocity(scene, up.x, up.y, up.z, 0);
  978.                 break;
  979.  
  980.             case Event.DOWN:
  981.                 camera.setVelocity(scene, -up.x, -up.y, -up.z, 0);
  982.                 break;
  983.  
  984.             case Event.RIGHT:
  985.                 camera.setVelocity(scene, right.x, right.y, right.z, 0);
  986.                 break;
  987.  
  988.             case Event.LEFT:
  989.                 camera.setVelocity(scene, -right.x, -right.y, -right.z, 0);
  990.                 break;
  991.  
  992.             case '+':
  993.                 if ( sFrame != null )
  994.                     sFrame.setVelocity(scene, dir.x, dir.y, dir.z, 0);
  995.                 break;
  996.  
  997.             case '-':
  998.                 if ( sFrame != null )
  999.                     sFrame.setVelocity(scene, -dir.x, -dir.y, -dir.z, 0);
  1000.                 break;
  1001.  
  1002.             case '/':
  1003.                 if ( sVisual != null )
  1004.                 {
  1005.                     sVisual.scale(0.9F, 0.9F, 0.9F);
  1006.                     sel.SelectVisual(sVisual, sFrame);
  1007.                 }
  1008.                 break;
  1009.  
  1010.             case '*':
  1011.                 if ( sVisual != null )
  1012.                 {
  1013.                     sVisual.scale(1.1F, 1.1F, 1.1F);
  1014.                     sel.SelectVisual(sVisual, sFrame);
  1015.                 }
  1016.                 break;
  1017.         }
  1018.         return true;
  1019.     }
  1020.  
  1021.     //////////////////////////////////////////////////////////////////////////
  1022.     public boolean MenuAction(int key)
  1023.     {
  1024.         String file;
  1025.         switch(key)
  1026.         {
  1027.             case MENU_LIGHT_DIRECTIONAL:
  1028.             case MENU_LIGHT_PARALLEL_POINT:
  1029.             case MENU_LIGHT_POINT:
  1030.             case MENU_LIGHT_SPOT:
  1031.                 CreateLight(key);
  1032.                 break;
  1033.             
  1034.             case MENU_FILE_OPEN:
  1035.                 file = OpenNewFile("Open a Mesh file");
  1036.                  if (file != null)
  1037.                       LoadMesh(file);
  1038.                  break;
  1039.  
  1040.             case MENU_FILE_OPEN_ANIMSET:
  1041.                 file = OpenNewFile("Open Animation ...");
  1042.                 if (file != null) 
  1043.                       LoadAnimationSet(file);
  1044.                 break;
  1045.  
  1046.             case MENU_FILE_OPEN_FRAME:
  1047.                 file = OpenNewFile("Open Frame ...");
  1048.                 if (file != null) 
  1049.                     LoadFrameHierarchy(file);
  1050.                   break;
  1051.  
  1052.             case MENU_EDIT_CUT:
  1053.                 sel.CutVisual();
  1054.                 break;
  1055.  
  1056.             case MENU_EDIT_COPY:
  1057.                 sel.CopyVisual();
  1058.                 break;
  1059.  
  1060.             case MENU_EDIT_PASTE:
  1061.                 sel.PasteVisual(scene);
  1062.                 break;
  1063.  
  1064.             case MENU_EDIT_DELETE:
  1065.                 sel.DeleteVisual();
  1066.                 break;
  1067.  
  1068.             case MENU_QUALITY_LIGHTING:
  1069.                 ToggleLighting();
  1070.                 break;
  1071.  
  1072.             case MENU_QUALITY_POINTS:
  1073.                 SetFillMode(D3DRMFILL_POINTS);
  1074.                 break;
  1075.  
  1076.             case MENU_QUALITY_WIREFRAME:
  1077.                 SetFillMode(D3DRMFILL_WIREFRAME);
  1078.                 break;
  1079.  
  1080.             case MENU_QUALITY_SOLID:
  1081.                 SetFillMode(D3DRMFILL_SOLID);
  1082.                 break;
  1083.  
  1084.             case MENU_QUALITY_FLAT:
  1085.                 SetShadeMode(D3DRMSHADE_FLAT);
  1086.                 break;
  1087.  
  1088.             case MENU_QUALITY_GOURAUD:
  1089.                 SetShadeMode(D3DRMSHADE_GOURAUD);
  1090.                 break;
  1091.  
  1092.             case MENU_QUALITY_PHONG:
  1093.                 SetShadeMode(D3DRMSHADE_PHONG);
  1094.                 break;
  1095.  
  1096.             case MENU_MODEL_MONO:
  1097.                 SetModel(D3DCOLOR_MONO);
  1098.                 break;
  1099.  
  1100.             case MENU_MODEL_RGB:
  1101.                 SetModel(D3DCOLOR_RGB);
  1102.                 break;
  1103.  
  1104.             case MENU_DITHER:
  1105.                 ToggleDither();
  1106.                 break;
  1107.  
  1108.             case MENU_FOG_ENABLE:
  1109.                 ToggleFog();
  1110.                 break;
  1111.  
  1112.             case MENU_TEXTURE_FILTERING:
  1113.                 ToggleTextureFiltering();
  1114.                 break;
  1115.  
  1116.             default:
  1117.                 return false;
  1118.         }
  1119.         return true;
  1120.     }
  1121.  
  1122.     //////////////////////////////////////////////////////////////////////////
  1123.     public boolean isbliting()
  1124.     {
  1125.         return inblit;
  1126.     }
  1127.  
  1128.     //////////////////////////////////////////////////////////////////////////
  1129.     void Render() 
  1130.     {
  1131.         inblit = true;
  1132.  
  1133.         //
  1134.         // Actually do the render, 
  1135.         // move the scene one tick
  1136.         // clear the viewport
  1137.         // then render the view
  1138.         //
  1139.         scene.move(1.0F);
  1140.         view.clear();
  1141.         view.render(scene);
  1142.  
  1143.         //
  1144.         // Blit the Offscreen surface attached to
  1145.         // the Viewport to the screen 
  1146.         // 
  1147.            ddsPrimary.blt(bltrect, ddsOffscreen, bltrect, DDBLT_WAIT);
  1148.  
  1149.         inblit = false;
  1150.     }
  1151. }
  1152.  
  1153.