- Main Page
- Packages
- Classes
- Files

- File List
- File Members

# D:/guillaume/guillara/3D/DXGfx/Backup/DXCommon/dxmutmesh.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             GraphicsStream adjacency; // Adjacency information
    00060             ExtendedMaterial[] materials; // 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 = Mesh.FromFile(path, MeshFlags.SystemMemory, device, out adjacency,
    00084                 out materials);
    00085
    00086             using (adjacency)
    00087             {
    00088                 // Optimize the mesh for performance
    00089                 systemMemoryMesh.OptimizeInPlace(MeshFlags.OptimizeVertexCache | MeshFlags.OptimizeCompact |
    00090                     MeshFlags.OptimizeAttributeSort, adjacency);
    00091
    00092                 // Find the folder of where the mesh file is located
    00093                 string folder = Utility.AppendDirectorySeparator(new System.IO.FileInfo(path).DirectoryName);
    00094
    00095                 // Create the materials
    00096                 CreateMaterials(folder, device, adjacency, materials);
    00097             }
    00098
    00099             // Finally call reset
    00100             OnResetDevice(device, EventArgs.Empty);
    00101         }
    00102         // TODO: Create with XOF
    00103
    00105         public void CreateMaterials(string folder, Device device, GraphicsStream adjacency, ExtendedMaterial[] materials)
    00106         {
    00107             // Does the mesh have materials?
    00108             if ((materials != null) && (materials.Length > 0))
    00109             {
    00110                 // Allocate the arrays for the materials
    00111                 meshMaterials = new Material[materials.Length];
    00112                 meshTextures = new BaseTexture[materials.Length];
    00113
    00114                 // Copy each material and create it's texture
    00115                 for(int i = 0; i < materials.Length; i++)
    00116                 {
    00117                     // Copy the material first
    00118                     meshMaterials[i] = materials[i].Material3D;
    00119
    00120                     // Is there a texture for this material?
    00121                     if ((materials[i].TextureFilename == null) || (materials[i].TextureFilename.Length == 0) )
    00122                         continue; // No, just continue now
    00123
    00124                     ImageInformation info = new ImageInformation();
    00125                     string textureFile = folder + materials[i].TextureFilename;
    00126                     try
    00127                     {
    00128                         // First look for the texture in the same folder as the input folder
    00129                         info = TextureLoader.ImageInformationFromFile(textureFile);
    00130                     }
    00131                     catch
    00132                     {
    00133                         try
    00134                         {
    00135                             // Couldn't find it, look in the media folder
    00136                             textureFile = Utility.FindMediaFile(materials[i].TextureFilename);
    00137                             info = TextureLoader.ImageInformationFromFile(textureFile);
    00138                         }
    00139                         catch (MediaNotFoundException)
    00140                         {
    00141                             // Couldn't find it anywhere, skip it
    00142                             continue;
    00143                         }
    00144                     }
    00145                     switch (info.ResourceType)
    00146                     {
    00147                         case ResourceType.Textures:
    00148                             meshTextures[i] = TextureLoader.FromFile(device, textureFile);
    00149                             break;
    00150                         case ResourceType.CubeTexture:
    00151                             meshTextures[i] = TextureLoader.FromCubeFile(device, textureFile);
    00152                             break;
    00153                         case ResourceType.VolumeTexture:
    00154                             meshTextures[i] = TextureLoader.FromVolumeFile(device, textureFile);
    00155                             break;
    00156                     }
    00157                 }
    00158             }
    00159         }
    00160         #endregion
    00161
    00162         #region Class Methods
    00164         public void SetVertexFormat(Device device, VertexFormats format)
    00165         {
    00166             Mesh tempSystemMesh = null;
    00167             Mesh tempLocalMesh = null;
    00168             VertexFormats oldFormat = VertexFormats.None;
    00169             using(systemMemoryMesh)
    00170             {
    00171                 using (localMemoryMesh)
    00172                 {
    00173                     // Clone the meshes
    00174                     if (systemMemoryMesh != null)
    00175                     {
    00176                         oldFormat = systemMemoryMesh.VertexFormat;
    00177                         tempSystemMesh = systemMemoryMesh.Clone(systemMemoryMesh.Options.Value,
    00178                             format, device);
    00179                     }
    00180                     if (localMemoryMesh != null)
    00181                     {
    00182                         tempLocalMesh = localMemoryMesh.Clone(localMemoryMesh.Options.Value,
    00183                             format, device);
    00184                     }
    00185                 }
    00186             }
    00187
    00188             // Store the new meshes
    00189             systemMemoryMesh = tempSystemMesh;
    00190             localMemoryMesh = tempLocalMesh;
    00191
    00192             // Compute normals if they are being requested and the old mesh didn't have them
    00193             if ( ((oldFormat & VertexFormats.Normal) == 0) && (format != 0) )
    00194             {
    00195                 if (systemMemoryMesh != null)
    00196                     systemMemoryMesh.ComputeNormals();
    00197                 if (localMemoryMesh != null)
    00198                     localMemoryMesh.ComputeNormals();
    00199             }
    00200         }
    00202         public void SetVertexDeclaration(Device device, VertexElement[] decl)
    00203         {
    00204             Mesh tempSystemMesh = null;
    00205             Mesh tempLocalMesh = null;
    00206             VertexElement[] oldDecl = null;
    00207             using(systemMemoryMesh)
    00208             {
    00209                 using (localMemoryMesh)
    00210                 {
    00211                     // Clone the meshes
    00212                     if (systemMemoryMesh != null)
    00213                     {
    00214                         oldDecl = systemMemoryMesh.Declaration;
    00215                         tempSystemMesh = systemMemoryMesh.Clone(systemMemoryMesh.Options.Value,
    00216                             decl, device);
    00217                     }
    00218                     if (localMemoryMesh != null)
    00219                     {
    00220                         tempLocalMesh = localMemoryMesh.Clone(localMemoryMesh.Options.Value,
    00221                             decl, device);
    00222                     }
    00223                 }
    00224             }
    00225
    00226             // Store the new meshes
    00227             systemMemoryMesh = tempSystemMesh;
    00228             localMemoryMesh = tempLocalMesh;
    00229
    00230             bool hadNormal = false;
    00231             // Check if the old declaration contains a normal.
    00232             for(int i = 0; i < oldDecl.Length; i++)
    00233             {
    00234                 if (oldDecl[i].DeclarationUsage == DeclarationUsage.Normal)
    00235                 {
    00236                     hadNormal = true;
    00237                     break;
    00238                 }
    00239             }
    00240             // Check to see if the new declaration has a normal
    00241             bool hasNormalNow = false;
    00242             for(int i = 0; i < decl.Length; i++)
    00243             {
    00244                 if (decl[i].DeclarationUsage == DeclarationUsage.Normal)
    00245                 {
    00246                     hasNormalNow = true;
    00247                     break;
    00248                 }
    00249             }
    00250
    00251             // Compute normals if they are being requested and the old mesh didn't have them
    00252             if ( !hadNormal && hasNormalNow )
    00253             {
    00254                 if (systemMemoryMesh != null)
    00255                     systemMemoryMesh.ComputeNormals();
    00256                 if (localMemoryMesh != null)
    00257                     localMemoryMesh.ComputeNormals();
    00258             }
    00259         }
    00260
    00262         private void OnResetDevice(object sender, EventArgs e)
    00263         {
    00264             Device device = sender as Device;
    00265             if (systemMemoryMesh == null)
    00266                 throw new InvalidOperationException("There is no system memory mesh.  Nothing to do here.");
    00267
    00268             // Make a local memory version of the mesh. Note: because we are passing in
    00269             // no flags, the default behavior is to clone into local memory.
    00270             localMemoryMesh = systemMemoryMesh.Clone((systemMemoryMesh.Options.Value & ~MeshFlags.SystemMemory),
    00271                 systemMemoryMesh.VertexFormat, device);
    00272         }
    00273
    00275         private void OnLostDevice(object sender, EventArgs e)
    00276         {
    00277             if (localMemoryMesh != null)
    00278                 localMemoryMesh.Dispose();
    00279
    00280             localMemoryMesh = null;
    00281         }
    00283         public void Render(Device device, bool canDrawOpaque, bool canDrawAlpha)
    00284         {
    00285             if (localMemoryMesh == null)
    00286                 throw new InvalidOperationException("No local memory mesh.");
    00287
    00288             // Frist, draw the subsets without alpha
    00289             if (canDrawOpaque)
    00290             {
    00291                 for (int i = 0; i < meshMaterials.Length; i++)
    00292                 {
    00293                     if (isUsingMeshMaterials)
    00294                     {
    00295                         if (meshMaterials[i].DiffuseColor.Alpha < 1.0f)
    00296                             continue; // Only drawing opaque right now
    00297
    00298                         // set the device material and texture
    00299                         device.Material = meshMaterials[i];
    00300                         device.SetTexture(0, meshTextures[i]);
    00301                     }
    00302                     localMemoryMesh.DrawSubset(i);
    00303                 }
    00304             }
    00305
    00306             // Then, draw the subsets with alpha
    00307             if (canDrawAlpha)
    00308             {
    00309                 for (int i = 0; i < meshMaterials.Length; i++)
    00310                 {
    00311                     if (meshMaterials[i].DiffuseColor.Alpha == 1.0f)
    00312                         continue; // Only drawing non-opaque right now
    00313
    00314                     // set the device material and texture
    00315                     device.Material = meshMaterials[i];
    00316                     device.SetTexture(0, meshTextures[i]);
    00317                     localMemoryMesh.DrawSubset(i);
    00318                 }
    00319             }
    00320         }
    00322         public void Render(Device device) { Render(device, true, true); }
    00323
    00324         // TODO: Render with effect
    00325
    00327         public float ComputeBoundingSphere(out Vector3 center)
    00328         {
    00329             if (systemMemoryMesh == null)
    00330                 throw new InvalidOperationException("There is no system memory mesh.  Nothing to do here.");
    00331
    00332             // Get the object declaration
    00333             int strideSize = VertexInformation.GetFormatSize(systemMemoryMesh.VertexFormat);
    00334
    00335             // Lock the vertex buffer
    00336             GraphicsStream data = null;
    00337             try
    00338             {
    00339                 data = systemMemoryMesh.LockVertexBuffer(LockFlags.ReadOnly);
    00340                 // Now compute the bounding sphere
    00341                 return Geometry.ComputeBoundingSphere(data, systemMemoryMesh.NumberVertices,
    00342                     systemMemoryMesh.VertexFormat, out center);
    00343             }
    00344             finally
    00345             {
    00346                 // Make sure to unlock the vertex buffer
    00347                 if (data != null)
    00348                     systemMemoryMesh.UnlockVertexBuffer();
    00349             }
    00350         }
    00351         #endregion
    00352
    00353         #region IDisposable Members
    00354
    00356         public void Dispose()
    00357         {
    00358             OnLostDevice(null, EventArgs.Empty);
    00359             if (meshTextures != null)
    00360             {
    00361                 for(int i = 0; i < meshTextures.Length; i++)
    00362                 {
    00363                     if (meshTextures[i] != null)
    00364                         meshTextures[i].Dispose();
    00365                 }
    00366             }
    00367             meshTextures = null;
    00368             meshMaterials = null;
    00369
    00370             if (systemMemoryMesh != null)
    00371                 systemMemoryMesh.Dispose();
    00372
    00373             systemMemoryMesh = null;
    00374
    00375         }
    00376
    00378         private void OnDeviceDisposing(object sender, EventArgs e)
    00379         {
    00380             // Just dispose of our class
    00381             Dispose();
    00382         }
    00383         #endregion
    00384
    00385     }
    00386 }