- Main Page
- Packages
- Classes
- Files

- File List
- File Members

# D:/guillaume/guillara/3D/DXGfx/DXCommon/wdxmutmesh.cs

Go to the documentation of this file.

    00001 //--------------------------------------------------------------------------------------
    00002 // File: DXMUTMesh.cs
    00003 //
    00004 // Support code for loading DirectX .X files.
    00005 //
    00006 // Copyright (c) Microsoft Corporation. All rights reserved.
    00007 //--------------------------------------------------------------------------------------
    00008 using System;
    00009 using Microsoft.DirectX;
    00010 using Microsoft.DirectX.Direct3D;
    00011
    00012 namespace Microsoft.Samples.DirectX.UtilityToolkit
    00013 {
    00015     public sealed class FrameworkMesh : IDisposable
    00016     {
    00017         #region Instance Data
    00018         private string meshFileName;
    00019         private Mesh systemMemoryMesh = null; // System Memory mesh, lives through a resize
    00020         private Mesh localMemoryMesh = null; // Local mesh, rebuilt on resize
    00021
    00022         private Material[] meshMaterials = null; // Materials for the mesh
    00023         private BaseTexture[] meshTextures = null; // Textures for the mesh
    00024         private bool isUsingMeshMaterials = true; // Should the mesh be rendered with the materials
    00025
    00027         public Mesh SystemMesh { get { return systemMemoryMesh; } }
    00029         public Mesh LocalMesh { get { return localMemoryMesh; } }
    00031         public bool IsUsingMaterials { get { return isUsingMeshMaterials; } set { isUsingMeshMaterials = value; } }
    00033         public int NumberMaterials { get { return meshMaterials.Length; } }
    00035         public BaseTexture GetTexture(int index) { return meshTextures[index]; }
    00037         public Material GetMaterial(int index) { return meshMaterials[index]; }
    00038         #endregion
    00039
    00040         #region Creation
    00042         public FrameworkMesh(Device device, string name)
    00043         {
    00044             meshFileName = name;
    00045             Create(device, meshFileName);
    00046         }
    00048         public FrameworkMesh() : this(null, "FrameworkMeshFile_Mesh") { }
    00049
    00051         public void Create(Device device, string name)
    00052         {
    00053             // Hook the device events
    00054             System.Diagnostics.Debug.Assert(device != null, "Device should not be null.");
    00055             device.DeviceLost += new EventHandler(OnLostDevice);
    00056             device.DeviceReset += new EventHandler(OnResetDevice);
    00057             device.Disposing += new EventHandler(OnDeviceDisposing);
    00058
    00059             GraphicsBuffer adjacency = new GraphicsBuffer(); // Adjacency information
    00060             MaterialList materials = new MaterialList(); // Mesh material information
    00061
    00062             // First try to find the filename
    00063             string path = string.Empty;
    00064             try
    00065             {
    00066                 path = Utility.FindMediaFile(name);
    00067             }
    00068             catch (MediaNotFoundException)
    00069             {
    00070                 // The media was not found, maybe a full path was passed in?
    00071                 if (System.IO.File.Exists(name))
    00072                 {
    00073                     path = name;
    00074                 }
    00075                 else
    00076                 {
    00077                     // No idea what this is trying to find
    00078                     throw new MediaNotFoundException();
    00079                 }
    00080             }
    00081
    00082             // Now load the mesh
    00083             systemMemoryMesh = new Mesh(device, path, MeshFlags.SystemMemory, adjacency, materials, null);
    00084
    00085             using (adjacency)
    00086             {
    00087                 // Optimize the mesh for performance
    00088                 systemMemoryMesh.OptimizeInPlace(MeshFlags.OptimizeVertexCache | MeshFlags.OptimizeCompact |
    00089                     MeshFlags.OptimizeAttributeSort, adjacency);
    00090
    00091                 // Find the folder of where the mesh file is located
    00092                 string folder = Utility.AppendDirectorySeparator(new System.IO.FileInfo(path).DirectoryName);
    00093
    00094                 // Create the materials
    00095                 CreateMaterials(folder, device, adjacency, materials);
    00096             }
    00097
    00098             // Finally call reset
    00099             OnResetDevice(device, EventArgs.Empty);
    00100         }
    00101         // TODO: Create with XOF
    00102
    00104         public void CreateMaterials(string folder, Device device, GraphicsBuffer adjacency, MaterialList materials)
    00105         {
    00106             // Does the mesh have materials?
    00107             if ((materials != null) && (materials.Count > 0))
    00108             {
    00109                 // Allocate the arrays for the materials
    00110                 meshMaterials = new Material[materials.Count];
    00111                 meshTextures = new BaseTexture[materials.Count];
    00112
    00113                 // Copy each material and create it's texture
    00114                 for (int i = 0; i < materials.Count; i++)
    00115                 {
    00116                     // Copy the material first
    00117                     meshMaterials[i] = materials[i].Material;
    00118
    00119                     // Is there a texture for this material?
    00120                     if (string.IsNullOrEmpty(materials[i].TextureFileName))
    00121                         continue; // No, just continue now
    00122
    00123                     ImageInformation info = new ImageInformation();
    00124                     string textureFile = folder + materials[i].TextureFileName;
    00125                     try
    00126                     {
    00127                         // First look for the texture in the same folder as the input folder
    00128                         info = BaseTexture.GetImageInformationFromFile(textureFile);
    00129                     }
    00130                     catch
    00131                     {
    00132                         try
    00133                         {
    00134                             // Couldn't find it, look in the media folder
    00135                             textureFile = Utility.FindMediaFile(materials[i].TextureFileName);
    00136                             info = BaseTexture.GetImageInformationFromFile(textureFile);
    00137                         }
    00138                         catch (MediaNotFoundException)
    00139                         {
    00140                             // Couldn't find it anywhere, skip it
    00141                             continue;
    00142                         }
    00143                     }
    00144                     switch (info.ResourceType)
    00145                     {
    00146                         case ResourceType.Texture:
    00147                             meshTextures[i] = new Texture(device, textureFile);
    00148                             break;
    00149                         case ResourceType.CubeTexture:
    00150                             meshTextures[i] = new CubeTexture(device, textureFile);
    00151                             break;
    00152                         case ResourceType.VolumeTexture:
    00153                             meshTextures[i] = new VolumeTexture(device, textureFile);
    00154                             break;
    00155                     }
    00156                 }
    00157             }
    00158         }
    00159         #endregion
    00160
    00161         #region Class Methods
    00163         public void SetVertexFormat(Device device, VertexFormats format)
    00164         {
    00165             Mesh tempSystemMesh = null;
    00166             Mesh tempLocalMesh = null;
    00167             VertexFormats oldFormat = VertexFormats.None;
    00168             using (systemMemoryMesh)
    00169             {
    00170                 using (localMemoryMesh)
    00171                 {
    00172                     // Clone the meshes
    00173                     if (systemMemoryMesh != null)
    00174                     {
    00175                         oldFormat = systemMemoryMesh.VertexFormat;
    00176                         tempSystemMesh = systemMemoryMesh.Clone(device, systemMemoryMesh.Options.Value,
    00177                             format);
    00178                     }
    00179                     if (localMemoryMesh != null)
    00180                     {
    00181                         tempLocalMesh = localMemoryMesh.Clone(device, localMemoryMesh.Options.Value,
    00182                             format);
    00183                     }
    00184                 }
    00185             }
    00186
    00187             // Store the new meshes
    00188             systemMemoryMesh = tempSystemMesh;
    00189             localMemoryMesh = tempLocalMesh;
    00190
    00191             // Compute normals if they are being requested and the old mesh didn't have them
    00192             if (((oldFormat & VertexFormats.Normal) == 0) && (format != 0))
    00193             {
    00194                 if (systemMemoryMesh != null)
    00195                     systemMemoryMesh.ComputeNormals();
    00196                 if (localMemoryMesh != null)
    00197                     localMemoryMesh.ComputeNormals();
    00198             }
    00199         }
    00201         public void SetVertexDeclaration(Device device, VertexElement[] decl)
    00202         {
    00203             Mesh tempSystemMesh = null;
    00204             Mesh tempLocalMesh = null;
    00205             VertexElement[] oldDecl = null;
    00206             using (systemMemoryMesh)
    00207             {
    00208                 using (localMemoryMesh)
    00209                 {
    00210                     // Clone the meshes
    00211                     if (systemMemoryMesh != null)
    00212                     {
    00213                         oldDecl = systemMemoryMesh.GetDeclaration();
    00214                         tempSystemMesh = systemMemoryMesh.Clone(device, systemMemoryMesh.Options.Value,
    00215                             decl);
    00216                     }
    00217                     if (localMemoryMesh != null)
    00218                     {
    00219                         tempLocalMesh = localMemoryMesh.Clone(device, localMemoryMesh.Options.Value,
    00220                             decl);
    00221                     }
    00222                 }
    00223             }
    00224
    00225             // Store the new meshes
    00226             systemMemoryMesh = tempSystemMesh;
    00227             localMemoryMesh = tempLocalMesh;
    00228
    00229             bool hadNormal = false;
    00230             // Check if the old declaration contains a normal.
    00231             for (int i = 0; i < oldDecl.Length; i++)
    00232             {
    00233                 if (oldDecl[i].DeclarationUsage == DeclarationUsage.Normal)
    00234                 {
    00235                     hadNormal = true;
    00236                     break;
    00237                 }
    00238             }
    00239             // Check to see if the new declaration has a normal
    00240             bool hasNormalNow = false;
    00241             for (int i = 0; i < decl.Length; i++)
    00242             {
    00243                 if (decl[i].DeclarationUsage == DeclarationUsage.Normal)
    00244                 {
    00245                     hasNormalNow = true;
    00246                     break;
    00247                 }
    00248             }
    00249
    00250             // Compute normals if they are being requested and the old mesh didn't have them
    00251             if (!hadNormal && hasNormalNow)
    00252             {
    00253                 if (systemMemoryMesh != null)
    00254                     systemMemoryMesh.ComputeNormals();
    00255                 if (localMemoryMesh != null)
    00256                     localMemoryMesh.ComputeNormals();
    00257             }
    00258         }
    00259
    00261         private void OnResetDevice(object sender, EventArgs e)
    00262         {
    00263             Device device = sender as Device;
    00264             if (systemMemoryMesh == null)
    00265                 throw new InvalidOperationException("There is no system memory mesh.  Nothing to do here.");
    00266
    00267             // Make a local memory version of the mesh. Note: because we are passing in
    00268             // no flags, the default behavior is to clone into local memory.
    00269             localMemoryMesh = systemMemoryMesh.Clone(device, (systemMemoryMesh.Options.Value & ~MeshFlags.SystemMemory),
    00270                 systemMemoryMesh.VertexFormat);
    00271         }
    00272
    00274         private void OnLostDevice(object sender, EventArgs e)
    00275         {
    00276             if (localMemoryMesh != null)
    00277                 localMemoryMesh.Dispose();
    00278
    00279             localMemoryMesh = null;
    00280         }
    00282         public void Render(Device device, bool canDrawOpaque, bool canDrawAlpha)
    00283         {
    00284             if (localMemoryMesh == null)
    00285                 throw new InvalidOperationException("No local memory mesh.");
    00286
    00287             // Frist, draw the subsets without alpha
    00288             if (canDrawOpaque)
    00289             {
    00290                 for (int i = 0; i < meshMaterials.Length; i++)
    00291                 {
    00292                     if (isUsingMeshMaterials)
    00293                     {
    00294                         if (meshMaterials[i].DiffuseColor.Alpha < 1.0f)
    00295                             continue; // Only drawing opaque right now
    00296
    00297                         // set the device material and texture
    00298                         device.Material = meshMaterials[i];
    00299                         device.SetTexture(0, meshTextures[i]);
    00300                     }
    00301                     localMemoryMesh.DrawSubset(i);
    00302                 }
    00303             }
    00304
    00305             // Then, draw the subsets with alpha
    00306             if (canDrawAlpha)
    00307             {
    00308                 for (int i = 0; i < meshMaterials.Length; i++)
    00309                 {
    00310                     if (meshMaterials[i].DiffuseColor.Alpha == 1.0f)
    00311                         continue; // Only drawing non-opaque right now
    00312
    00313                     // set the device material and texture
    00314                     device.Material = meshMaterials[i];
    00315                     device.SetTexture(0, meshTextures[i]);
    00316                     localMemoryMesh.DrawSubset(i);
    00317                 }
    00318             }
    00319         }
    00321         public void Render(Device device) { Render(device, true, true); }
    00322
    00323         // TODO: Render with effect
    00324
    00326         public BoundingSphere ComputeBoundingSphere()
    00327         {
    00328             if (systemMemoryMesh == null)
    00329                 throw new InvalidOperationException("There is no system memory mesh.  Nothing to do here.");
    00330
    00331             // Lock the vertex buffer
    00332             GraphicsBuffer data = null;
    00333             try
    00334             {
    00335                 data = systemMemoryMesh.LockVertexBuffer(LockFlags.ReadOnly);
    00336                 // Now compute the bounding sphere
    00337                 return Geometry.ComputeBoundingSphere(data, systemMemoryMesh.VertexCount,
    00338                     systemMemoryMesh.VertexFormat);
    00339             }
    00340             finally
    00341             {
    00342                 // Make sure to unlock the vertex buffer
    00343                 if (data != null)
    00344                     systemMemoryMesh.UnlockVertexBuffer();
    00345             }
    00346         }
    00347         #endregion
    00348
    00349         #region IDisposable Members
    00350
    00352         public void Dispose()
    00353         {
    00354             OnLostDevice(null, EventArgs.Empty);
    00355             if (meshTextures != null)
    00356             {
    00357                 for (int i = 0; i < meshTextures.Length; i++)
    00358                 {
    00359                     if (meshTextures[i] != null)
    00360                         meshTextures[i].Dispose();
    00361                 }
    00362             }
    00363             meshTextures = null;
    00364             meshMaterials = null;
    00365
    00366             if (systemMemoryMesh != null)
    00367                 systemMemoryMesh.Dispose();
    00368
    00369             systemMemoryMesh = null;
    00370
    00371         }
    00372
    00374         private void OnDeviceDisposing(object sender, EventArgs e)
    00375         {
    00376             // Just dispose of our class
    00377             Dispose();
    00378         }
    00379         #endregion
    00380
    00381     }
    00382 }